Compare commits

...

40 Commits

Author SHA1 Message Date
A. Regnander 83d661ab2a Create sv_se.json (#4485) 2020-07-20 21:33:44 +02:00
shartte a537bcf0ee Merge pull request #4486 from AppliedEnergistics/number-entry-dialogs
Number Entry Dialogs
2020-07-20 20:13:04 +02:00
Sebastian Hartte 590e435ad6 Formatting fixes 2020-07-19 23:51:57 +02:00
Sebastian Hartte 8d92a51e4f Formatting fixes 2020-07-19 23:50:47 +02:00
Sebastian Hartte 4322910614 Added labels that specify the unit of power (AE) and the unit of fluid (mB) for the level emitters. 2020-07-19 23:50:18 +02:00
Sebastian Hartte ebe589a714 Ported the other number entry dialogs over to the shared widget. 2020-07-19 23:25:11 +02:00
Sebastian Hartte 6187e6a7bb Started refactoring number entry dialogs to use shared code. 2020-07-19 20:04:08 +02:00
shartte d5f113eb35 Merge pull request #4484 from AppliedEnergistics/energy-grid-failfast
Guard Against Concurrent EnergyGrid Modifications
2020-07-19 17:56:22 +02:00
shartte 9ad5bb21c0 Merge pull request #4480 from AppliedEnergistics/mb-fixes
Fix more MultiBlock issues
2020-07-19 17:31:06 +02:00
Sebastian Hartte 1c88ea7b78 Fail faster when something modifies the list of energy providers/requesters while an extract/inject operation is ongoing, since this would lead to ConcurrentModificationExceptions later, without a way of tracking down what caused the modification in the first place. 2020-07-19 16:39:37 +02:00
shartte 5a976ebfae Merge pull request #4483 from AppliedEnergistics/texture-cleanup
Texture Cleanup
2020-07-19 16:20:32 +02:00
Sebastian Hartte b45669bb82 Removed several unchecked casts. 2020-07-19 16:01:19 +02:00
Sebastian Hartte e52cc40dbf JSON Formatting Fix 2020-07-19 16:00:01 +02:00
Sebastian Hartte 8a20d3c1d7 Consolidated fluid models to reuse the item counterparts with different textures. 2020-07-19 15:00:46 +02:00
Sebastian Hartte 749ebeb91d Moved part textures from parts to part to be consistent with singular naming used in Minecraft (and for the model directory). 2020-07-19 14:14:18 +02:00
Sebastian Hartte 82586732e3 Removed unused crafting and fluid terminal models and associated textures.
Unified naming for textures used by the fluid terminal.
2020-07-19 14:09:57 +02:00
Sebastian Hartte e023d83e62 Deleted unused matrix frame related documentation images. 2020-07-19 13:40:42 +02:00
Sebastian Hartte de7cbc4949 Moved part-related textures from textures/item/part to textures/parts/ and adapted the level emitter item models to use the normal part texture. 2020-07-19 13:37:23 +02:00
Sebastian Hartte 71a91e51fb Naming improvements 2020-07-19 13:16:50 +02:00
yueh 223163aa0a Fixes #4330: Avoid mutating the input stack (#4481) 2020-07-19 13:13:20 +02:00
Sebastian Hartte bdd22093c3 Account for empty messages when drawing tooltips. 2020-07-19 12:05:26 +02:00
Sebastian Hartte 0367b35ce0 Never return null from Widget#getMessage since the
narrator will always dereference it, leading to a crash.
2020-07-19 12:04:15 +02:00
yueh 755ac12b8a Fix SortedSet using compare for equals (#4479)
Fix SortedSet using compare for equals
2020-07-19 11:43:20 +02:00
Sebastian Hartte e1f9e01404 Force cluster-rebuilds on the first detected change, if their bounds do not match.
Also use a client-side method to update connected textures
for crafting cubes if two previously distinct clusters are connected.
Refactored MBCalculator to use generics for type checks and remove more casts.
2020-07-19 00:16:33 +02:00
Sebastian Hartte 7121426fc9 Disable AO for the Spatial Pylon due to artifacts. 2020-07-19 00:12:35 +02:00
yueh a94e8504f8 Correctly convert milliseconds to microseconds (#4478) 2020-07-18 20:51:30 +02:00
yueh 9275bfe001 Split TickHandler#onTick into more specific event handlers (#4477) 2020-07-18 19:35:33 +02:00
shartte 5b3c4aef79 When blocks adjacent to multiblock-capable blocks are updated, (#4474)
do not always recalculate existing multiblocks. Only do so,
if the adjacent block is either part of the multiblock's bounding
box, or if the adjacent block would be a valid part of the multiblock.
2020-07-18 18:18:24 +02:00
yueh 4a289470e2 Added a priority to IAEPowerStorage (#4473)
Added a priority to IAEPowerStorage
2020-07-18 18:06:05 +02:00
shartte d79c0f642c Do not allow recursive creation of multiblocks. (#4472) 2020-07-18 18:00:40 +02:00
aoisensi 9ecad8749f Added new japanese translate (#4475)
* Added new japanese translate
2020-07-18 12:38:23 +02:00
shartte e8b57c6dc5 Multiblocks sometimes can't be broken because during removal, (#4469)
they update their own block-state to display the disconnected
state, effectively reversing their own removal. This occurs
because the cached block state in the tile entity base class is
outdated and doesn't reflect the removal.
2020-07-17 22:35:49 +02:00
shartte 8142eb90a6 Added new Cell Rendering to ME Chest (#4464)
Moved cell models to origin 0,0,0.
Implemented a TER to render cell models/LED in the ME chest as they are rendered in the drive.
2020-07-17 20:37:07 +02:00
Sebastian Hartte 08abd4a770 Fixed formatting. 2020-07-17 20:26:17 +02:00
Sebastian Hartte b8722dbbc0 Do not rely on exceptions for control flow, when the
cell has no fuzzy mode.
2020-07-17 19:51:59 +02:00
Sebastian Hartte 1ac6d5d967 Fixes creation of entangled singularities. 2020-07-17 15:27:03 +02:00
Sebastian Hartte 5c290789e0 Fixes #4467: Private methods also need to be annotated with @OnlyIn(Dist.CLIENT)
if they use client-side classes.
2020-07-17 12:45:17 +02:00
yueh 38f6bf16f2 Updated dependencies (#4466)
Changed forge to 31.2.31 and also marked it as required version.
Changed JEI to 6.0.2.12 for dev usage.
2020-07-15 23:25:35 +02:00
Sebastian Hartte 4953509255 P2P Fluid Tunnel Fix 2020-07-13 17:45:40 +02:00
Sebastian Hartte 188f105730 Fix the alive check for the matter cannon. 2020-07-12 17:20:42 +02:00
603 changed files with 3306 additions and 2851 deletions
+3 -3
View File
@@ -10,13 +10,13 @@ artifact_basename=appliedenergistics2
#########################################################
minecraft_release=1.15
minecraft_version=1.15.2
mcp_mappings=20200701-1.15.1
forge_version=31.2.20
mcp_mappings=20200715-1.15.1
forge_version=31.2.31
#########################################################
# Provided APIs #
#########################################################
jei_version=6.0.0.4
jei_version=6.0.2.12
top_version=2.0.4-5
hwyla_version=1.10.8-B72_1.15.2
ctm_version=MC1.15.2-1.1.0.9
@@ -27,6 +27,7 @@ import javax.annotation.Nonnull;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.IGrid;
/**
* Used to access information about AE's various power accepting blocks for
@@ -71,4 +72,22 @@ public interface IAEPowerStorage extends IEnergySource {
*/
@Nonnull
AccessRestriction getPowerFlow();
}
/**
* The priority to use this energy storage.
*
* A higher value means it is more likely to be extracted from first, and less
* likely to be inserted into first.
*
* The value needs to be constant once added to a {@link IGrid}. Should it ever
* need to be changed, it has to be removed from the grid, then update the
* value, and finally added back to the grid.
*
* This should never use {@link Integer#MIN_VALUE} or {@link Integer#MAX_VALUE}.
*
* @return the priority for this storage
*/
default int getPriority() {
return 0;
}
}
@@ -23,10 +23,13 @@ import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
@@ -54,12 +57,22 @@ public abstract class AbstractCraftingUnitBlock<T extends CraftingTileEntity> ex
builder.add(FORMED);
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
TileEntity te = worldIn.getTileEntity(currentPos);
if (te != null) {
te.requestModelDataUpdate();
}
return super.updatePostPlacement(stateIn, facing, facingState, worldIn, currentPos, facingPos);
}
@Override
public void neighborChanged(final BlockState state, final World worldIn, final BlockPos pos, final Block blockIn,
final BlockPos fromPos, boolean isMoving) {
final CraftingTileEntity cp = this.getTileEntity(worldIn, pos);
if (cp != null) {
cp.updateMultiBlock();
cp.updateMultiBlock(fromPos);
}
}
@@ -41,9 +41,9 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
private static final Material TEXTURE_RING_LIGHT_CORNER = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
private static final Material TEXTURE_CABLE_GLASS = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/cable/glass/transparent"));
new ResourceLocation(AppEng.MOD_ID, "part/cable/glass/transparent"));
private static final Material TEXTURE_COVERED_CABLE = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/cable/covered/transparent"));
new ResourceLocation(AppEng.MOD_ID, "part/cable/covered/transparent"));
private static final float DEFAULT_RENDER_MIN = 2.0f;
private static final float DEFAULT_RENDER_MAX = 14.0f;
@@ -70,7 +70,7 @@ public abstract class QuantumBaseBlock extends AEBaseTileBlock<QuantumBridgeTile
boolean isMoving) {
final QuantumBridgeTileEntity bridge = this.getTileEntity(world, pos);
if (bridge != null) {
bridge.neighborUpdate();
bridge.neighborUpdate(fromPos);
}
}
@@ -39,7 +39,7 @@ public class SpatialPylonBlock extends AEBaseTileBlock<SpatialPylonTileEntity> {
boolean isMoving) {
final SpatialPylonTileEntity tsp = this.getTileEntity(world, pos);
if (tsp != null) {
tsp.neighborChanged();
tsp.neighborChanged(fromPos);
}
}
@@ -25,7 +25,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
@@ -42,18 +42,17 @@ import appeng.tile.storage.ChestTileEntity;
public class ChestBlock extends AEBaseTileBlock<ChestTileEntity> {
private final static EnumProperty<DriveSlotState> SLOT_STATE = EnumProperty.create("slot_state",
DriveSlotState.class);
private final static BooleanProperty LIGHTS_ON = BooleanProperty.create("lights_on");
public ChestBlock() {
super(defaultProps(Material.IRON));
this.setDefaultState(this.getDefaultState().with(SLOT_STATE, DriveSlotState.EMPTY));
this.setDefaultState(this.getDefaultState().with(LIGHTS_ON, false));
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(SLOT_STATE);
builder.add(LIGHTS_ON);
}
@Override
@@ -68,7 +67,7 @@ public class ChestBlock extends AEBaseTileBlock<ChestTileEntity> {
slotState = DriveSlotState.OFFLINE;
}
return currentState.with(SLOT_STATE, slotState);
return currentState.with(LIGHTS_ON, slotState != DriveSlotState.EMPTY && slotState != DriveSlotState.OFFLINE);
}
@Override
@@ -35,6 +35,7 @@ import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.renderer.BufferBuilder;
@@ -60,6 +61,7 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.CustomSlotWidget;
import appeng.client.gui.widgets.ITickingWidget;
import appeng.client.gui.widgets.ITooltip;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.InternalSlotME;
@@ -88,6 +90,9 @@ import appeng.fluids.container.slots.IMEFluidSlot;
import appeng.helpers.InventoryAction;
public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerScreen<T> {
public static final int COLOR_DARK_GRAY = 4210752;
private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y
private final Set<Slot> drag_click = new HashSet<>();
@@ -176,7 +181,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
final String msg = tooltip.getMessage();
if (msg != null) {
if (msg != null && !msg.isEmpty()) {
this.drawTooltip(x + 11, y + 4, msg);
}
}
@@ -781,4 +786,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected List<InternalSlotME> getMeSlots() {
return this.meSlots;
}
public void tick() {
super.tick();
for (IGuiEventListener child : children) {
if (child instanceof ITickingWidget) {
((ITickingWidget) child).tick();
}
}
}
}
@@ -0,0 +1,16 @@
package appeng.client.gui;
public enum NumberEntryType {
CRAFT_ITEM_COUNT(Long.class), PRIORITY(Long.class), LEVEL_ITEM_COUNT(Long.class), LEVEL_FLUID_VOLUME(Long.class);
private final Class<? extends Number> inputType;
NumberEntryType(Class<? extends Number> inputType) {
this.inputType = inputType;
}
public Class<? extends Number> getInputType() {
return inputType;
}
}
@@ -19,15 +19,13 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.CraftAmountContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.CraftRequestPacket;
@@ -35,7 +33,7 @@ import appeng.core.sync.packets.CraftRequestPacket;
public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
private final AESubScreen subGui;
private NumberBox amountToCraft;
private NumberEntryWidget amountToCraft;
private Button next;
@@ -48,39 +46,22 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
public void init() {
super.init();
final int a = AEConfig.instance().craftItemsByStackAmounts(0);
final int b = AEConfig.instance().craftItemsByStackAmounts(1);
final int c = AEConfig.instance().craftItemsByStackAmounts(2);
final int d = AEConfig.instance().craftItemsByStackAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 26, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 26, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 26, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 26, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 75, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 75, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 75, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 75, 38, 20, "-" + d, btn -> addQty(-d)));
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
});
this.amountToCraft.setValue(1);
this.amountToCraft.setTextFieldBounds(62, 57, 50);
this.amountToCraft.setMinValue(1);
this.amountToCraft.addButtons(children::add, this::addButton);
this.next = this.addButton(
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.getLocal(), this::confirm));
subGui.addBackButton(this::addButton, 154, 0);
this.amountToCraft = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Integer.class);
this.amountToCraft.setEnableBackgroundDrawing(false);
this.amountToCraft.setMaxStringLength(16);
this.amountToCraft.setTextColor(0xFFFFFF);
this.amountToCraft.setVisible(true);
this.amountToCraft.setFocused2(true);
this.amountToCraft.setText("1");
}
private void confirm(Button button) {
NetworkHandler.instance()
.sendToServer(new CraftRequestPacket(Integer.parseInt(this.amountToCraft.getText()), hasShiftDown()));
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
}
@Override
@@ -95,99 +76,23 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
this.bindTexture("guis/craft_amt.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
try {
Long.parseLong(this.amountToCraft.getText());
this.next.active = !this.amountToCraft.getText().isEmpty();
} catch (final NumberFormatException e) {
this.next.active = false;
}
this.next.active = this.amountToCraft.getValue() > 0;
this.amountToCraft.render(offsetX, offsetY, partialTicks);
}
@Override
public boolean charTyped(char ch, int p_charTyped_2_) {
// Forward entered text to the craft amount text-field
return this.amountToCraft.charTyped(ch, p_charTyped_2_);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 28) {
this.next.onPress();
}
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.amountToCraft.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
final long result = Long.parseLong(out);
if (result < 0) {
this.amountToCraft.setText("1");
}
} catch (final NumberFormatException e) {
// :P
}
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
private void addQty(final int i) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Integer.parseInt(out);
if (result == 1 && i > 1) {
result = 0;
}
result += i;
if (result < 1) {
result = 1;
}
out = Long.toString(result);
Integer.parseInt(out);
this.amountToCraft.setText(out);
} catch (final NumberFormatException e) {
// :P
if (keyCode == 28) {
this.next.onPress();
return true;
} else {
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
protected String getBackground() {
return "guis/craftAmt.png";
}
}
@@ -18,39 +18,27 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.PowerUnits;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.LevelEmitterContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
private NumberBox level;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
private NumberEntryWidget level;
private SettingToggleButton<LevelType> levelMode;
private SettingToggleButton<YesNo> craftingMode;
@@ -62,16 +50,17 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
public void init() {
super.init();
this.level = new NumberBox(this.font, this.guiLeft + 24, this.guiTop + 43, 79, this.font.FONT_HEIGHT,
Long.class);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.setFocused2(true);
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75);
this.level.addButtons(children::add, this::addButton);
container.setTextField(this.level);
}
private void onLevelChange(long level) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
}
@Override
protected void addButtons() {
this.levelMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8, Settings.LEVEL_TYPE,
@@ -82,29 +71,6 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
FuzzyMode.IGNORE_ALL);
this.craftingMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48,
Settings.CRAFT_VIA_REDSTONE, YesNo.NO);
final int a = AEConfig.instance().levelByStackAmounts(0);
final int b = AEConfig.instance().levelByStackAmounts(1);
final int c = AEConfig.instance().levelByStackAmounts(2);
final int d = AEConfig.instance().levelByStackAmounts(3);
this.addButton(this.plus1 = new Button(this.guiLeft + 20, this.guiTop + 17, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(
this.plus10 = new Button(this.guiLeft + 48, this.guiTop + 17, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(
this.plus100 = new Button(this.guiLeft + 82, this.guiTop + 17, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(
this.plus1000 = new Button(this.guiLeft + 120, this.guiTop + 17, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(
this.minus1 = new Button(this.guiLeft + 20, this.guiTop + 59, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(
this.minus10 = new Button(this.guiLeft + 48, this.guiTop + 59, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(
this.minus100 = new Button(this.guiLeft + 82, this.guiTop + 59, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(
this.minus1000 = new Button(this.guiLeft + 120, this.guiTop + 59, 38, 20, "-" + d, btn -> addQty(-d)));
this.addButton(this.levelMode);
this.addButton(this.redstoneMode);
this.addButton(this.craftingMode);
@@ -115,15 +81,7 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
final boolean notCraftingMode = this.bc.getInstalledUpgrades(Upgrades.CRAFTING) == 0;
// configure enabled status...
this.level.setEnabled(notCraftingMode);
this.plus1.active = notCraftingMode;
this.plus10.active = notCraftingMode;
this.plus100.active = notCraftingMode;
this.plus1000.active = notCraftingMode;
this.minus1.active = notCraftingMode;
this.minus10.active = notCraftingMode;
this.minus100.active = notCraftingMode;
this.minus1000.active = notCraftingMode;
this.level.setActive(notCraftingMode);
this.levelMode.active = notCraftingMode;
this.redstoneMode.active = notCraftingMode;
@@ -134,7 +92,14 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
}
if (this.levelMode != null) {
this.levelMode.set(((LevelEmitterContainer) this.cvb).getLevelMode());
LevelType currentLevelMode = ((LevelEmitterContainer) this.cvb).getLevelMode();
this.levelMode.set(currentLevelMode);
if (notCraftingMode) {
if (currentLevelMode == LevelType.ENERGY_LEVEL) {
this.font.drawString(PowerUnits.AE.textComponent().getString(), 110, 44, COLOR_DARK_GRAY);
}
}
}
}
@@ -160,70 +125,4 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
return GuiText.LevelEmitter;
}
private void addQty(final long i) {
try {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
long result = Long.parseLong(Out);
result += i;
if (result < 0) {
result = 0;
}
this.level.setText(Out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
} catch (final NumberFormatException e) {
// nope..
this.level.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
// Forward entered characters to the number-text-field
return level.charTyped(character, key);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14) {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
@@ -0,0 +1,130 @@
package appeng.client.gui.implementations;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.widget.button.Button;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ITickingWidget;
import appeng.client.gui.widgets.NumberBox;
import appeng.core.AEConfig;
/**
* A utility widget that consists of a text-field to enter a number with
* attached buttons to increment/decrement the number in fixed intervals.
*/
public class NumberEntryWidget implements ITickingWidget {
private final AEBaseScreen<?> parent;
private final int x;
private final int y;
private final NumberBox level;
private final NumberEntryType type;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
LongConsumer changeListener) {
this.parent = parent;
this.x = x;
this.y = y;
this.type = type;
FontRenderer font = parent.getMinecraft().fontRenderer;
int inputX = parent.getGuiLeft() + x;
int inputY = parent.getGuiTop() + y;
this.level = new NumberBox(font, inputX, inputY, width, font.FONT_HEIGHT, type.getInputType(), changeListener);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.setFocused2(true);
parent.setFocusedDefault(this.level);
}
public void setActive(boolean active) {
this.level.setEnabled(active);
this.plus1.active = active;
this.plus10.active = active;
this.plus100.active = active;
this.plus1000.active = active;
this.minus1.active = active;
this.minus10.active = active;
this.minus100.active = active;
this.minus1000.active = active;
}
public void setTextFieldBounds(int x, int y, int width) {
this.level.x = parent.getGuiLeft() + x;
this.level.y = parent.getGuiTop() + y;
this.level.setWidth(width);
}
public void setMinValue(long minValue) {
this.level.setMinValue(minValue);
}
public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) {
final int[] steps = AEConfig.instance().getNumberEntrySteps(type);
int a = steps[0];
int b = steps[1];
int c = steps[2];
int d = steps[3];
int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y;
addButton.accept(this.plus1 = new Button(left, top, 22, 20, "+" + a, btn -> addQty(a)));
addButton.accept(this.plus10 = new Button(left + 28, top, 28, 20, "+" + b, btn -> addQty(b)));
addButton.accept(this.plus100 = new Button(left + 62, top, 32, 20, "+" + c, btn -> addQty(c)));
addButton.accept(this.plus1000 = new Button(left + 100, top, 38, 20, "+" + d, btn -> addQty(d)));
// Placing this here will give a sensible tab order
addChildren.accept(this.level);
addButton.accept(this.minus1 = new Button(left, top + 42, 22, 20, "-" + a, btn -> addQty(-a)));
addButton.accept(this.minus10 = new Button(left + 28, top + 42, 28, 20, "-" + b, btn -> addQty(-b)));
addButton.accept(this.minus100 = new Button(left + 62, top + 42, 32, 20, "-" + c, btn -> addQty(-c)));
addButton.accept(this.minus1000 = new Button(left + 100, top + 42, 38, 20, "-" + d, btn -> addQty(-d)));
}
private void addQty(final long i) {
long currentValue = this.level.getValue();
long minValue = this.level.getMinValue();
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
}
public void render(int mouseX, int mouseY, float partialTicks) {
this.level.render(mouseX, mouseY, partialTicks);
}
public void setValue(long value, boolean skipNotify) {
this.level.setValue(value, skipNotify);
}
public void setValue(long value) {
setValue(value, false);
}
public long getValue() {
return level.getValue();
}
@Override
public void tick() {
this.level.tick();
}
}
@@ -18,15 +18,12 @@
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.PriorityContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -35,7 +32,7 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
private final AESubScreen subGui;
private NumberBox priority;
private NumberEntryWidget priority;
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) {
super(container, playerInventory, title);
@@ -46,31 +43,18 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
public void init() {
super.init();
final int a = AEConfig.instance().priorityByStacksAmounts(0);
final int b = AEConfig.instance().priorityByStacksAmounts(1);
final int c = AEConfig.instance().priorityByStacksAmounts(2);
final int d = AEConfig.instance().priorityByStacksAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 32, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 32, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 32, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 32, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 69, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 69, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 69, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 69, 38, 20, "-" + d, btn -> addQty(-d)));
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
this.priority.setTextFieldBounds(62, 57, 50);
this.priority.setMinValue(Integer.MIN_VALUE);
container.setTextField(this.priority);
this.priority.addButtons(children::add, this::addButton);
this.subGui.addBackButton(this::addButton, 154, 0);
}
this.priority = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Long.class);
this.priority.setEnableBackgroundDrawing(false);
this.priority.setMaxStringLength(16);
this.priority.setTextColor(0xFFFFFF);
this.priority.setVisible(true);
this.priority.setFocused2(true);
container.setTextField(this.priority);
private void onPriorityChange(long priority) {
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
}
@Override
@@ -86,90 +70,6 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
this.priority.render(mouseX, mouseY, partialTicks);
}
private void addQty(final int i) {
try {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Long.parseLong(out);
result += i;
this.priority.setText(out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
} catch (final NumberFormatException e) {
// nope..
this.priority.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
if (priority.charTyped(character, key)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.priority.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
protected String getBackground() {
return "guis/priority.png";
}
@@ -0,0 +1,13 @@
package appeng.client.gui.widgets;
import net.minecraft.client.gui.screen.Screen;
/**
* Indicates that a widget (anything that is in the {@link Screen#children()}
* list) should receive callbacks every tick.
*/
public interface ITickingWidget {
void tick();
}
@@ -18,35 +18,131 @@
package appeng.client.gui.widgets;
import java.util.function.LongConsumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
// FIXME: Fix this piece of crap (i.e. onChange listener)
public class NumberBox extends TextFieldWidget {
private final Class type;
private final LongConsumer changeListener;
private long lastValue;
private long minValue = 0;
private long maxValue;
public NumberBox(final FontRenderer fontRenderer, final int x, final int y, final int width, final int height,
final Class type) {
final Class<?> type, LongConsumer changeListener) {
super(fontRenderer, x, y, width, height, "0");
this.type = type;
this.setText("0");
setResponder(this::onTextChanged);
this.lastValue = 0;
this.changeListener = changeListener;
if (type == int.class || type == Integer.class) {
maxValue = Integer.MAX_VALUE;
} else {
maxValue = Long.MAX_VALUE;
}
}
private void onTextChanged(String text) {
if (text.isEmpty()) {
setText("0"); // Will call onTextChanged recursively
return;
}
boolean canBeNegative = canBeNegative();
if (canBeNegative && text.equals("-")) {
// Allow this as a special case to make typing in a negative number easier
return;
}
StringBuilder sanitized = new StringBuilder(text);
boolean encounteredNonZero = false;
for (int i = 0; i < sanitized.length(); i++) {
char ch = sanitized.charAt(i);
if (canBeNegative && i == 0 && ch == '-') {
continue; // Allow leading minus sign
}
if (ch >= '1' && ch <= '9') {
encounteredNonZero = true;
continue;
}
if (ch != '0' || !encounteredNonZero) {
sanitized.deleteCharAt(i--);
}
}
if (sanitized.length() == 0) {
sanitized.append('0');
}
String sanitizedStr = sanitized.toString();
if (!sanitizedStr.equals(text)) {
setText(sanitizedStr); // Will call onTextChanged recursively
return;
}
if (getValue() < minValue) {
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
return;
}
if (getValue() > maxValue) {
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
return;
}
reportChange();
}
private void reportChange() {
long value = getValue();
if (value != lastValue) {
lastValue = value;
changeListener.accept(value);
}
}
public void setValue(long value, boolean skipNotify) {
// This check avoid changing the cursor position needlessly
if (value == this.getValue()) {
return;
}
if (skipNotify) {
lastValue = value;
}
setText(String.valueOf(value));
}
public long getValue() {
if (getText().equals("-") && canBeNegative()) {
return lastValue; // Allow this as a special case to type in a negative number more easily
}
return Long.parseLong(getText());
}
@Override
public void writeText(final String selectedText) {
final String original = this.getText();
super.writeText(selectedText);
try {
if (this.type == int.class || this.type == Integer.class) {
Integer.parseInt(this.getText());
} else if (this.type == long.class || this.type == Long.class) {
Long.parseLong(this.getText());
} else if (this.type == double.class || this.type == Double.class) {
Double.parseDouble(this.getText());
}
} catch (final NumberFormatException e) {
this.setText(original);
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
return true;
}
// Swallow key presses for numbers because they would otherwise trigger the
// hotbar swapping unintentionally
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
}
public void setMinValue(long minValue) {
this.minValue = minValue;
}
public long getMinValue() {
return minValue;
}
private boolean canBeNegative() {
return minValue < 0;
}
}
@@ -314,7 +314,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
return name + '\n' + sb;
}
return null;
return "";
}
public String getFillVar() {
@@ -99,7 +99,7 @@ public class ToggleButton extends Button implements ITooltip {
return name + '\n' + sb;
}
return null;
return "";
}
@Override
@@ -81,19 +81,19 @@ class CableBuilder {
String textureFolder;
switch (cableType) {
case GLASS:
textureFolder = "parts/cable/glass/";
textureFolder = "part/cable/glass/";
break;
case COVERED:
textureFolder = "parts/cable/covered/";
textureFolder = "part/cable/covered/";
break;
case SMART:
textureFolder = "parts/cable/smart/";
textureFolder = "part/cable/smart/";
break;
case DENSE_COVERED:
textureFolder = "parts/cable/dense_covered/";
textureFolder = "part/cable/dense_covered/";
break;
case DENSE_SMART:
textureFolder = "parts/cable/dense_smart/";
textureFolder = "part/cable/dense_smart/";
break;
default:
throw new IllegalStateException("Cable type " + cableType + " does not support connections.");
@@ -37,7 +37,7 @@ import appeng.core.AppEng;
* Covered (also used by the Smart Cable) - Dense
*/
public enum CableCoreType {
GLASS("parts/cable/core/glass"), COVERED("parts/cable/core/covered"), DENSE("parts/cable/core/dense_smart");
GLASS("part/cable/core/glass"), COVERED("part/cable/core/covered"), DENSE("part/cable/core/dense_smart");
private static final Map<AECableType, CableCoreType> cableMapping = generateCableMapping();
@@ -23,7 +23,7 @@ import appeng.core.AppEng;
public class P2PTunnelFrequencyModel implements IModelGeometry<P2PTunnelFrequencyModel> {
private static final Material TEXTURE = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "parts/p2p_tunnel_frequency"));
new ResourceLocation(AppEng.MOD_ID, "part/p2p_tunnel_frequency"));
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
@@ -34,16 +34,16 @@ import appeng.core.AppEng;
public class SmartCableTextures {
public static final Material[] SMART_CHANNELS_TEXTURES = Arrays
.stream(new ResourceLocation[] { new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_00"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_01"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_02"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_03"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_04"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_10"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_11"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_12"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_13"), //
new ResourceLocation(AppEng.MOD_ID, "parts/cable/smart/channels_14")//
.stream(new ResourceLocation[] { new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_00"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_01"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_02"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_03"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_04"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_10"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_11"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_12"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_13"), //
new ResourceLocation(AppEng.MOD_ID, "part/cable/smart/channels_14")//
}).map(e -> new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, e)).toArray(Material[]::new);
// Textures used to display channels on smart cables. There's two sets of 5
@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.item.Item;
@@ -49,6 +50,19 @@ public class DriveBakedModel extends DelegateBakedModel {
this.defaultCell = defaultCell;
}
/**
* Calculates the origin of a drive slot for positioning a cell model into it.
*/
public static void getSlotOrigin(int row, int col, Vector3f translation) {
// Position this drive model copy at the correct slot. The transform is based on
// the cell-model being in slot 0,0,0 while the upper left slot's origin is at
// 9,13,1
float xOffset = (9 - col * 8) / 16.0f;
float yOffset = (13 - row * 3) / 16.0f;
float zOffset = 1 / 16.0f;
translation.set(xOffset, yOffset, zOffset);
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@@ -63,17 +77,14 @@ public class DriveBakedModel extends DelegateBakedModel {
DriveSlotsState slotsState = driveModelData.getSlotsState();
Vector3f slotTranslation = new Vector3f();
if (slotsState != null) {
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) {
Matrix4f transform = new Matrix4f();
// Position this drive model copy at the correct slot. The transform is based on
// the
// cell-model being in slot 0,0 at the top left of the drive.
float xOffset = -col * 8 / 16.0f;
float yOffset = -row * 3 / 16.0f;
transform.setTranslation(xOffset, yOffset, 0);
getSlotOrigin(row, col, slotTranslation);
transform.setTranslation(slotTranslation.getX(), slotTranslation.getY(), slotTranslation.getZ());
int slot = row * 2 + col;
@@ -184,7 +184,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
@Override
public boolean isAmbientOcclusion() {
return true;
return false;
}
@Override
@@ -0,0 +1,106 @@
package appeng.client.render.tesr;
import java.util.EnumMap;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.block.storage.DriveSlotState;
/**
* Utility class to render LEDs for storage cells from a Tile Entity Renderer.
*/
class CellLedRenderer {
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
// Color used for the cell indicator for blinking during recent activity
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
static {
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
}
// The positions are based on the upper left slot in a drive
private static final float L = 5 / 16.f; // left (x-axis)
private static final float R = 4 / 16.f; // right (x-axis)
private static final float T = 1 / 16.f; // top (y-axis)
private static final float B = -0.001f / 16.f; // bottom (y-axis)
private static final float FR = -0.001f / 16.f; // front (z-axis)
private static final float BA = 0.499f / 16.f; // back (z-axis)
// Vertex data for the LED cuboid (has no back)
// Directions are when looking from the front onto the LED
private static final float[] LED_QUADS = {
// Front Face
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
// Left Face
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
// Right Face
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
// Top Face
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
// Bottom Face
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
public static final RenderType RENDER_LAYER = RenderType.makeType("ae_drive_leds",
DefaultVertexFormats.POSITION_COLOR, 7, 32565, false, true, RenderType.State.getBuilder().build(false));
public static void renderLed(IChestOrDrive drive, int slot, IVertexBuilder buffer, MatrixStack ms,
float partialTicks) {
Vector3f color = getColorForSlot(drive, slot, partialTicks);
if (color == null) {
return;
}
for (int i = 0; i < LED_QUADS.length; i += 3) {
float x = LED_QUADS[i];
float y = LED_QUADS[i + 1];
float z = LED_QUADS[i + 2];
buffer.pos(ms.getLast().getMatrix(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
.endVertex();
}
}
private static Vector3f getColorForSlot(IChestOrDrive drive, int slot, float partialTicks) {
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
if (state == DriveSlotState.EMPTY) {
return null;
}
if (!drive.isPowered()) {
return STATE_COLORS.get(DriveSlotState.OFFLINE);
}
Vector3f col = STATE_COLORS.get(state);
if (drive.isCellBlinking(slot)) {
// 200 ms interval (100ms to get to red, then 100ms back)
long t = System.currentTimeMillis() % 200;
float f = (t - 100) / 200.0f + 0.5f;
f = easeInOutCubic(f);
col = col.copy();
col.lerp(BLINK_COLOR, f);
}
return col;
}
private static float easeInOutCubic(float x) {
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
}
private CellLedRenderer() {
}
}
@@ -0,0 +1,154 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.tesr;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ModelManager;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.client.ICellModelRegistry;
import appeng.block.storage.DriveSlotsState;
import appeng.client.render.DelegateBakedModel;
import appeng.client.render.FacingToRotation;
import appeng.core.Api;
import appeng.tile.storage.ChestTileEntity;
/**
* The tile entity renderer for ME chests takes care of rendering the right
* model for the inserted cell, as well as the LED.
*/
public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity> {
private final ICellModelRegistry cellModelRegistry = Api.instance().client().cells();
private final ModelManager modelManager;
private final BlockModelRenderer blockRenderer;
public ChestTileEntityRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
Minecraft client = Minecraft.getInstance();
modelManager = client.getModelManager();
blockRenderer = client.getBlockRendererDispatcher().getBlockModelRenderer();
}
@Override
public void render(ChestTileEntity chest, float partialTicks, MatrixStack matrices, IRenderTypeBuffer buffers,
int combinedLight, int combinedOverlay) {
World world = chest.getWorld();
if (world == null) {
return;
}
DriveSlotsState driveSlotState = DriveSlotsState.fromChestOrDrive(chest);
Item cellItem = driveSlotState.getCell(0);
if (cellItem == null || cellItem == Items.AIR) {
return; // No cell inserted into chest
}
ResourceLocation cellModelLocation = cellModelRegistry.model(cellItem);
if (cellModelLocation == null) {
cellModelLocation = cellModelRegistry.getDefaultModel();
}
IBakedModel model = modelManager.getModel(cellModelLocation);
matrices.push();
matrices.translate(0.5, 0.5, 0.5);
FacingToRotation rotation = FacingToRotation.get(chest.getForward(), chest.getUp());
rotation.push(matrices);
matrices.translate(-0.5, -0.5, -0.5);
// The models are created for the top-left slot of the drive model,
// we need to move them into place for the slot on the ME chest
matrices.translate(5 / 16.0, 4 / 16.0, 0);
// Render the cell model as-if it was a block model
IVertexBuilder buffer = buffers.getBuffer(RenderType.getCutout());
// We "fake" the position here to make it use the light-value in front of the
// drive
FaceRotatingModel rotatedModel = new FaceRotatingModel(model, rotation);
blockRenderer.renderModel(world, rotatedModel, chest.getBlockState(), chest.getPos(), matrices, buffer, false,
new Random(), 0L, combinedOverlay, EmptyModelData.INSTANCE);
IVertexBuilder ledBuffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
CellLedRenderer.renderLed(chest, 0, ledBuffer, matrices, partialTicks);
matrices.pop();
}
/**
* The actual vertex data will be transformed using the matrix stack, but the
* faces will not be correctly rotated so the incorrect lighting data would be
* used to apply diffuse lighting and the lightmap texture.
*/
private static class FaceRotatingModel extends DelegateBakedModel {
private final FacingToRotation r;
protected FaceRotatingModel(IBakedModel base, FacingToRotation r) {
super(base);
this.r = r;
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (side != null) {
side = r.rotate(side); // This fixes the incorrect lightmap position
}
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
for (int i = 0; i < quads.size(); i++) {
BakedQuad quad = quads.get(i);
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
quad.func_187508_a(), quad.shouldApplyDiffuseLighting()));
}
return quads;
}
}
}
@@ -1,21 +1,17 @@
package appeng.client.render.tesr;
import java.util.EnumMap;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.block.storage.DriveSlotState;
import appeng.client.render.FacingToRotation;
import appeng.client.render.model.DriveBakedModel;
import appeng.tile.storage.DriveTileEntity;
/**
@@ -24,44 +20,6 @@ import appeng.tile.storage.DriveTileEntity;
@OnlyIn(Dist.CLIENT)
public class DriveLedTileEntityRenderer extends TileEntityRenderer<DriveTileEntity> {
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
// Color used for the cell indicator for blinking during recent activity
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
static {
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
}
private static final float L = 14 / 16.f; // left (x-axis)
private static final float R = 13 / 16.f; // right (x-axis)
private static final float T = 14 / 16.f; // top (x-axis)
private static final float B = 12.999f / 16.f; // bottom (x-axis)
private static final float FR = 0.999f / 16.f; // front (z-axis)
private static final float BA = 1.499f / 16.f; // back (z-axis)
// Vertex data for the LED cuboid (has no back)
// Directions are when looking from the front onto the LED
private static final float[] LED_QUADS = {
// Front Face
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
// Left Face
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
// Right Face
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
// Top Face
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
// Bottom Face
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
private static final RenderType STATE = RenderType.makeType("ae_drive_leds", DefaultVertexFormats.POSITION_COLOR, 7,
32565, false, true, RenderType.State.getBuilder().build(false));
public DriveLedTileEntityRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
}
@@ -79,32 +37,18 @@ public class DriveLedTileEntityRenderer extends TileEntityRenderer<DriveTileEnti
FacingToRotation.get(drive.getForward(), drive.getUp()).push(ms);
ms.translate(-0.5, -0.5, -0.5);
IVertexBuilder buffer = buffers.getBuffer(STATE);
IVertexBuilder buffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
Vector3f slotTranslation = new Vector3f();
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) {
int slot = row * 2 + col;
Vector3f color = getColorForSlot(drive, slot, partialTicks);
if (color == null) {
continue;
}
ms.push();
// Position this drive model copy at the correct slot. The transform is based on
// the
// cell-model being in slot 0,0 at the top left of the drive.
float xOffset = -col * 8 / 16.0f;
float yOffset = -row * 3 / 16.0f;
ms.translate(xOffset, yOffset, 0);
DriveBakedModel.getSlotOrigin(row, col, slotTranslation);
ms.translate(slotTranslation.getX(), slotTranslation.getY(), slotTranslation.getZ());
for (int i = 0; i < LED_QUADS.length; i += 3) {
float x = LED_QUADS[i];
float y = LED_QUADS[i + 1];
float z = LED_QUADS[i + 2];
buffer.pos(ms.getLast().getMatrix(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
.endVertex();
}
int slot = row * 2 + col;
CellLedRenderer.renderLed(drive, slot, buffer, ms, partialTicks);
ms.pop();
}
@@ -113,31 +57,4 @@ public class DriveLedTileEntityRenderer extends TileEntityRenderer<DriveTileEnti
ms.pop();
}
private Vector3f getColorForSlot(DriveTileEntity drive, int slot, float partialTicks) {
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
if (state == DriveSlotState.EMPTY) {
return null;
}
if (!drive.isPowered()) {
return STATE_COLORS.get(DriveSlotState.OFFLINE);
}
Vector3f col = STATE_COLORS.get(state);
if (drive.isCellBlinking(slot)) {
// 200 ms interval (100ms to get to red, then 100ms back)
long t = System.currentTimeMillis() % 200;
float f = (t - 100) / 200.0f + 0.5f;
f = easeInOutCubic(f);
col = col.copy();
col.lerp(BLINK_COLOR, f);
}
return col;
}
private static float easeInOutCubic(float x) {
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
}
}
@@ -47,7 +47,6 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.helpers.ICustomNameObject;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.tile.crafting.CraftingTileEntity;
import appeng.util.Platform;
@@ -82,7 +81,7 @@ public class CraftingCPUContainer extends AEBaseContainer
}
if (te instanceof CraftingTileEntity) {
this.setCPU((ICraftingCPU) ((IAEMultiBlock) te).getCluster());
this.setCPU(((CraftingTileEntity) te).getCluster());
}
if (this.getNetwork() == null && Platform.isServer()) {
@@ -18,7 +18,6 @@
package appeng.container.implementations;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType;
@@ -33,6 +32,7 @@ import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.FakeTypeOnlySlot;
@@ -58,7 +58,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
private final LevelEmitterPart lvlEmitter;
@OnlyIn(Dist.CLIENT)
private TextFieldWidget textField;
private NumberEntryWidget textField;
@GuiSync(2)
public LevelType lvType;
@GuiSync(3)
@@ -72,9 +72,9 @@ public class LevelEmitterContainer extends UpgradeableContainer {
}
@OnlyIn(Dist.CLIENT)
public void setTextField(final TextFieldWidget level) {
public void setTextField(final NumberEntryWidget level) {
this.textField = level;
this.textField.setText(String.valueOf(this.EmitterValue));
this.textField.setValue(this.EmitterValue);
}
public void setLevel(final long l, final PlayerEntity player) {
@@ -104,7 +104,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
final IItemHandler inv = this.getUpgradeable().getInventoryByName("config");
final int y = 40;
final int x = 80 + 44;
final int x = 80 + 57;
this.addSlot(new FakeTypeOnlySlot(inv, 0, x, y));
}
@@ -140,7 +140,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
if (field.equals("EmitterValue")) {
if (this.textField != null) {
this.textField.setText(String.valueOf(this.EmitterValue));
this.textField.setValue(this.EmitterValue);
}
}
}
@@ -18,7 +18,6 @@
package appeng.container.implementations;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType;
@@ -29,6 +28,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPart;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync;
@@ -53,7 +53,8 @@ public class PriorityContainer extends AEBaseContainer {
private final IPriorityHost priHost;
@OnlyIn(Dist.CLIENT)
private TextFieldWidget textField;
private NumberEntryWidget textField;
@GuiSync(2)
public long PriorityValue = -1;
@@ -64,9 +65,9 @@ public class PriorityContainer extends AEBaseContainer {
}
@OnlyIn(Dist.CLIENT)
public void setTextField(final TextFieldWidget level) {
public void setTextField(final NumberEntryWidget level) {
this.textField = level;
this.textField.setText(String.valueOf(this.PriorityValue));
this.textField.setValue(this.PriorityValue, true);
}
public void setPriority(final int newValue, final PlayerEntity player) {
@@ -88,7 +89,7 @@ public class PriorityContainer extends AEBaseContainer {
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
if (field.equals("PriorityValue")) {
if (this.textField != null) {
this.textField.setText(String.valueOf(this.PriorityValue));
this.textField.setValue(this.PriorityValue, true);
}
}
+18 -14
View File
@@ -53,6 +53,7 @@ import appeng.api.config.Settings;
import appeng.api.config.TerminalStyle;
import appeng.api.config.YesNo;
import appeng.api.features.AEFeature;
import appeng.client.gui.NumberEntryType;
import appeng.core.settings.TickRates;
import appeng.util.EnumCycler;
@@ -273,20 +274,23 @@ public final class AEConfig {
}
}
public int craftItemsByStackAmounts(final int i) {
return this.craftByStacks[i];
}
public int priorityByStacksAmounts(final int i) {
return this.priorityByStacks[i];
}
public int levelByStackAmounts(final int i) {
return this.levelByStacks[i];
}
public int levelByMillyBuckets(final int i) {
return this.levelByMillibuckets[i];
/**
* Returns an array with the quantity-steps for the +/- buttons in number entry
* dialogs of the given type. Guaranteed to have 4 entries.
*/
public int[] getNumberEntrySteps(NumberEntryType type) {
switch (type) {
case CRAFT_ITEM_COUNT:
return craftByStacks;
case PRIORITY:
return priorityByStacks;
case LEVEL_ITEM_COUNT:
return levelByStacks;
case LEVEL_FLUID_VOLUME:
return levelByMillibuckets;
default:
throw new IllegalArgumentException("Unknown number entry: " + type);
}
}
public PowerUnits getSelectedPowerUnit() {
+4 -6
View File
@@ -115,7 +115,7 @@ public final class AppEng {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
proxy = DistExecutor.runForDist(() -> ClientHelper::new, () -> ServerHelper::new);
proxy = DistExecutor.safeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
CrashReportExtender.registerCrashCallable(new ModCrashEnhancement());
@@ -136,15 +136,14 @@ public final class AppEng {
modEventBus.addGenericListener(ModDimension.class, registration::registerModDimension);
modEventBus.addListener(Integrations::enqueueIMC);
modEventBus.addListener(this::commonSetup);
// Register client-only events
DistExecutor.runWhenOn(Dist.CLIENT, () -> registration::registerClientEvents);
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> modEventBus.addListener(this::clientSetup));
MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::unloadWorld);
MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::onTick);
TickHandler.setup(MinecraftForge.EVENT_BUS);
MinecraftForge.EVENT_BUS.addListener(this::onServerAboutToStart);
MinecraftForge.EVENT_BUS.addListener(this::serverStopped);
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
@@ -154,7 +153,6 @@ public final class AppEng {
}
private void commonSetup(FMLCommonSetupEvent event) {
ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IInitComponent.class)
.forEachRemaining(IInitComponent::initialize);
@@ -300,7 +298,7 @@ public final class AppEng {
private void serverStopped(final FMLServerStoppedEvent event) {
WorldData.instance().onServerStoppped();
TickHandler.INSTANCE.shutdown();
TickHandler.instance().shutdown();
}
}
@@ -97,6 +97,7 @@ import appeng.client.render.crafting.CraftingMonitorTESR;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
import appeng.client.render.spatial.SpatialPylonRendering;
import appeng.client.render.tesr.ChestTileEntityRenderer;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.DriveLedTileEntityRenderer;
import appeng.client.render.tesr.SkyChestTESR;
@@ -426,7 +427,14 @@ public final class ApiBlocks implements IBlocks {
}).build())
.rendering(new DriveRendering()).build();
this.chest = registry.block("chest", ChestBlock::new).features(AEFeature.STORAGE_CELLS, AEFeature.ME_CHEST)
.tileEntity(registry.tileEntity("chest", ChestTileEntity.class, ChestTileEntity::new).build())
.tileEntity(registry.tileEntity("chest", ChestTileEntity.class, ChestTileEntity::new)
.rendering(new TileEntityRenderingCustomizer<ChestTileEntity>() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(TileEntityRendering<ChestTileEntity> rendering) {
rendering.tileEntityRenderer(ChestTileEntityRenderer::new);
}
}).build())
.rendering(new ChestRendering()).build();
this.iface = registry.block("interface", InterfaceBlock::new).features(AEFeature.INTERFACE)
.tileEntity(
@@ -27,7 +27,7 @@ public enum GuiText {
Chest, StoredEnergy, Of, Condenser, Drive, GrindStone, SkyChest,
VibrationChamber, SpatialIOPort, LevelEmitter, FluidLevelEmitter, Terminal,
VibrationChamber, SpatialIOPort, LevelEmitter, FluidLevelEmitter, FluidLevelEmitterUnit, Terminal,
Interface, FluidInterface, Config, StoredItems, StoredFluids, Patterns, ImportBus, ImportBusFluids, ExportBus,
ExportBusFluids,
@@ -103,6 +103,7 @@ public class BlockTransitionEffectPacket extends BasePacket {
playBreakOrPickupSound();
}
@OnlyIn(Dist.CLIENT)
private void spawnParticles() {
EnergyParticleData data = new EnergyParticleData(false, direction);
@@ -121,6 +122,7 @@ public class BlockTransitionEffectPacket extends BasePacket {
}
}
@OnlyIn(Dist.CLIENT)
private void playBreakOrPickupSound() {
SoundEvent soundEvent;
@@ -57,6 +57,6 @@ public class PaintedEntityPacket extends BasePacket {
@Override
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
final PlayerColor pc = new PlayerColor(this.entityId, this.myColor, this.ticks);
TickHandler.INSTANCE.getPlayerColors().put(this.entityId, pc);
TickHandler.instance().getPlayerColors().put(this.entityId, pc);
}
}
@@ -125,7 +125,7 @@ public class CraftingJob implements Runnable, ICraftingJob {
public void run() {
try {
try {
TickHandler.INSTANCE.registerCraftingSimulation(this.world, this);
TickHandler.instance().registerCraftingSimulation(this.world, this);
this.handlePausing();
final Stopwatch timer = Stopwatch.createStarted();
@@ -76,7 +76,7 @@ public class DebugCardItem extends AEBaseItem {
int grids = 0;
int totalNodes = 0;
for (final Grid g : TickHandler.INSTANCE.getGridList()) {
for (final Grid g : TickHandler.instance().getGridList()) {
grids++;
totalNodes += g.getNodes().size();
}
@@ -27,6 +27,7 @@ import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
@@ -38,6 +39,8 @@ import appeng.util.Platform;
public final class SingularityEntity extends AEBaseItemEntity {
private static final ResourceLocation TAG_ENDER_PEARL = new ResourceLocation("forge:ender_pearls");
public static EntityType<SingularityEntity> TYPE;
private static int randTickSeed = 0;
@@ -84,6 +87,17 @@ public final class SingularityEntity extends AEBaseItemEntity {
if (!other.isEmpty()) {
boolean matches = false;
if (materials.enderDust().isSameAs(other)) {
matches = true;
}
// check... other name.
if (!matches) {
if (other.getItem().getTags().contains(TAG_ENDER_PEARL)) {
matches = true;
}
}
if (matches) {
while (item.getCount() > 0 && other.getCount() > 0) {
other.grow(-1);
@@ -1,17 +1,15 @@
package appeng.fluids.client.gui;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.client.gui.NumberEntryType;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -19,7 +17,8 @@ import appeng.fluids.client.gui.widgets.FluidSlotWidget;
import appeng.fluids.container.FluidLevelEmitterContainer;
public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitterContainer> {
private NumberBox level;
private NumberEntryWidget level;
public FluidLevelEmitterScreen(FluidLevelEmitterContainer container, PlayerInventory playerInventory,
ITextComponent title) {
@@ -30,17 +29,14 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
public void init() {
super.init();
this.level = new NumberBox(this.font, this.guiLeft + 24, this.guiTop + 43, 79, this.font.FONT_HEIGHT,
Long.class);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.changeFocus(true);
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME,
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75);
container.setTextField(this.level);
this.level.addButtons(children::add, this::addButton);
final int y = 40;
final int x = 80 + 44;
final int x = 80 + 57;
this.guiSlots.add(new FluidSlotWidget(this.container.getFluidConfigInventory(), 0, 0, x, y));
}
@@ -48,22 +44,6 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
protected void addButtons() {
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28,
Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL);
final int a = AEConfig.instance().levelByMillyBuckets(0);
final int b = AEConfig.instance().levelByMillyBuckets(1);
final int c = AEConfig.instance().levelByMillyBuckets(2);
final int d = AEConfig.instance().levelByMillyBuckets(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 17, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 17, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 17, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 17, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 59, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 59, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 59, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 59, 38, 20, "-" + d, btn -> addQty(-d)));
this.addButton(this.redstoneMode);
}
@@ -73,6 +53,13 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
this.level.render(mouseX, mouseY, partialTicks);
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) {
super.drawFG(offsetX, offsetY, mouseX, mouseY);
this.font.drawString(GuiText.FluidLevelEmitterUnit.getLocal(), 110, 44, COLOR_DARK_GRAY);
}
@Override
protected boolean drawUpgrades() {
return false;
@@ -92,89 +79,8 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
protected void handleButtonVisibility() {
}
private void addQty(final long i) {
try {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
long result = Long.parseLong(Out);
result += i;
if (result < 0) {
result = 0;
}
this.level.setText(Out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", Out));
} catch (final NumberFormatException e) {
// nope..
this.level.setText("0");
}
private void onLevelChange(long level) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(level)));
}
@Override
public boolean charTyped(char character, int keyCode) {
if (level.charTyped(character, keyCode)) {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", Out));
return true;
}
return super.charTyped(character, keyCode);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.level.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", Out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
@@ -93,7 +93,7 @@ public class FluidTankWidget extends Widget implements ITooltip {
return desc + "\n" + amountToText;
}
return null;
return "";
}
@Override
@@ -1,6 +1,5 @@
package appeng.fluids.container;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType;
@@ -11,6 +10,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync;
import appeng.container.implementations.ContainerHelper;
@@ -35,7 +35,7 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
private final FluidLevelEmitterPart lvlEmitter;
@OnlyIn(Dist.CLIENT)
private TextFieldWidget textField;
private NumberEntryWidget textField;
@GuiSync(3)
public long EmitterValue = -1;
@@ -45,9 +45,9 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
}
@OnlyIn(Dist.CLIENT)
public void setTextField(final TextFieldWidget level) {
public void setTextField(final NumberEntryWidget level) {
this.textField = level;
this.textField.setText(String.valueOf(this.EmitterValue));
this.textField.setValue(this.EmitterValue);
}
public void setLevel(final long l, final PlayerEntity player) {
@@ -87,7 +87,7 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
if (field.equals("EmitterValue")) {
if (this.textField != null) {
this.textField.setText(String.valueOf(this.EmitterValue));
this.textField.setValue(this.EmitterValue);
}
}
}
+72 -42
View File
@@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.WeakHashMap;
@@ -36,11 +37,15 @@ import com.google.common.collect.Multimap;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.Type;
import net.minecraftforge.event.TickEvent.ServerTickEvent;
import net.minecraftforge.event.TickEvent.WorldTickEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.DistExecutor.SafeRunnable;
import appeng.api.networking.IGridNode;
import appeng.api.parts.CableRenderMode;
@@ -58,17 +63,39 @@ import appeng.util.Platform;
public class TickHandler {
public static final TickHandler INSTANCE = new TickHandler();
private static final TickHandler INSTANCE = new TickHandler();
private final Queue<IWorldCallable<?>> serverQueue = new ArrayDeque<>();
private final Multimap<World, CraftingJob> craftingJobs = LinkedListMultimap.create();
private final WeakHashMap<IWorld, Queue<IWorldCallable<?>>> callQueue = new WeakHashMap<>();
private final Map<IWorld, Queue<IWorldCallable<?>>> callQueue = new WeakHashMap<>();
private final HandlerRep server = new HandlerRep();
private final HandlerRep client = new HandlerRep();
private final HashMap<Integer, PlayerColor> cliPlayerColors = new HashMap<>();
private final HashMap<Integer, PlayerColor> srvPlayerColors = new HashMap<>();
private final Map<Integer, PlayerColor> cliPlayerColors = new HashMap<>();
private final Map<Integer, PlayerColor> srvPlayerColors = new HashMap<>();
private CableRenderMode crm = CableRenderMode.STANDARD;
public HashMap<Integer, PlayerColor> getPlayerColors() {
public static TickHandler instance() {
return INSTANCE;
}
public static void setup(IEventBus eventBus) {
eventBus.addListener(INSTANCE::onServerTick);
eventBus.addListener(INSTANCE::onWorldTick);
eventBus.addListener(INSTANCE::onUnloadWorld);
// DistExecutor does not like functional interfaces
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> new SafeRunnable() {
private static final long serialVersionUID = 5221919736953944125L;
@Override
public void run() {
eventBus.addListener(INSTANCE::onClientTick);
}
});
}
public Map<Integer, PlayerColor> getPlayerColors() {
if (Platform.isServer()) {
return this.srvPlayerColors;
}
@@ -91,8 +118,8 @@ public class TickHandler {
}
public void addInit(final AEBaseTileEntity tile) {
if (Platform.isServer()) // for no there is no reason to care about this on the client...
{
// for no there is no reason to care about this on the client...
if (Platform.isServer()) {
this.getRepo().tiles.add(tile);
}
}
@@ -105,15 +132,15 @@ public class TickHandler {
}
public void addNetwork(final Grid grid) {
if (Platform.isServer()) // for no there is no reason to care about this on the client...
{
// for no there is no reason to care about this on the client...
if (Platform.isServer()) {
this.getRepo().addNetwork(grid);
}
}
public void removeNetwork(final Grid grid) {
if (Platform.isServer()) // for no there is no reason to care about this on the client...
{
// for no there is no reason to care about this on the client...
if (Platform.isServer()) {
this.getRepo().removeNetwork(grid);
}
}
@@ -126,9 +153,9 @@ public class TickHandler {
this.getRepo().clear();
}
public void unloadWorld(final WorldEvent.Unload ev) {
if (Platform.isServer()) // for no there is no reason to care about this on the client...
{
public void onUnloadWorld(final WorldEvent.Unload ev) {
// for no there is no reason to care about this on the client...
if (Platform.isServer()) {
final List<IGridNode> toDestroy = new ArrayList<>();
this.getRepo().updateNetworks();
@@ -146,25 +173,36 @@ public class TickHandler {
}
}
public void onTick(final TickEvent ev) {
if (ev.type == Type.CLIENT && ev.phase == Phase.START) {
public void onClientTick(final ClientTickEvent ev) {
if (ev.phase == Phase.START) {
this.tickColors(this.cliPlayerColors);
final CableRenderMode currentMode = Api.instance().partHelper().getCableRenderMode();
if (currentMode != this.crm) {
this.crm = currentMode;
AppEng.proxy.triggerUpdates();
}
}
}
if (ev.type == Type.WORLD && ev.phase == Phase.END) {
final WorldTickEvent wte = (WorldTickEvent) ev;
public void onWorldTick(final WorldTickEvent ev) {
if (ev.phase == Phase.START) {
final World world = ev.world;
final Queue<IWorldCallable<?>> queue = this.callQueue.get(world);
this.processQueue(queue, world);
}
if (ev.phase == Phase.END) {
synchronized (this.craftingJobs) {
final Collection<CraftingJob> jobSet = this.craftingJobs.get(wte.world);
final Collection<CraftingJob> jobSet = this.craftingJobs.get(ev.world);
if (!jobSet.isEmpty()) {
final int simTime = Math.max(1,
AEConfig.instance().getCraftingCalculationTimePerTick() / jobSet.size());
final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
final Iterator<CraftingJob> i = jobSet.iterator();
while (i.hasNext()) {
final CraftingJob cj = i.next();
if (!cj.simulateFor(simTime)) {
@@ -174,10 +212,12 @@ public class TickHandler {
}
}
}
}
// for no there is no reason to care about this on the client...
else if (ev.type == Type.SERVER && ev.phase == Phase.END) {
public void onServerTick(final ServerTickEvent ev) {
if (ev.phase == Phase.END) {
this.tickColors(this.srvPlayerColors);
// ready tiles.
final HandlerRep repo = this.getRepo();
while (!repo.tiles.isEmpty()) {
@@ -196,17 +236,17 @@ public class TickHandler {
// cross world queue.
this.processQueue(this.serverQueue, null);
}
}
// world synced queue(s)
if (ev.type == Type.WORLD && ev.phase == Phase.START) {
final World world = ((WorldTickEvent) ev).world;
final Queue<IWorldCallable<?>> queue = this.callQueue.get(world);
this.processQueue(queue, world);
public void registerCraftingSimulation(final World world, final CraftingJob craftingJob) {
synchronized (this.craftingJobs) {
this.craftingJobs.put(world, craftingJob);
}
}
private void tickColors(final HashMap<Integer, PlayerColor> playerSet) {
private void tickColors(final Map<Integer, PlayerColor> playerSet) {
final Iterator<PlayerColor> i = playerSet.values().iterator();
while (i.hasNext()) {
final PlayerColor pc = i.next();
if (pc.ticksLeft <= 0) {
@@ -235,16 +275,6 @@ public class TickHandler {
AELog.debug(e);
}
}
// long time = sw.elapsed( TimeUnit.MILLISECONDS );
// if ( time > 0 )
// AELog.info( "processQueue Time: " + time + "ms" );
}
public void registerCraftingSimulation(final World world, final CraftingJob craftingJob) {
synchronized (this.craftingJobs) {
this.craftingJobs.put(world, craftingJob);
}
}
private static class HandlerRep {
@@ -118,6 +118,9 @@ public abstract class AbstractStorageCell<T extends IAEStack<T>> extends AEBaseI
@Override
public FuzzyMode getFuzzyMode(final ItemStack is) {
final String fz = is.getOrCreateTag().getString("FuzzyMode");
if (fz.isEmpty()) {
return FuzzyMode.IGNORE_ALL;
}
try {
return FuzzyMode.valueOf(fz);
} catch (final Throwable t) {
@@ -188,26 +188,24 @@ public class MatterCannonItem extends AEBasePoweredItem implements IStorageCell<
for (int l = 0; l < list.size(); ++l) {
final Entity entity1 = (Entity) list.get(l);
if (!entity1.isAlive() && entity1 != p && !(entity1 instanceof ItemEntity)) {
if (entity1.isAlive()) {
// prevent killing / flying of mounts.
if (entity1.isRidingOrBeingRiddenBy(p)) {
continue;
}
if (entity1.isAlive() && entity1 != p && !(entity1 instanceof ItemEntity)) {
// prevent killing / flying of mounts.
if (entity1.isRidingOrBeingRiddenBy(p)) {
continue;
}
final float f1 = 0.3F;
final float f1 = 0.3F;
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow(f1, f1, f1);
final Vec3d intersection = boundingBox.rayTrace(Vec3d, Vec3d1).orElse(null);
final AxisAlignedBB boundingBox = entity1.getBoundingBox().grow(f1, f1, f1);
final Vec3d intersection = boundingBox.rayTrace(Vec3d, Vec3d1).orElse(null);
if (intersection != null) {
final double nd = Vec3d.squareDistanceTo(intersection);
if (intersection != null) {
final double nd = Vec3d.squareDistanceTo(intersection);
if (nd < closest) {
entity = entity1;
entityIntersection = intersection;
closest = nd;
}
if (nd < closest) {
entity = entity1;
entityIntersection = intersection;
closest = nd;
}
}
}
@@ -246,7 +244,7 @@ public class MatterCannonItem extends AEBasePoweredItem implements IStorageCell<
final int id = entityHit.getEntityId();
final PlayerColor marker = new PlayerColor(id, col, 20 * 30);
TickHandler.INSTANCE.getPlayerColors().put(id, marker);
TickHandler.instance().getPlayerColors().put(id, marker);
if (entityHit instanceof SheepEntity) {
final SheepEntity sh = (SheepEntity) entityHit;
+2 -2
View File
@@ -64,7 +64,7 @@ public class Grid implements IGrid {
this.postEvent(new MENetworkPostCacheConstruction());
TickHandler.INSTANCE.addNetwork(this);
TickHandler.instance().addNetwork(this);
center.setGrid(this);
}
@@ -112,7 +112,7 @@ public class Grid implements IGrid {
this.pivot = (GridNode) n.next();
} else {
this.pivot = null;
TickHandler.INSTANCE.removeNetwork(this);
TickHandler.instance().removeNetwork(this);
this.myStorage.remove();
}
}
+2 -2
View File
@@ -384,7 +384,7 @@ public class GridNode implements IGridNode, IPathItem {
GridConnection.create(node, this, f.getOpposite());
} catch (SecurityConnectionException e) {
AELog.debug(e);
TickHandler.INSTANCE.addCallable(node.getWorld(), new MachineSecurityBreak(this));
TickHandler.instance().addCallable(node.getWorld(), new MachineSecurityBreak(this));
return;
} catch (final FailedConnectionException e) {
@@ -411,7 +411,7 @@ public class GridNode implements IGridNode, IPathItem {
} catch (SecurityConnectionException e) {
AELog.debug(e);
TickHandler.INSTANCE.addCallable(node.getWorld(), new MachineSecurityBreak(this));
TickHandler.instance().addCallable(node.getWorld(), new MachineSecurityBreak(this));
return;
} catch (final FailedConnectionException e) {
+87 -21
View File
@@ -23,16 +23,19 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -72,10 +75,33 @@ public class EnergyGridCache implements IEnergyGrid {
return Double.compare(percent1, percent2);
};
private static final Comparator<IAEPowerStorage> COMPARATOR_HIGHEST_PRIORITY_FIRST = (o1, o2) -> {
final int cmp = Integer.compare(o2.getPriority(), o1.getPriority());
return cmp != 0 ? cmp : Integer.compare(System.identityHashCode(o2), System.identityHashCode(o1));
};
private static final Comparator<IAEPowerStorage> COMPARATOR_LOWEST_PRIORITY_FIRST = (o1,
o2) -> -COMPARATOR_HIGHEST_PRIORITY_FIRST.compare(o1, o2);
private final NavigableSet<EnergyThreshold> interests = Sets.newTreeSet();
private final double averageLength = 40.0;
private final Set<IAEPowerStorage> providers = new LinkedHashSet<>();
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>();
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final SortedSet<IAEPowerStorage> providers = new ObjectRBTreeSet<>(COMPARATOR_HIGHEST_PRIORITY_FIRST);
// Used to track whether an extraction is currently in progress, to fail fast
// when something externally
// modifies the energy grid.
private boolean ongoingExtractOperation = false;
// Should only be modified from the add/remove methods below to guard against
// concurrent modifications
private final SortedSet<IAEPowerStorage> requesters = new ObjectRBTreeSet<>(COMPARATOR_LOWEST_PRIORITY_FIRST);
// Used to track whether an injection is currently in progress, to fail fast
// when something externally
// modifies the energy grid.
private boolean ongoingInjectOperation = false;
private final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
private final IGrid myGrid;
private final HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<>();
@@ -138,12 +164,12 @@ public class EnergyGridCache implements IEnergyGrid {
switch (ev.type) {
case PROVIDE_POWER:
if (ev.storage.getPowerFlow() != AccessRestriction.WRITE) {
this.providers.add(ev.storage);
addProvider(ev.storage);
}
break;
case REQUEST_POWER:
if (ev.storage.getPowerFlow() != AccessRestriction.READ) {
this.requesters.add(ev.storage);
addRequester(ev.storage);
}
break;
}
@@ -271,16 +297,21 @@ public class EnergyGridCache implements IEnergyGrid {
final Iterator<IAEPowerStorage> it = this.providers.iterator();
while (extractedPower < amt && it.hasNext()) {
final IAEPowerStorage node = it.next();
ongoingExtractOperation = true;
try {
while (extractedPower < amt && it.hasNext()) {
final IAEPowerStorage node = it.next();
final double req = amt - extractedPower;
final double newPower = node.extractAEPower(req, mode, PowerMultiplier.ONE);
extractedPower += newPower;
final double req = amt - extractedPower;
final double newPower = node.extractAEPower(req, mode, PowerMultiplier.ONE);
extractedPower += newPower;
if (newPower < req && mode == Actionable.MODULATE) {
it.remove();
if (newPower < req && mode == Actionable.MODULATE) {
it.remove();
}
}
} finally {
ongoingExtractOperation = false;
}
final double result = Math.min(extractedPower, amt);
@@ -303,13 +334,18 @@ public class EnergyGridCache implements IEnergyGrid {
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
while (amt > 0 && it.hasNext()) {
final IAEPowerStorage node = it.next();
amt = node.injectAEPower(amt, mode);
ongoingInjectOperation = true;
try {
while (amt > 0 && it.hasNext()) {
final IAEPowerStorage node = it.next();
amt = node.injectAEPower(amt, mode);
if (amt > 0 && mode == Actionable.MODULATE) {
it.remove();
if (amt > 0 && mode == Actionable.MODULATE) {
it.remove();
}
}
} finally {
ongoingInjectOperation = false;
}
final double overflow = Math.max(0.0, amt);
@@ -442,8 +478,8 @@ public class EnergyGridCache implements IEnergyGrid {
this.globalAvailablePower -= ps.getAECurrentPower();
}
this.providers.remove(ps);
this.requesters.remove(ps);
removeProvider(ps);
removeRequester(ps);
}
}
@@ -457,6 +493,30 @@ public class EnergyGridCache implements IEnergyGrid {
}
}
private void addRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester);
}
private void removeRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester);
}
private void addProvider(IAEPowerStorage provider) {
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
this.providers.add(provider);
}
private void removeProvider(IAEPowerStorage provider) {
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
this.providers.remove(provider);
}
@Override
public void addNode(final IGridNode node, final IGridHost machine) {
if (machine instanceof IEnergyGridProvider) {
@@ -482,11 +542,11 @@ public class EnergyGridCache implements IEnergyGrid {
if (current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE) {
this.globalAvailablePower += current;
this.providers.add(ps);
addProvider(ps);
}
if (current < max && ps.getPowerFlow() != AccessRestriction.READ) {
this.requesters.add(ps);
addRequester(ps);
}
}
}
@@ -572,6 +632,12 @@ public class EnergyGridCache implements IEnergyGrid {
return this.stored;
}
@Override
public int getPriority() {
// MIN_VALUE to push it to the back
return Integer.MIN_VALUE;
}
private void addCurrentAEPower(double amount) {
this.stored += amount;
+32 -20
View File
@@ -82,21 +82,21 @@ public class SpatialPylonCache implements ISpatialCache {
int pylonBlocks = 0;
for (final SpatialPylonCluster cl : this.clusters.values()) {
if (this.captureMax == null) {
this.captureMax = cl.getMax().copy();
this.captureMax = new DimensionalCoord(cl.getWorld(), cl.getBoundsMax());
}
if (this.captureMin == null) {
this.captureMin = cl.getMin().copy();
this.captureMin = new DimensionalCoord(cl.getWorld(), cl.getBoundsMin());
}
pylonBlocks += cl.tileCount();
this.captureMin.x = Math.min(this.captureMin.x, cl.getMin().x);
this.captureMin.y = Math.min(this.captureMin.y, cl.getMin().y);
this.captureMin.z = Math.min(this.captureMin.z, cl.getMin().z);
this.captureMin.x = Math.min(this.captureMin.x, cl.getBoundsMin().getX());
this.captureMin.y = Math.min(this.captureMin.y, cl.getBoundsMin().getY());
this.captureMin.z = Math.min(this.captureMin.z, cl.getBoundsMin().getZ());
this.captureMax.x = Math.max(this.captureMax.x, cl.getMax().x);
this.captureMax.y = Math.max(this.captureMax.y, cl.getMax().y);
this.captureMax.z = Math.max(this.captureMax.z, cl.getMax().z);
this.captureMax.x = Math.max(this.captureMax.x, cl.getBoundsMax().getX());
this.captureMax.y = Math.max(this.captureMax.y, cl.getBoundsMax().getY());
this.captureMax.z = Math.max(this.captureMax.z, cl.getBoundsMax().getZ());
}
double maxPower = 0;
@@ -110,28 +110,40 @@ public class SpatialPylonCache implements ISpatialCache {
case X:
this.isValid = this.isValid
&& ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl.getMax().y)
|| (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z))
&& ((this.captureMax.y == cl.getMax().y || this.captureMin.y == cl.getMin().y)
|| (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
&& ((this.captureMax.y == cl.getBoundsMin().getY()
|| this.captureMin.y == cl.getBoundsMax().getY())
|| (this.captureMax.z == cl.getBoundsMin().getZ()
|| this.captureMin.z == cl.getBoundsMax().getZ()))
&& ((this.captureMax.y == cl.getBoundsMax().getY()
|| this.captureMin.y == cl.getBoundsMin().getY())
|| (this.captureMax.z == cl.getBoundsMax().getZ()
|| this.captureMin.z == cl.getBoundsMin().getZ()));
break;
case Y:
this.isValid = this.isValid
&& ((this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x)
|| (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z))
&& ((this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x)
|| (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
&& ((this.captureMax.x == cl.getBoundsMin().getX()
|| this.captureMin.x == cl.getBoundsMax().getX())
|| (this.captureMax.z == cl.getBoundsMin().getZ()
|| this.captureMin.z == cl.getBoundsMax().getZ()))
&& ((this.captureMax.x == cl.getBoundsMax().getX()
|| this.captureMin.x == cl.getBoundsMin().getX())
|| (this.captureMax.z == cl.getBoundsMax().getZ()
|| this.captureMin.z == cl.getBoundsMin().getZ()));
break;
case Z:
this.isValid = this.isValid
&& ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl.getMax().y)
|| (this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x))
&& ((this.captureMax.y == cl.getMax().y || this.captureMin.y == cl.getMin().y)
|| (this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x));
&& ((this.captureMax.y == cl.getBoundsMin().getY()
|| this.captureMin.y == cl.getBoundsMax().getY())
|| (this.captureMax.x == cl.getBoundsMin().getX()
|| this.captureMin.x == cl.getBoundsMax().getX()))
&& ((this.captureMax.y == cl.getBoundsMax().getY()
|| this.captureMin.y == cl.getBoundsMin().getY())
|| (this.captureMax.x == cl.getBoundsMax().getX()
|| this.captureMin.x == cl.getBoundsMin().getX()));
break;
case UNFORMED:
@@ -20,13 +20,32 @@ package appeng.me.cluster;
import java.util.Iterator;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import appeng.api.networking.IGridHost;
public interface IAECluster {
/**
* The minimum x,y,z position still within the bounds of the cluster.
*/
BlockPos getBoundsMin();
/**
* The maximum x,y,z position still within the bounds of the cluster.
*/
BlockPos getBoundsMax();
void updateStatus(boolean updateGrid);
void destroy();
Iterator<IGridHost> getTiles();
/**
* @return True if the cluster has been destroyed, but not yet removed from a
* tile entity. Usually true during destruction.
*/
boolean isDestroyed();
Iterator<? extends IGridHost> getTiles();
}
@@ -18,11 +18,11 @@
package appeng.me.cluster;
public interface IAEMultiBlock {
public interface IAEMultiBlock<Cluster extends IAECluster> {
void disconnect(boolean b);
IAECluster getCluster();
Cluster getCluster();
boolean isValid();
}
+106 -42
View File
@@ -18,56 +18,108 @@
package appeng.me.cluster;
import java.lang.ref.WeakReference;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.util.AEPartLocation;
import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.util.Platform;
public abstract class MBCalculator {
public abstract class MBCalculator<TTile extends IAEMultiBlock<TCluster>, TCluster extends IAECluster> {
private final IAEMultiBlock target;
/**
* To avoid recursive cluster rebuilds, we use a global field to prevent this
* from happening. This is set to the cluster that is currently causing a
* Multiblock modification.
*/
private static WeakReference<IAECluster> modificationInProgress = new WeakReference<>(null);
public MBCalculator(final IAEMultiBlock t) {
protected final TTile target;
public MBCalculator(final TTile t) {
this.target = t;
}
public void calculateMultiblock(final World world, final WorldCoord loc) {
if (Platform.isClient()) {
public static void setModificationInProgress(IAECluster cluster) {
IAECluster inProgress = modificationInProgress.get();
if (inProgress == cluster) {
return;
}
if (inProgress != null && cluster != null) {
throw new IllegalStateException("A modification is already in-progress for: " + inProgress);
}
modificationInProgress = new WeakReference<>(cluster);
}
public static boolean isModificationInProgress() {
return modificationInProgress.get() != null;
}
public void updateMultiblockAfterNeighborUpdate(final World world, final BlockPos loc, BlockPos changedPos) {
boolean recheck;
TCluster cluster = target.getCluster();
if (cluster != null) {
if (isWithinBounds(changedPos, cluster.getBoundsMin(), cluster.getBoundsMax())) {
// If the location is part of the current multiblock, always re-check
recheck = true;
} else {
// If the location is outside, only re-check if it would now be considered part
// of it
recheck = isValidTileAt(world, changedPos.getX(), changedPos.getY(), changedPos.getZ());
}
} else {
// Always recheck if the tile is not part of a cluster, because the adjacent
// block could have previously been a valid tile, but in a wrong placement,
// or the other way around.
recheck = true;
}
if (recheck) {
calculateMultiblock(world, loc);
}
}
public void calculateMultiblock(final World world, final BlockPos loc) {
if (Platform.isClient() || isModificationInProgress()) {
return;
}
IAECluster currentCluster = target.getCluster();
if (currentCluster != null && currentCluster.isDestroyed()) {
return; // If we're still part of a cluster that is in the process of being destroyed,
// don't recalc.
}
try {
final WorldCoord min = loc.copy();
final WorldCoord max = loc.copy();
final BlockPos.Mutable min = new BlockPos.Mutable(loc);
final BlockPos.Mutable max = new BlockPos.Mutable(loc);
// find size of MB structure...
while (this.isValidTileAt(world, min.x - 1, min.y, min.z)) {
min.x--;
while (this.isValidTileAt(world, min.getX() - 1, min.getY(), min.getZ())) {
min.setX(min.getX() - 1);
}
while (this.isValidTileAt(world, min.x, min.y - 1, min.z)) {
min.y--;
while (this.isValidTileAt(world, min.getX(), min.getY() - 1, min.getZ())) {
min.setY(min.getY() - 1);
}
while (this.isValidTileAt(world, min.x, min.y, min.z - 1)) {
min.z--;
while (this.isValidTileAt(world, min.getX(), min.getY(), min.getZ() - 1)) {
min.setZ(min.getZ() - 1);
}
while (this.isValidTileAt(world, max.x + 1, max.y, max.z)) {
max.x++;
while (this.isValidTileAt(world, max.getX() + 1, max.getY(), max.getZ())) {
max.setX(max.getX() + 1);
}
while (this.isValidTileAt(world, max.x, max.y + 1, max.z)) {
max.y++;
while (this.isValidTileAt(world, max.getX(), max.getY() + 1, max.getZ())) {
max.setY(max.getY() + 1);
}
while (this.isValidTileAt(world, max.x, max.y, max.z + 1)) {
max.z++;
while (this.isValidTileAt(world, max.getX(), max.getY(), max.getZ() + 1)) {
max.setZ(max.getZ() + 1);
}
if (this.checkMultiblockScale(min, max)) {
if (this.verifyUnownedRegion(world, min, max)) {
IAECluster c = this.createCluster(world, min, max);
try {
if (!this.verifyInternalStructure(world, min, max)) {
this.disconnect();
@@ -79,26 +131,39 @@ public abstract class MBCalculator {
}
boolean updateGrid = false;
final IAECluster cluster = this.target.getCluster();
if (cluster == null) {
this.updateTiles(c, world, min, max);
TCluster cluster = this.target.getCluster();
if (cluster == null || !cluster.getBoundsMin().equals(min) || !cluster.getBoundsMax().equals(max)) {
cluster = this.createCluster(world, min, max);
setModificationInProgress(cluster);
// NOTE: The following will break existing clusters within the bounds
this.updateTiles(cluster, world, min, max);
updateGrid = true;
} else {
c = cluster;
setModificationInProgress(cluster);
}
c.updateStatus(updateGrid);
cluster.updateStatus(updateGrid);
return;
}
}
} catch (final Throwable err) {
AELog.debug(err);
} finally {
setModificationInProgress(null);
}
this.disconnect();
}
private static boolean isWithinBounds(BlockPos pos, BlockPos boundsMin, BlockPos boundsMax) {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
return (x >= boundsMin.getX() && y >= boundsMin.getY() && z >= boundsMin.getZ() && x <= boundsMax.getX()
&& y <= boundsMax.getY() && z <= boundsMax.getZ());
}
private boolean isValidTileAt(final World w, final int x, final int y, final int z) {
return this.isValidTile(w.getTileEntity(new BlockPos(x, y, z)));
}
@@ -111,11 +176,12 @@ public abstract class MBCalculator {
*
* @return true if structure has correct dimensions or size
*/
public abstract boolean checkMultiblockScale(WorldCoord min, WorldCoord max);
public abstract boolean checkMultiblockScale(BlockPos min, BlockPos max);
private boolean verifyUnownedRegion(final World w, final WorldCoord min, final WorldCoord max) {
private boolean verifyUnownedRegion(final World w, final BlockPos min, final BlockPos max) {
for (final AEPartLocation side : AEPartLocation.SIDE_LOCATIONS) {
if (this.verifyUnownedRegionInner(w, min.x, min.y, min.z, max.x, max.y, max.z, side)) {
if (this.verifyUnownedRegionInner(w, min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ(),
side)) {
return false;
}
}
@@ -132,14 +198,16 @@ public abstract class MBCalculator {
*
* @return created cluster
*/
public abstract IAECluster createCluster(World w, WorldCoord min, WorldCoord max);
public abstract TCluster createCluster(World w, BlockPos min, BlockPos max);
public abstract boolean verifyInternalStructure(World world, WorldCoord min, WorldCoord max);
public abstract boolean verifyInternalStructure(World world, BlockPos min, BlockPos max);
/**
* disassembles the multi-block.
*/
public abstract void disconnect();
public void disconnect() {
this.target.disconnect(true);
}
/**
* configure the multi-block tiles, most of the important stuff is in here.
@@ -149,7 +217,7 @@ public abstract class MBCalculator {
* @param min min world coord
* @param max max world coord
*/
public abstract void updateTiles(IAECluster c, World w, WorldCoord min, WorldCoord max);
public abstract void updateTiles(TCluster c, World w, BlockPos min, BlockPos max);
/**
* check if the tile entities are correct for the structure.
@@ -191,14 +259,10 @@ public abstract class MBCalculator {
return false;
}
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
final TileEntity te = w.getTileEntity(new BlockPos(x, y, z));
if (this.isValidTile(te)) {
return true;
}
}
for (BlockPos p : BlockPos.getAllInBoxMutable(minX, minY, minZ, maxX, maxY, maxZ)) {
final TileEntity te = w.getTileEntity(p);
if (this.isValidTile(te)) {
return true;
}
}
@@ -29,32 +29,27 @@ import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkCraftingCpuChange;
import appeng.api.util.AEPartLocation;
import appeng.api.util.WorldCoord;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.crafting.CraftingTileEntity;
public class CraftingCPUCalculator extends MBCalculator {
public class CraftingCPUCalculator extends MBCalculator<CraftingTileEntity, CraftingCPUCluster> {
private final CraftingTileEntity tqb;
public CraftingCPUCalculator(final IAEMultiBlock t) {
public CraftingCPUCalculator(final CraftingTileEntity t) {
super(t);
this.tqb = (CraftingTileEntity) t;
}
@Override
public boolean checkMultiblockScale(final WorldCoord min, final WorldCoord max) {
if (max.x - min.x > 16) {
public boolean checkMultiblockScale(final BlockPos min, final BlockPos max) {
if (max.getX() - min.getX() > 16) {
return false;
}
if (max.y - min.y > 16) {
if (max.getY() - min.getY() > 16) {
return false;
}
if (max.z - min.z > 16) {
if (max.getZ() - min.getZ() > 16) {
return false;
}
@@ -62,27 +57,23 @@ public class CraftingCPUCalculator extends MBCalculator {
}
@Override
public IAECluster createCluster(final World w, final WorldCoord min, final WorldCoord max) {
public CraftingCPUCluster createCluster(final World w, final BlockPos min, final BlockPos max) {
return new CraftingCPUCluster(min, max);
}
@Override
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
public boolean verifyInternalStructure(final World w, final BlockPos min, final BlockPos max) {
boolean storage = false;
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(new BlockPos(x, y, z));
for (BlockPos blockPos : BlockPos.getAllInBoxMutable(min, max)) {
final IAEMultiBlock<?> te = (IAEMultiBlock<?>) w.getTileEntity(blockPos);
if (!te.isValid()) {
return false;
}
if (te == null || !te.isValid()) {
return false;
}
if (!storage && te instanceof CraftingTileEntity) {
storage = ((CraftingTileEntity) te).getStorageBytes() > 0;
}
}
if (!storage && te instanceof CraftingTileEntity) {
storage = ((CraftingTileEntity) te).getStorageBytes() > 0;
}
}
@@ -90,27 +81,16 @@ public class CraftingCPUCalculator extends MBCalculator {
}
@Override
public void disconnect() {
this.tqb.disconnect(true);
}
@Override
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
final CraftingCPUCluster c = (CraftingCPUCluster) cl;
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final CraftingTileEntity te = (CraftingTileEntity) w.getTileEntity(new BlockPos(x, y, z));
te.updateStatus(c);
c.addTile(te);
}
}
public void updateTiles(final CraftingCPUCluster c, final World w, final BlockPos min, final BlockPos max) {
for (BlockPos blockPos : BlockPos.getAllInBoxMutable(min, max)) {
final CraftingTileEntity te = (CraftingTileEntity) w.getTileEntity(blockPos);
te.updateStatus(c);
c.addTile(te);
}
c.done();
final Iterator<IGridHost> i = c.getTiles();
final Iterator<CraftingTileEntity> i = c.getTiles();
while (i.hasNext()) {
final IGridHost gh = i.next();
final IGridNode n = gh.getGridNode(AEPartLocation.INTERNAL);
@@ -18,12 +18,7 @@
package appeng.me.cluster.implementations;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
@@ -32,6 +27,7 @@ import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
@@ -44,14 +40,7 @@ import appeng.api.crafting.ICraftingHelper;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.CraftingItemList;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingMedium;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.crafting.*;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCraftingCpuChange;
import appeng.api.networking.security.IActionSource;
@@ -61,17 +50,13 @@ import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.WorldCoord;
import appeng.container.ContainerNull;
import appeng.core.AELog;
import appeng.core.Api;
import appeng.crafting.CraftBranchFailure;
import appeng.crafting.CraftingJob;
import appeng.crafting.CraftingLink;
import appeng.crafting.CraftingWatcher;
import appeng.crafting.MECraftingInventory;
import appeng.crafting.*;
import appeng.me.cache.CraftingGridCache;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.MBCalculator;
import appeng.me.helpers.MachineSource;
import appeng.tile.crafting.CraftingMonitorTileEntity;
import appeng.tile.crafting.CraftingTileEntity;
@@ -82,8 +67,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
private static final String LOG_MARK_AS_COMPLETE = "Completed job for %s.";
private final WorldCoord min;
private final WorldCoord max;
private final BlockPos boundsMin;
private final BlockPos boundsMax;
private final int[] usedOps = new int[3];
private final Map<ICraftingPatternDetails, TaskProgress> tasks = new HashMap<>();
// INSTANCE sate
@@ -114,11 +99,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
private long startItemCount;
private long remainingItemCount;
public CraftingCPUCluster(final WorldCoord min, final WorldCoord max) {
this.min = min;
this.max = max;
public CraftingCPUCluster(final BlockPos boundsMin, final BlockPos boundsMax) {
this.boundsMin = boundsMin.toImmutable();
this.boundsMax = boundsMax.toImmutable();
}
@Override
public boolean isDestroyed() {
return this.isDestroyed;
}
@@ -127,6 +113,16 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
return this.myLastLink;
}
@Override
public BlockPos getBoundsMin() {
return boundsMin;
}
@Override
public BlockPos getBoundsMax() {
return boundsMax;
}
/**
* add a new Listener to the monitor, be sure to properly remove yourself when
* your done.
@@ -162,25 +158,35 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
}
this.isDestroyed = true;
boolean posted = false;
boolean ownsModification = !MBCalculator.isModificationInProgress();
if (ownsModification) {
MBCalculator.setModificationInProgress(this);
}
try {
boolean posted = false;
for (final CraftingTileEntity r : this.tiles) {
final IGridNode n = r.getActionableNode();
if (n != null && !posted) {
final IGrid g = n.getGrid();
if (g != null) {
g.postEvent(new MENetworkCraftingCpuChange(n));
posted = true;
for (final CraftingTileEntity r : this.tiles) {
final IGridNode n = r.getActionableNode();
if (n != null && !posted) {
final IGrid g = n.getGrid();
if (g != null) {
g.postEvent(new MENetworkCraftingCpuChange(n));
posted = true;
}
}
}
r.updateStatus(null);
r.updateStatus(null);
}
} finally {
if (ownsModification) {
MBCalculator.setModificationInProgress(null);
}
}
}
@Override
public Iterator<IGridHost> getTiles() {
return (Iterator) this.tiles.iterator();
public Iterator<CraftingTileEntity> getTiles() {
return this.tiles.iterator();
}
void addTile(final CraftingTileEntity te) {
@@ -25,31 +25,25 @@ import net.minecraft.world.World;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.definitions.IBlocks;
import appeng.api.util.WorldCoord;
import appeng.core.Api;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.qnb.QuantumBridgeTileEntity;
public class QuantumCalculator extends MBCalculator {
public class QuantumCalculator extends MBCalculator<QuantumBridgeTileEntity, QuantumCluster> {
private final QuantumBridgeTileEntity tqb;
public QuantumCalculator(final IAEMultiBlock t) {
public QuantumCalculator(final QuantumBridgeTileEntity t) {
super(t);
this.tqb = (QuantumBridgeTileEntity) t;
}
@Override
public boolean checkMultiblockScale(final WorldCoord min, final WorldCoord max) {
public boolean checkMultiblockScale(final BlockPos min, final BlockPos max) {
if ((max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) == 9) {
final int ones = ((max.getX() - min.getX()) == 0 ? 1 : 0) + ((max.getY() - min.getY()) == 0 ? 1 : 0)
+ ((max.getZ() - min.getZ()) == 0 ? 1 : 0);
if ((max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1) == 9) {
final int ones = ((max.x - min.x) == 0 ? 1 : 0) + ((max.y - min.y) == 0 ? 1 : 0)
+ ((max.z - min.z) == 0 ? 1 : 0);
final int threes = ((max.x - min.x) == 2 ? 1 : 0) + ((max.y - min.y) == 2 ? 1 : 0)
+ ((max.z - min.z) == 2 ? 1 : 0);
final int threes = ((max.getX() - min.getX()) == 2 ? 1 : 0) + ((max.getY() - min.getY()) == 2 ? 1 : 0)
+ ((max.getZ() - min.getZ()) == 2 ? 1 : 0);
return ones == 1 && threes == 2;
}
@@ -57,36 +51,31 @@ public class QuantumCalculator extends MBCalculator {
}
@Override
public IAECluster createCluster(final World w, final WorldCoord min, final WorldCoord max) {
public QuantumCluster createCluster(final World w, final BlockPos min, final BlockPos max) {
return new QuantumCluster(min, max);
}
@Override
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
public boolean verifyInternalStructure(final World w, final BlockPos min, final BlockPos max) {
byte num = 0;
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final BlockPos p = new BlockPos(x, y, z);
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(p);
for (BlockPos p : BlockPos.getAllInBoxMutable(min, max)) {
final IAEMultiBlock<?> te = (IAEMultiBlock<?>) w.getTileEntity(p);
if (!te.isValid()) {
return false;
}
if (te == null || !te.isValid()) {
return false;
}
num++;
final IBlocks blocks = Api.instance().definitions().blocks();
if (num == 5) {
if (!this.isBlockAtLocation(w, p, blocks.quantumLink())) {
return false;
}
} else {
if (!this.isBlockAtLocation(w, p, blocks.quantumRing())) {
return false;
}
}
num++;
final IBlocks blocks = Api.instance().definitions().blocks();
if (num == 5) {
if (!this.isBlockAtLocation(w, p, blocks.quantumLink())) {
return false;
}
} else {
if (!this.isBlockAtLocation(w, p, blocks.quantumRing())) {
return false;
}
}
}
@@ -94,39 +83,29 @@ public class QuantumCalculator extends MBCalculator {
}
@Override
public void disconnect() {
this.tqb.disconnect(true);
}
@Override
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
public void updateTiles(final QuantumCluster c, final World w, final BlockPos min, final BlockPos max) {
byte num = 0;
byte ringNum = 0;
final QuantumCluster c = (QuantumCluster) cl;
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final QuantumBridgeTileEntity te = (QuantumBridgeTileEntity) w.getTileEntity(new BlockPos(x, y, z));
for (BlockPos p : BlockPos.getAllInBoxMutable(min, max)) {
final QuantumBridgeTileEntity te = (QuantumBridgeTileEntity) w.getTileEntity(p);
num++;
final byte flags;
if (num == 5) {
flags = num;
c.setCenter(te);
} else {
if (num == 1 || num == 3 || num == 7 || num == 9) {
flags = (byte) (this.tqb.getCorner() | num);
} else {
flags = num;
}
c.getRing()[ringNum] = te;
ringNum++;
}
te.updateStatus(c, flags, true);
num++;
final byte flags;
if (num == 5) {
flags = num;
c.setCenter(te);
} else {
if (num == 1 || num == 3 || num == 7 || num == 9) {
flags = (byte) (this.target.getCorner() | num);
} else {
flags = num;
}
c.getRing()[ringNum] = te;
ringNum++;
}
te.updateStatus(c, flags, true);
}
}
@@ -21,6 +21,7 @@ package appeng.me.cluster.implementations;
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.minecraft.world.dimension.DimensionType;
@@ -32,21 +33,20 @@ import appeng.api.events.LocatableEventAnnounce;
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
import appeng.api.exceptions.FailedConnectionException;
import appeng.api.features.ILocatable;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.util.AEPartLocation;
import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.core.Api;
import appeng.me.cache.helpers.ConnectionWrapper;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.MBCalculator;
import appeng.tile.qnb.QuantumBridgeTileEntity;
import appeng.util.iterators.ChainedIterator;
public class QuantumCluster implements ILocatable, IAECluster {
private final WorldCoord min;
private final WorldCoord max;
private final BlockPos boundsMin;
private final BlockPos boundsMax;
private boolean isDestroyed = false;
private boolean updateStatus = true;
private QuantumBridgeTileEntity[] Ring;
@@ -56,9 +56,9 @@ public class QuantumCluster implements ILocatable, IAECluster {
private long otherSide;
private QuantumBridgeTileEntity center;
public QuantumCluster(final WorldCoord min, final WorldCoord max) {
this.min = min;
this.max = max;
public QuantumCluster(final BlockPos min, final BlockPos max) {
this.boundsMin = min.toImmutable();
this.boundsMax = max.toImmutable();
this.setRing(new QuantumBridgeTileEntity[8]);
}
@@ -189,6 +189,21 @@ public class QuantumCluster implements ILocatable, IAECluster {
return this.thisSide != 0;
}
@Override
public BlockPos getBoundsMin() {
return boundsMin;
}
@Override
public BlockPos getBoundsMax() {
return boundsMax;
}
@Override
public boolean isDestroyed() {
return isDestroyed;
}
@Override
public void destroy() {
if (this.isDestroyed) {
@@ -196,28 +211,33 @@ public class QuantumCluster implements ILocatable, IAECluster {
}
this.isDestroyed = true;
if (this.registered) {
MinecraftForge.EVENT_BUS.unregister(this);
this.registered = false;
MBCalculator.setModificationInProgress(this);
try {
if (this.registered) {
MinecraftForge.EVENT_BUS.unregister(this);
this.registered = false;
}
if (this.thisSide != 0) {
this.updateStatus(true);
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
}
this.center.updateStatus(null, (byte) -1, this.isUpdateStatus());
for (final QuantumBridgeTileEntity r : this.getRing()) {
r.updateStatus(null, (byte) -1, this.isUpdateStatus());
}
this.center = null;
this.setRing(new QuantumBridgeTileEntity[8]);
} finally {
MBCalculator.setModificationInProgress(null);
}
if (this.thisSide != 0) {
this.updateStatus(true);
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
}
this.center.updateStatus(null, (byte) -1, this.isUpdateStatus());
for (final QuantumBridgeTileEntity r : this.getRing()) {
r.updateStatus(null, (byte) -1, this.isUpdateStatus());
}
this.center = null;
this.setRing(new QuantumBridgeTileEntity[8]);
}
@Override
public Iterator<IGridHost> getTiles() {
public Iterator<QuantumBridgeTileEntity> getTiles() {
return new ChainedIterator<>(this.getRing()[0], this.getRing()[1], this.getRing()[2], this.getRing()[3],
this.getRing()[4], this.getRing()[5], this.getRing()[6], this.getRing()[7], this.center);
}
@@ -22,47 +22,36 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.WorldCoord;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.spatial.SpatialPylonTileEntity;
public class SpatialPylonCalculator extends MBCalculator {
public class SpatialPylonCalculator extends MBCalculator<SpatialPylonTileEntity, SpatialPylonCluster> {
private final SpatialPylonTileEntity tqb;
public SpatialPylonCalculator(final IAEMultiBlock t) {
public SpatialPylonCalculator(final SpatialPylonTileEntity t) {
super(t);
this.tqb = (SpatialPylonTileEntity) t;
}
@Override
public boolean checkMultiblockScale(final WorldCoord min, final WorldCoord max) {
return (min.x == max.x && min.y == max.y && min.z != max.z)
|| (min.x == max.x && min.y != max.y && min.z == max.z)
|| (min.x != max.x && min.y == max.y && min.z == max.z);
public boolean checkMultiblockScale(final BlockPos min, final BlockPos max) {
return (min.getX() == max.getX() && min.getY() == max.getY() && min.getZ() != max.getZ())
|| (min.getX() == max.getX() && min.getY() != max.getY() && min.getZ() == max.getZ())
|| (min.getX() != max.getX() && min.getY() == max.getY() && min.getZ() == max.getZ());
}
@Override
public IAECluster createCluster(final World w, final WorldCoord min, final WorldCoord max) {
return new SpatialPylonCluster(new DimensionalCoord(w, min.x, min.y, min.z),
new DimensionalCoord(w, max.x, max.y, max.z));
public SpatialPylonCluster createCluster(final World w, final BlockPos min, final BlockPos max) {
return new SpatialPylonCluster(w, min, max);
}
@Override
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
public boolean verifyInternalStructure(final World w, final BlockPos min, final BlockPos max) {
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(new BlockPos(x, y, z));
for (BlockPos p : BlockPos.getAllInBoxMutable(min, max)) {
final IAEMultiBlock<?> te = (IAEMultiBlock<?>) w.getTileEntity(p);
if (!te.isValid()) {
return false;
}
}
if (te == null || !te.isValid()) {
return false;
}
}
@@ -70,22 +59,11 @@ public class SpatialPylonCalculator extends MBCalculator {
}
@Override
public void disconnect() {
this.tqb.disconnect(true);
}
@Override
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
final SpatialPylonCluster c = (SpatialPylonCluster) cl;
for (int x = min.x; x <= max.x; x++) {
for (int y = min.y; y <= max.y; y++) {
for (int z = min.z; z <= max.z; z++) {
final SpatialPylonTileEntity te = (SpatialPylonTileEntity) w.getTileEntity(new BlockPos(x, y, z));
te.updateStatus(c);
c.getLine().add((te));
}
}
public void updateTiles(final SpatialPylonCluster c, final World w, final BlockPos min, final BlockPos max) {
for (BlockPos p : BlockPos.getAllInBoxMutable(min, max)) {
final SpatialPylonTileEntity te = (SpatialPylonTileEntity) w.getTileEntity(p);
te.updateStatus(c);
c.getLine().add(te);
}
}
@@ -22,30 +22,34 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import appeng.api.networking.IGridHost;
import appeng.api.util.DimensionalCoord;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.MBCalculator;
import appeng.tile.spatial.SpatialPylonTileEntity;
public class SpatialPylonCluster implements IAECluster {
private final DimensionalCoord min;
private final DimensionalCoord max;
private final World world;
private final BlockPos boundsMin;
private final BlockPos boundsMax;
private final List<SpatialPylonTileEntity> line = new ArrayList<>();
private boolean isDestroyed = false;
private Axis currentAxis = Axis.UNFORMED;
private boolean isValid;
public SpatialPylonCluster(final DimensionalCoord min, final DimensionalCoord max) {
this.min = min.copy();
this.max = max.copy();
public SpatialPylonCluster(final World world, final BlockPos boundsMin, final BlockPos boundsMax) {
this.world = world;
this.boundsMin = boundsMin.toImmutable();
this.boundsMax = boundsMax.toImmutable();
if (this.getMin().x != this.getMax().x) {
if (this.getBoundsMin().getX() != this.getBoundsMax().getX()) {
this.setCurrentAxis(Axis.X);
} else if (this.getMin().y != this.getMax().y) {
} else if (this.getBoundsMin().getY() != this.getBoundsMax().getY()) {
this.setCurrentAxis(Axis.Y);
} else if (this.getMin().z != this.getMax().z) {
} else if (this.getBoundsMin().getZ() != this.getBoundsMax().getZ()) {
this.setCurrentAxis(Axis.Z);
} else {
this.setCurrentAxis(Axis.UNFORMED);
@@ -59,6 +63,11 @@ public class SpatialPylonCluster implements IAECluster {
}
}
@Override
public boolean isDestroyed() {
return isDestroyed;
}
@Override
public void destroy() {
@@ -67,14 +76,19 @@ public class SpatialPylonCluster implements IAECluster {
}
this.isDestroyed = true;
for (final SpatialPylonTileEntity r : this.getLine()) {
r.updateStatus(null);
MBCalculator.setModificationInProgress(this);
try {
for (final SpatialPylonTileEntity r : this.getLine()) {
r.updateStatus(null);
}
} finally {
MBCalculator.setModificationInProgress(null);
}
}
@Override
public Iterator<IGridHost> getTiles() {
return (Iterator) this.getLine().iterator();
public Iterator<SpatialPylonTileEntity> getTiles() {
return this.getLine().iterator();
}
public int tileCount() {
@@ -97,12 +111,18 @@ public class SpatialPylonCluster implements IAECluster {
this.isValid = isValid;
}
public DimensionalCoord getMax() {
return this.max;
public World getWorld() {
return world;
}
public DimensionalCoord getMin() {
return this.min;
@Override
public BlockPos getBoundsMax() {
return this.boundsMax;
}
@Override
public BlockPos getBoundsMin() {
return this.boundsMin;
}
List<SpatialPylonTileEntity> getLine() {
@@ -96,7 +96,7 @@ public class AENetworkProxy implements IGridBlock {
public void validate() {
if (this.gp instanceof AEBaseTileEntity) {
TickHandler.INSTANCE.addInit((AEBaseTileEntity) this.gp);
TickHandler.instance().addInit((AEBaseTileEntity) this.gp);
}
}
@@ -41,11 +41,10 @@ public class AENetworkProxyMultiblock extends AENetworkProxy implements IGridMul
if (this.getCluster() == null) {
return new ChainedIterator<>();
}
return new ProxyNodeIterator(this.getCluster().getTiles());
}
private IAECluster getCluster() {
return ((IAEMultiBlock) this.getMachine()).getCluster();
return ((IAEMultiBlock<?>) this.getMachine()).getCluster();
}
}
@@ -408,7 +408,7 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
performBreakBlock(w, pos, blockState, energy, requiredPower, items);
} else {
this.breaking = true;
TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this);
TickHandler.instance().addCallable(this.getTile().getWorld(), this);
}
return TickRateModulation.URGENT;
}
@@ -158,7 +158,7 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
return 0;
}
if (action == FluidAction.EXECUTE) {
if (action != FluidAction.EXECUTE) {
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
@@ -138,14 +138,14 @@ public class MEP2PTunnelPart extends P2PTunnelPart<MEP2PTunnelPart> implements I
if (!this.getProxy().getPath().isNetworkBooting()) {
if (!this.getProxy().getEnergy().isNetworkPowered()) {
this.connection.markDestroy();
TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection);
TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection);
} else {
if (this.getProxy().isActive()) {
this.connection.markCreate();
TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection);
TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection);
} else {
this.connection.markDestroy();
TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection);
TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection);
}
}
@@ -434,7 +434,7 @@ public class AEBaseTileEntity extends TileEntity implements IOrientable, ICommon
if (this.world != null) {
this.world.markChunkDirty(this.pos, this);
if (!this.markDirtyQueued) {
TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick);
TickHandler.instance().addCallable(null, this::markDirtyAtEndOfTick);
this.markDirtyQueued = true;
}
}
@@ -29,30 +29,24 @@ import javax.annotation.Nonnull;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.util.Constants;
import appeng.api.config.Actionable;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridHost;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AEPartLocation;
import appeng.api.util.WorldCoord;
import appeng.block.crafting.AbstractCraftingUnitBlock;
import appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
import appeng.core.Api;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.CraftingCPUCalculator;
import appeng.me.cluster.implementations.CraftingCPUCluster;
@@ -61,7 +55,8 @@ import appeng.me.helpers.AENetworkProxyMultiblock;
import appeng.tile.grid.AENetworkTileEntity;
import appeng.util.Platform;
public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiBlock, IPowerChannelState {
public class CraftingTileEntity extends AENetworkTileEntity
implements IAEMultiBlock<CraftingCPUCluster>, IPowerChannelState {
private final CraftingCPUCalculator calc = new CraftingCPUCalculator(this);
private CompoundNBT previousState = null;
@@ -95,7 +90,7 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
@Override
public boolean canBeRotated() {
return true;// return BlockCraftingUnit.checkType( world.getBlockMetadata( xCoord, yCoord,
// zCoord ),
// zCoord ),
// BlockCraftingUnit.BASE_MONITOR );
}
@@ -112,7 +107,7 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
return false;
}
final AbstractCraftingUnitBlock unit = (AbstractCraftingUnitBlock) this.world.getBlockState(this.pos)
final AbstractCraftingUnitBlock<?> unit = (AbstractCraftingUnitBlock<?>) this.world.getBlockState(this.pos)
.getBlock();
return unit.type == CraftingUnitType.ACCELERATOR;
}
@@ -121,11 +116,11 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
public void onReady() {
super.onReady();
this.getProxy().setVisualRepresentation(this.getItemFromTile(this));
this.updateMultiBlock();
this.calc.calculateMultiblock(world, pos);
}
public void updateMultiBlock() {
this.calc.calculateMultiblock(this.world, this.getLocation());
public void updateMultiBlock(BlockPos changedPos) {
this.calc.updateMultiblockAfterNeighborUpdate(this.world, pos, changedPos);
}
public void updateStatus(final CraftingCPUCluster c) {
@@ -160,7 +155,7 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
// Not using flag 2 here (only send to clients, prevent block update) will cause
// infinite loops
// In case there is an inconsistency in the crafting clusters.
this.world.setBlockState(this.pos, newState, Constants.BlockFlags.BLOCK_UPDATE);
this.world.setBlockState(this.pos, newState, 2);
}
}
@@ -214,7 +209,7 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
}
@Override
public IAECluster getCluster() {
public CraftingCPUCluster getCluster() {
return this.cluster;
}
@@ -246,25 +241,27 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
}
public void breakCluster() {
// Since breaking the cluster will most likely also update the TE's state,
// it's essential that we're not working with outdated block-state information,
// since this particular TE's block might already have been removed (state=air)
updateContainingBlockInfo();
if (this.cluster != null) {
this.cluster.cancel();
final IMEInventory<IAEItemStack> inv = this.cluster.getInventory();
final LinkedList<WorldCoord> places = new LinkedList<>();
final LinkedList<BlockPos> places = new LinkedList<>();
final Iterator<IGridHost> i = this.cluster.getTiles();
final Iterator<CraftingTileEntity> i = this.cluster.getTiles();
while (i.hasNext()) {
final IGridHost h = i.next();
final CraftingTileEntity h = i.next();
if (h == this) {
places.add(new WorldCoord(this));
places.add(pos);
} else {
final TileEntity te = (TileEntity) h;
for (final AEPartLocation d : AEPartLocation.SIDE_LOCATIONS) {
final WorldCoord wc = new WorldCoord(te);
wc.add(d, 1);
if (this.world.isAirBlock(wc.getPos())) {
places.add(wc);
for (Direction d : Direction.values()) {
BlockPos p = h.pos.offset(d);
if (this.world.isAirBlock(p)) {
places.add(p);
}
}
}
@@ -288,10 +285,10 @@ public class CraftingTileEntity extends AENetworkTileEntity implements IAEMultiB
break;
}
final WorldCoord wc = places.poll();
places.add(wc);
final BlockPos pos = places.poll();
places.add(pos);
Platform.spawnDrops(this.world, wc.getPos(), Collections.singletonList(g.createItemStack()));
Platform.spawnDrops(this.world, pos, Collections.singletonList(g.createItemStack()));
}
}
@@ -124,7 +124,7 @@ public class CableBusTileEntity extends AEBaseTileEntity implements AEMultiTile
@Override
public void validate() {
super.validate();
TickHandler.INSTANCE.addInit(this);
TickHandler.instance().addInit(this);
}
@Override
@@ -69,4 +69,10 @@ public class CreativeEnergyCellTileEntity extends AENetworkTileEntity implements
public double extractAEPower(final double amt, final Actionable mode, final PowerMultiplier pm) {
return amt;
}
@Override
public int getPriority() {
// MAX_VALUE to move creative cells to the front.
return Integer.MAX_VALUE;
}
}
@@ -22,9 +22,16 @@ import net.minecraft.tileentity.TileEntityType;
public class DenseEnergyCellTileEntity extends EnergyCellTileEntity {
private final static double MAX_STORED = 200000 * 8;
public DenseEnergyCellTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
this.setInternalMaxPower(200000 * 8);
this.setInternalMaxPower(MAX_STORED);
}
@Override
public int getPriority() {
return 1600;
}
}
@@ -36,8 +36,10 @@ import appeng.util.SettingsFrom;
public class EnergyCellTileEntity extends AENetworkTileEntity implements IAEPowerStorage {
private static final double MAX_STORED = 200000.0;
private double internalCurrentPower = 0.0;
private double internalMaxPower = 200000.0;
private double internalMaxPower = MAX_STORED;
private byte currentMeta = -1;
@@ -179,6 +181,11 @@ public class EnergyCellTileEntity extends AENetworkTileEntity implements IAEPowe
return pm.divide(this.extractAEPower(pm.multiply(amt), mode));
}
@Override
public int getPriority() {
return 200;
}
private double extractAEPower(double amt, final Actionable mode) {
if (mode == Actionable.SIMULATE) {
if (this.internalCurrentPower > amt) {
@@ -218,4 +225,5 @@ public class EnergyCellTileEntity extends AENetworkTileEntity implements IAEPowe
void setInternalMaxPower(final double internalMaxPower) {
this.internalMaxPower = internalMaxPower;
}
}
@@ -32,6 +32,7 @@ import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
@@ -48,7 +49,6 @@ import appeng.api.util.DimensionalCoord;
import appeng.block.qnb.QnbFormedState;
import appeng.core.Api;
import appeng.me.GridAccessException;
import appeng.me.cluster.IAECluster;
import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.implementations.QuantumCalculator;
import appeng.me.cluster.implementations.QuantumCluster;
@@ -56,7 +56,8 @@ import appeng.tile.grid.AENetworkInvTileEntity;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.inv.InvOperation;
public class QuantumBridgeTileEntity extends AENetworkInvTileEntity implements IAEMultiBlock, ITickableTileEntity {
public class QuantumBridgeTileEntity extends AENetworkInvTileEntity
implements IAEMultiBlock<QuantumCluster>, ITickableTileEntity {
public static final ModelProperty<QnbFormedState> FORMED_STATE = new ModelProperty<>();
@@ -190,7 +191,7 @@ public class QuantumBridgeTileEntity extends AENetworkInvTileEntity implements I
}
@Override
public IAECluster getCluster() {
public QuantumCluster getCluster() {
return this.cluster;
}
@@ -209,11 +210,7 @@ public class QuantumBridgeTileEntity extends AENetworkInvTileEntity implements I
}
if (this.isCorner() || this.isCenter()) {
final EnumSet<Direction> sides = EnumSet.noneOf(Direction.class);
for (final Direction dir : this.getAdjacentQuantumBridges()) {
sides.add(dir);
}
EnumSet<Direction> sides = EnumSet.copyOf(this.getAdjacentQuantumBridges());
this.getProxy().setValidSides(sides);
} else {
this.getProxy().setValidSides(EnumSet.allOf(Direction.class));
@@ -272,8 +269,8 @@ public class QuantumBridgeTileEntity extends AENetworkInvTileEntity implements I
return AECableType.DENSE_SMART;
}
public void neighborUpdate() {
this.calc.calculateMultiblock(this.world, this.getLocation());
public void neighborUpdate(BlockPos fromPos) {
this.calc.updateMultiblockAfterNeighborUpdate(this.world, this.pos, fromPos);
}
@Override
@@ -289,6 +286,11 @@ public class QuantumBridgeTileEntity extends AENetworkInvTileEntity implements I
}
public void breakCluster() {
// Since breaking the cluster will most likely also update the TE's state,
// it's essential that we're not working with outdated block-state information,
// since this particular TE's block might already have been removed (state=air)
updateContainingBlockInfo();
if (this.cluster != null) {
this.cluster.destroy();
}
@@ -99,7 +99,7 @@ public class SpatialIOPortTileEntity extends AENetworkInvTileEntity implements I
if (Platform.isServer()) {
final ItemStack cell = this.inv.getStackInSlot(0);
if (this.isSpatialCell(cell)) {
TickHandler.INSTANCE.addCallable(null, this);// this needs to be cross world synced.
TickHandler.instance().addCallable(null, this);// this needs to be cross world synced.
}
}
}
@@ -26,6 +26,7 @@ import javax.annotation.Nonnull;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
@@ -42,7 +43,7 @@ import appeng.me.helpers.AENetworkProxy;
import appeng.me.helpers.AENetworkProxyMultiblock;
import appeng.tile.grid.AENetworkTileEntity;
public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMultiBlock {
public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMultiBlock<SpatialPylonCluster> {
public static final ModelProperty<Integer> STATE = new ModelProperty<>(value -> {
// The lower 6 bits are used
@@ -87,7 +88,7 @@ public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMu
@Override
public void onReady() {
super.onReady();
this.neighborChanged();
this.calc.calculateMultiblock(world, pos);
}
@Override
@@ -96,8 +97,8 @@ public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMu
super.remove();
}
public void neighborChanged() {
this.calc.calculateMultiblock(this.world, this.getLocation());
public void neighborChanged(BlockPos changedPos) {
this.calc.updateMultiblockAfterNeighborUpdate(this.world, pos, changedPos);
}
@Override
@@ -130,9 +131,9 @@ public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMu
this.displayBits = 0;
if (this.cluster != null) {
if (this.cluster.getMin().equals(this.getLocation())) {
if (this.cluster.getBoundsMin().equals(this.pos)) {
this.displayBits = DISPLAY_END_MIN;
} else if (this.cluster.getMax().equals(this.getLocation())) {
} else if (this.cluster.getBoundsMax().equals(this.pos)) {
this.displayBits = DISPLAY_END_MAX;
} else {
this.displayBits = DISPLAY_MIDDLE;
@@ -29,6 +29,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.ITickableTileEntity;
@@ -42,44 +43,24 @@ import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.registries.ForgeRegistries;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.config.*;
import appeng.api.implementations.tiles.IColorableTile;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.MENetworkCellArrayUpdate;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.events.MENetworkPowerStorage;
import appeng.api.networking.events.*;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.cells.CellState;
import appeng.api.storage.cells.ICellGuiHandler;
import appeng.api.storage.cells.ICellHandler;
import appeng.api.storage.cells.ICellInventory;
import appeng.api.storage.cells.ICellInventoryHandler;
import appeng.api.storage.*;
import appeng.api.storage.cells.*;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
@@ -133,6 +114,10 @@ public class ChestTileEntity extends AENetworkPowerTileEntity
private ChestMonitorHandler cellHandler;
private Accessor accessor;
private IFluidHandler fluidHandler;
// This is only used on the client to display the right cell model without
// synchronizing the entire
// cell's inventory when a chest comes into view.
private Item cellItem = Items.AIR;
public ChestTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
@@ -273,6 +258,10 @@ public class ChestTileEntity extends AENetworkPowerTileEntity
if (slot != 0) {
return null;
}
// Client-side we'll need to actually use the synced state
if (world == null || world.isRemote) {
return cellItem;
}
ItemStack cell = getCell();
return cell.isEmpty() ? null : cell.getItem();
}
@@ -364,6 +353,12 @@ public class ChestTileEntity extends AENetworkPowerTileEntity
data.writeByte(this.state);
data.writeByte(this.paintedColor.ordinal());
// Note that we trust that the change detection in recalculateDisplay will trip
// when it changes from
// empty->non-empty, so when the cell is changed, it should re-send the state
// because of that
data.writeRegistryIdUnsafe(ForgeRegistries.ITEMS, getCell().getItem().getRegistryName());
}
@Override
@@ -375,6 +370,7 @@ public class ChestTileEntity extends AENetworkPowerTileEntity
this.state = data.readByte();
final AEColor oldPaintedColor = this.paintedColor;
this.paintedColor = AEColor.values()[data.readByte()];
this.cellItem = data.readRegistryIdUnsafe(ForgeRegistries.ITEMS);
this.lastStateChange = this.world.getGameTime();
+15 -13
View File
@@ -822,34 +822,36 @@ public class Platform {
Preconditions.checkNotNull(src);
Preconditions.checkNotNull(mode);
final T possible = cell.injectItems(input.copy(), Actionable.SIMULATE, src);
final T overflow = cell.injectItems(input.copy(), Actionable.SIMULATE, src);
long stored = input.getStackSize();
if (possible != null) {
stored -= possible.getStackSize();
long transferAmount = input.getStackSize();
if (overflow != null) {
transferAmount -= overflow.getStackSize();
}
final double energyFactor = Math.max(1.0, cell.getChannel().transferFactor());
final double availablePower = energy.extractAEPower(stored / energyFactor, Actionable.SIMULATE,
final double availablePower = energy.extractAEPower(transferAmount / energyFactor, Actionable.SIMULATE,
PowerMultiplier.CONFIG);
final long itemToAdd = Math.min((long) ((availablePower * energyFactor) + 0.9), stored);
final long itemToAdd = Math.min((long) ((availablePower * energyFactor) + 0.9), transferAmount);
if (itemToAdd > 0) {
if (mode == Actionable.MODULATE) {
energy.extractAEPower(stored / energyFactor, Actionable.MODULATE, PowerMultiplier.CONFIG);
energy.extractAEPower(transferAmount / energyFactor, Actionable.MODULATE, PowerMultiplier.CONFIG);
if (itemToAdd < input.getStackSize()) {
final long original = input.getStackSize();
final T leftover = input.copy();
final T split = input.copy();
split.decStackSize(itemToAdd);
input.setStackSize(itemToAdd);
split.add(cell.injectItems(input, Actionable.MODULATE, src));
leftover.decStackSize(itemToAdd);
split.setStackSize(itemToAdd);
leftover.add(cell.injectItems(split, Actionable.MODULATE, src));
src.player().ifPresent(player -> {
final long diff = original - split.getStackSize();
final long diff = original - leftover.getStackSize();
AeStats.ItemsInserted.addToPlayer(player, (int) diff);
});
return split;
return leftover;
}
final T ret = cell.injectItems(input, Actionable.MODULATE, src);
@@ -1125,7 +1127,7 @@ public class Platform {
public static void notifyBlocksOfNeighbors(final World world, final BlockPos pos) {
if (!world.isRemote) {
TickHandler.INSTANCE.addCallable(world, new BlockUpdate(pos));
TickHandler.instance().addCallable(world, new BlockUpdate(pos));
}
}
@@ -25,9 +25,9 @@ import appeng.api.networking.IGridNode;
import appeng.api.util.AEPartLocation;
public final class ProxyNodeIterator implements Iterator<IGridNode> {
private final Iterator<IGridHost> hosts;
private final Iterator<? extends IGridHost> hosts;
public ProxyNodeIterator(final Iterator<IGridHost> hosts) {
public ProxyNodeIterator(final Iterator<? extends IGridHost> hosts) {
this.hosts = hosts;
}
+1 -1
View File
@@ -16,7 +16,7 @@ description="A Mod about Matter, Energy and using them to conquer the world.."
[[dependencies.appliedenergistics2]]
modId="forge"
mandatory=true
versionRange="[31.0.0,)"
versionRange="[31.2.31,32.0.0)"
ordering="NONE"
side="BOTH"
@@ -7,7 +7,7 @@
},
{
"when": {
"slot_state": "empty|offline"
"lights_on": false
},
"apply": {
"model": "appliedenergistics2:block/chest/lights_off"
@@ -15,59 +15,11 @@
},
{
"when": {
"slot_state": "online|not_empty|types_full|full"
"lights_on": true
},
"apply": {
"model": "appliedenergistics2:block/chest/lights_on"
}
},
{
"when": {
"slot_state": "empty"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_empty"
}
},
{
"when": {
"slot_state": "offline"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_offline"
}
},
{
"when": {
"slot_state": "online"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_online"
}
},
{
"when": {
"slot_state": "not_empty"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_not_empty"
}
},
{
"when": {
"slot_state": "types_full"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_types_full"
}
},
{
"when": {
"slot_state": "full"
},
"apply": {
"model": "appliedenergistics2:block/chest/cell_state_full"
}
}
]
}
@@ -190,6 +190,7 @@
"gui.appliedenergistics2.FluidFormationPlane": "Fluid Formation Plane",
"gui.appliedenergistics2.FluidInterface": "ME Fluid Interface",
"gui.appliedenergistics2.FluidLevelEmitter": "ME Fluid Level Emitter",
"gui.appliedenergistics2.FluidLevelEmitterUnit": "mB",
"gui.appliedenergistics2.Fluix": "Fluix",
"gui.appliedenergistics2.FormationPlane": "Formation Plane",
"gui.appliedenergistics2.FromStorage": "Available",
@@ -0,0 +1,613 @@
{
"block.appliedenergistics2.cable_bus": "AE2ケーブルまたはバス",
"block.appliedenergistics2.cell_workbench": "セルワークベンチ",
"block.appliedenergistics2.charger": "チャージャー",
"block.appliedenergistics2.chest": "MEチェスト",
"block.appliedenergistics2.condenser": "マターコンデンサー",
"block.appliedenergistics2.controller": "MEコントローラー",
"block.appliedenergistics2.crank": "木のクランク",
"block.appliedenergistics2.creative_energy_cell": "クリエイティブエナジーセル",
"block.appliedenergistics2.dense_energy_cell": "濃縮エナジーセル",
"block.appliedenergistics2.energy_cell": "エナジーセル",
"block.appliedenergistics2.drive": "MEドライブ",
"block.appliedenergistics2.energy_acceptor": "エナジーアクセプター",
"block.appliedenergistics2.grindstone": "クォーツ粉砕機",
"block.appliedenergistics2.matrix_frame": "マトリックスフレーム",
"block.appliedenergistics2.io_port": "ME入出力ポート",
"block.appliedenergistics2.inscriber": "刻印機",
"block.appliedenergistics2.interface": "MEインターフェース",
"block.appliedenergistics2.fluid_interface": "ME液体インターフェース",
"block.appliedenergistics2.quantum_link": "MEクァンタムリンクチェンバー",
"block.appliedenergistics2.quantum_ring": "MEクァンタムリング",
"block.appliedenergistics2.fluix_block": "フルーシュブロック",
"block.appliedenergistics2.quartz_block": "ケルタスクォーツブロック",
"block.appliedenergistics2.chiseled_quartz_block": "模様入りケルタスクォーツブロック",
"block.appliedenergistics2.quartz_glass": "クォーツガラス",
"block.appliedenergistics2.quartz_vibrant_glass": "彩光クォーツガラス",
"block.appliedenergistics2.quartz_pillar": "柱状ケルタスクォーツブロック",
"block.appliedenergistics2.quartz_fixture": "チャージ済みケルタスクォーツ電灯",
"block.appliedenergistics2.light_detector": "光検知器",
"block.appliedenergistics2.spatial_io_port": "空間入出力ポート",
"block.appliedenergistics2.spatial_pylon": "空間標識",
"block.appliedenergistics2.tiny_tnt": "極小TNT",
"block.appliedenergistics2.vibration_chamber": "火力発電機",
"block.appliedenergistics2.wireless_access_point": "ME無線アクセスポイント",
"block.appliedenergistics2.quartz_ore": "ケルタスクォーツ鉱石",
"block.appliedenergistics2.charged_quartz_ore": "チャージ済みケルタスクォーツ鉱石",
"block.appliedenergistics2.security_station": "MEセキュリティターミナル",
"block.appliedenergistics2.quartz_growth_accelerator": "クリスタル成長加速器",
"block.appliedenergistics2.sky_stone_block": "スカイストーン",
"block.appliedenergistics2.smooth_sky_stone_block": "スカイストーンブロック",
"block.appliedenergistics2.sky_stone_brick": "スカイストーンレンガ",
"block.appliedenergistics2.sky_stone_small_brick": "スカイストーン小レンガ",
"block.appliedenergistics2.sky_stone_chest": "スカイストーンチェスト",
"block.appliedenergistics2.smooth_sky_stone_chest": "スカイストーンブロックチェスト",
"block.appliedenergistics2.sky_compass": "隕石コンパス",
"block.appliedenergistics2.crafting_monitor": "クラフトモニター",
"block.appliedenergistics2.crafting_storage_1k": "1kクラフトストレージ",
"block.appliedenergistics2.crafting_storage_4k": "4kクラフトストレージ",
"block.appliedenergistics2.crafting_storage_16k": "16kクラフトストレージ",
"block.appliedenergistics2.crafting_storage_64k": "64kクラフトストレージ",
"block.appliedenergistics2.crafting_accelerator": "並列クラフトユニット",
"block.appliedenergistics2.crafting_unit": "クラフトユニット",
"block.appliedenergistics2.molecular_assembler": "分子組立機",
"block.appliedenergistics2.fluix_stairs": "フルーシュの階段",
"block.appliedenergistics2.quartz_stairs": "ケルタスクォーツの階段",
"block.appliedenergistics2.chiseled_quartz_stairs": "模様入りケルタスクォーツの階段",
"block.appliedenergistics2.quartz_pillar_stairs": "柱状ケルタスクォーツの階段",
"block.appliedenergistics2.smooth_sky_stone_stairs": "スカイストーンブロックの階段",
"block.appliedenergistics2.sky_stone_brick_stairs": "スカイストーンレンガの階段",
"block.appliedenergistics2.sky_stone_small_brick_stairs": "スカイストーン小レンガの階段",
"block.appliedenergistics2.sky_stone_stairs": "スカイストーンの階段",
"block.appliedenergistics2.chiseled_quartz_slab": "模様入りケルタスクォーツのハーフブロック",
"block.appliedenergistics2.fluix_slab": "フルーシュのハーフブロック",
"block.appliedenergistics2.quartz_pillar_slab": "柱状ケルタスクォーツのハーフブロック",
"block.appliedenergistics2.quartz_slab": "ケルタスクォーツのハーフブロック",
"block.appliedenergistics2.smooth_sky_stone_slab": "スカイストーンブロックのハーフブロック",
"block.appliedenergistics2.sky_stone_brick_slab": "スカイストーンレンガのハーフブロック",
"block.appliedenergistics2.sky_stone_small_brick_slab": "スカイストーン小レンガのハーフブロック",
"block.appliedenergistics2.sky_stone_slab": "スカイストーンのハーフブロック",
"chat.appliedenergistics2.ChestCannotReadStorageCell": "MEチェストがストレージセルを読み込めません。",
"chat.appliedenergistics2.SettingCleared": "メモリーカードを消去しました。",
"chat.appliedenergistics2.OutOfRange": "無線が範囲外です。",
"chat.appliedenergistics2.InvalidMachine": "無効な装置です。",
"chat.appliedenergistics2.LoadedSettings": "メモリカードからデバイス構成をロードしました。",
"chat.appliedenergistics2.DeviceNotPowered": "デバイスの電力が低下しています。",
"chat.appliedenergistics2.DeviceNotWirelessTerminal": "デバイスは無線ターミナルではありません。",
"chat.appliedenergistics2.DeviceNotLinked": "デバイスはリンクされていません。",
"chat.appliedenergistics2.StationCanNotBeLocated": "ステーションが見つかりません。",
"chat.appliedenergistics2.MachineNotPowered": "マシンの電源が入っていません。",
"chat.appliedenergistics2.CommunicationError": "ネットワーク通信エラー。",
"chat.appliedenergistics2.SavedSettings": "現在のデバイス構成をメモリカードにコピーしました。",
"chat.appliedenergistics2.ResetSettings": "新しいデバイス構成が作成され、メモリカードにコピーされました。",
"chat.appliedenergistics2.AmmoDepleted": "弾薬がなくなりました。",
"chat.appliedenergistics2.isNowLocked": "モニターはロックされました。",
"chat.appliedenergistics2.isNowUnlocked": "モニターのロックが解除されました。",
"itemGroup.appliedenergistics2": "Applied Energistics 2",
"itemGroup.appliedenergistics2.facades": "Applied Energistics 2 - 外観",
"gui.appliedenergistics2.CraftingTerminal": "クラフトターミナル",
"gui.appliedenergistics2.METunnel": "ME",
"gui.appliedenergistics2.ItemTunnel": "アイテム",
"gui.appliedenergistics2.FluidTunnel": "液体",
"gui.appliedenergistics2.RedstoneTunnel": "レッドストーン",
"gui.appliedenergistics2.EUTunnel": "EU",
"gui.appliedenergistics2.FETunnel": "FE",
"gui.appliedenergistics2.LightTunnel": "光",
"gui.appliedenergistics2.OCTunnel": "OpenComputers",
"gui.appliedenergistics2.PressureTunnel": "Pressure",
"gui.appliedenergistics2.security.extract": "引き出し",
"gui.appliedenergistics2.security.inject": "入金",
"gui.appliedenergistics2.security.craft": "クラフト",
"gui.appliedenergistics2.security.build": "ビルド",
"gui.appliedenergistics2.security.security": "セキュリティ",
"gui.appliedenergistics2.security.extract.tip": "ユーザーはストレージからアイテムを削除できます。",
"gui.appliedenergistics2.security.inject.tip": "ユーザーは新しいアイテムをストレージに保存できます。",
"gui.appliedenergistics2.security.craft.tip": "ユーザーは新しいクラフトジョブを開始できます。",
"gui.appliedenergistics2.security.build.tip": "ユーザーはネットワークの物理構造を変更し、構成を変更できます。",
"gui.appliedenergistics2.security.security.tip": "ユーザーは、ネットワークのセキュリティ端末にアクセスして変更できます。",
"gui.appliedenergistics2.Efficiency": "効率",
"gui.appliedenergistics2.SCSSize": "SCSサイズ",
"gui.appliedenergistics2.SCSInvalid": "無効",
"gui.appliedenergistics2.RequiredPower": "必要な電力",
"gui.appliedenergistics2.StoredPower": "充電済み電力",
"gui.appliedenergistics2.MaxPower": "最大電力",
"gui.appliedenergistics2.QuartzCuttingKnife": "クォーツナイフ",
"gui.appliedenergistics2.Inscriber": "刻印機",
"gui.appliedenergistics2.Wireless": "無線アクセスポイント",
"gui.appliedenergistics2.WirelessTerminal": "ワイヤレスターミナル",
"gui.appliedenergistics2.NoPermissions": "権限未選択",
"gui.appliedenergistics2.SecurityCardEditor": "生体認証カードエディター",
"gui.appliedenergistics2.Encoded": "エンコード済み",
"gui.appliedenergistics2.Priority": "優先度",
"gui.appliedenergistics2.StorageBus": "ストレージバス",
"gui.appliedenergistics2.StorageBusFluids": "液体ストレージバス",
"gui.appliedenergistics2.EnergyDrain": "受動排泄",
"gui.appliedenergistics2.Installed": "インストール済み",
"gui.appliedenergistics2.NetworkTool": "ネットワークツール",
"gui.appliedenergistics2.PowerUsageRate": "エネルギー使用率",
"gui.appliedenergistics2.PowerInputRate": "エネルギー充電率",
"gui.appliedenergistics2.PortableCell": "ポータブルセル",
"gui.appliedenergistics2.Security": "セキュリティ端末",
"gui.appliedenergistics2.CellWorkbench": "セルワークベンチ",
"gui.appliedenergistics2.QuantumLinkChamber": "クァンタムリンクチェンバー",
"gui.appliedenergistics2.IOPort": "ME入出力ポート",
"gui.appliedenergistics2.Chest": "MEチェスト",
"gui.appliedenergistics2.Condenser": "マターコンデンサー",
"gui.appliedenergistics2.Config": "コンフィグ",
"gui.appliedenergistics2.Drive": "MEドライブ",
"gui.appliedenergistics2.ExportBus": "ME出力バス",
"gui.appliedenergistics2.ExportBusFluids": "ME液体出力バス",
"gui.appliedenergistics2.GrindStone": "粉砕機",
"gui.appliedenergistics2.ImportBus": "MEインポートバス",
"gui.appliedenergistics2.ImportBusFluids": "ME液体インポートバス",
"gui.appliedenergistics2.Interface": "MEインターフェース",
"gui.appliedenergistics2.FluidInterface": "ME液体インターフェース",
"gui.appliedenergistics2.LevelEmitter": "MEレベルエミッター",
"gui.appliedenergistics2.FluidLevelEmitter": "ME液体レベルエミッター",
"gui.appliedenergistics2.Of": "の",
"gui.appliedenergistics2.Patterns": "パターン",
"gui.appliedenergistics2.SpatialIOPort": "空間入出力ポート",
"gui.appliedenergistics2.StoredEnergy": "保管済みエネルギー",
"gui.appliedenergistics2.StoredItems": "保管済みアイテム",
"gui.appliedenergistics2.StoredFluids": "保管済み液体",
"gui.appliedenergistics2.Terminal": "ターミナル",
"gui.appliedenergistics2.InterfaceTerminal": "インターフェースターミナル",
"gui.appliedenergistics2.InterfaceTerminalHint": "インターフェースターミナルで表示または隠す。",
"gui.appliedenergistics2.FormationPlane": "ブロック形成機",
"gui.appliedenergistics2.FluidFormationPlane": "液体形成機",
"gui.appliedenergistics2.VibrationChamber": "火力発電機",
"gui.appliedenergistics2.NetworkDetails": "ネットワークの詳細",
"gui.appliedenergistics2.StorageCells": "MEストレージセル",
"gui.appliedenergistics2.IOBuses": "MEインポート/エクスポートバス",
"gui.appliedenergistics2.IOBusesFluids": "ME液体インポート/エクスポートバス",
"gui.appliedenergistics2.Stores": "保管",
"gui.appliedenergistics2.BytesUsed": "バイト使用済み",
"gui.appliedenergistics2.Types": "タイプ",
"gui.appliedenergistics2.Blank": "空",
"gui.appliedenergistics2.Unlinked": "リンクされてない",
"gui.appliedenergistics2.Linked": "リンク済み",
"gui.appliedenergistics2.StoredSize": "保管済みサイズ",
"gui.appliedenergistics2.CellId": "セルID",
"gui.appliedenergistics2.SkyChest": "スカイストーンチェスト",
"gui.appliedenergistics2.PatternTerminal": "パターンターミナル",
"gui.appliedenergistics2.CraftingPattern": "クラフトパターン",
"gui.appliedenergistics2.MolecularAssembler": "分子集成室",
"gui.appliedenergistics2.ProcessingPattern": "処理パターン",
"gui.appliedenergistics2.Crafts": "クラフト",
"gui.appliedenergistics2.And": "と",
"gui.appliedenergistics2.Creates": "クリエイト",
"gui.appliedenergistics2.With": "と",
"gui.appliedenergistics2.Substitute": "置き換えの使用:",
"gui.appliedenergistics2.Yes": "はい",
"gui.appliedenergistics2.No": "いいえ",
"gui.appliedenergistics2.InWorldCrafting": "AE2のワールド内のクラフト",
"gui.appliedenergistics2.inWorldFluix": "チャージ済みケルタスクォーツ1つ、ネザークォーツ1つ、レッドストーン1つをまとめて水の中に入れると2つのフルーシュクリスタルになります。",
"gui.appliedenergistics2.inWorldPurificationCertus": "ケルタスクォーツの粉と砂で作られたケルタスクォーツの種を水の中に落とします。成長を高速化するには、クリスタル成長加速器を使用します。",
"gui.appliedenergistics2.inWorldPurificationNether": "ネザークォーツの粉と砂で作られたネザークォーツの種を水の中に落とします。成長を高速化するには、クリスタル成長加速器を使用します。",
"gui.appliedenergistics2.inWorldPurificationFluix": "フルーシュの粉と砂で作ったフルーシュの種を水の中に落とします。 成長を高速化するには、クリスタル成長加速器を追加します。",
"gui.appliedenergistics2.inWorldSingularity": "作成するには特異点とエンダーパールの粉を置いて、爆発に巻き込ませてください。",
"gui.appliedenergistics2.ChargedQuartz": "チャージ済みケルタスクォーツはチャージャーを使うことで、チャージされていないケルタスクォーツから作ることができます。",
"gui.appliedenergistics2.ChargedQuartzFind": "チャージ済みケルタスクォーツは、ワールド内ではめったに見つけることができません。輝くことを除けば、通常のケルタスクォーツに似ています。",
"gui.appliedenergistics2.NoSecondOutput": "2番目の出力無し",
"gui.appliedenergistics2.OfSecondOutput": "2番目の出力率 %1$d%%。",
"gui.appliedenergistics2.MultipleOutputs": "2番目 %1$d%%、3番目の出力率 %2$d%%。",
"gui.appliedenergistics2.SelectAmount": "金額を選択",
"gui.appliedenergistics2.CopyMode": "コピーモード",
"gui.appliedenergistics2.CopyModeDesc": "セルを削除するときに構成ペインの内容をクリアするかどうかをコントロールします。",
"gui.appliedenergistics2.Next": "次",
"gui.appliedenergistics2.Lumen": "ルーメン",
"gui.appliedenergistics2.Empty": "空",
"gui.appliedenergistics2.Stored": "保管済み",
"gui.appliedenergistics2.Cancel": "キャンセル",
"gui.appliedenergistics2.ETAFormat": "HH:mm:ss",
"gui.appliedenergistics2.Crafting": "クラフト",
"gui.appliedenergistics2.Scheduled": "予約済み",
"gui.appliedenergistics2.CraftingStatus": "クラフト状況",
"gui.appliedenergistics2.FromStorage": "有効",
"gui.appliedenergistics2.ToCraft": "クラフトへ",
"gui.appliedenergistics2.CraftingPlan": "クラフト計画",
"gui.appliedenergistics2.Automatic": "自動",
"gui.appliedenergistics2.Start": "スタート",
"gui.appliedenergistics2.Missing": "不足",
"gui.appliedenergistics2.Bytes": "ストレージ",
"gui.appliedenergistics2.Simulation": "シュミレート",
"gui.appliedenergistics2.CoProcessors": "プロセッサ",
"gui.appliedenergistics2.CraftingCPU": "クラフトCPU",
"gui.appliedenergistics2.NoCraftingCPUs": "クラフトCPUが有効ではありません",
"gui.appliedenergistics2.CalculatingWait": "計算中 しばらくお待ち下さい...",
"gui.appliedenergistics2.Clean": "消去",
"gui.appliedenergistics2.InvalidPattern": "無効なパターン",
"gui.appliedenergistics2.Range": "範囲",
"gui.appliedenergistics2.TransparentFacades": "透明な外装",
"gui.appliedenergistics2.TransparentFacadesHint": "ネットワークツールが手持ちにあるときに、外装の可視性を制御します。",
"gui.appliedenergistics2.CPUs": "CPU",
"gui.appliedenergistics2.NoCraftingJobs": "有効なクラフトジョブはありません",
"gui.appliedenergistics2.FacadeCrafting": "外装クラフト中",
"gui.appliedenergistics2.inWorldCraftingPresses": "金型は、ワールド内にある隕石の中心にあり、隕石コンパスを使用して見つけることができます。",
"gui.appliedenergistics2.Included": "付属済み",
"gui.appliedenergistics2.Excluded": "除外済み",
"gui.appliedenergistics2.Partitioned": "仕切られた",
"gui.appliedenergistics2.Precise": "正確",
"gui.appliedenergistics2.Fuzzy": "あいまい",
"gui.appliedenergistics2.SmallFontCraft": "クラフト",
"gui.appliedenergistics2.LargeFontCraft": "+",
"gui.appliedenergistics2.Nothing": "無し",
"gui.tooltips.appliedenergistics2.Stash": "保管済みアイテム",
"gui.tooltips.appliedenergistics2.StashDesc": "クラフトグリッド上のアイテムをネットワークストレージに戻します。",
"gui.tooltips.appliedenergistics2.Substitutions": "鉱石辞書の置換",
"gui.tooltips.appliedenergistics2.SubstitutionsDescEnabled": "入力コンポーネントの置換を許可します。",
"gui.tooltips.appliedenergistics2.SubstitutionsDescDisabled": "入力コンポーネントの置換を防止します。",
"gui.tooltips.appliedenergistics2.SubstitutionsOn": "置換有効",
"gui.tooltips.appliedenergistics2.SubstitutionsOff": "置換無効",
"gui.tooltips.appliedenergistics2.Encode": "エンコードパターン",
"gui.tooltips.appliedenergistics2.EncodeDescription": "入力したパターンを現在のエンコードされたパターン、または利用可能な空のパターンに書き込みます。",
"gui.tooltips.appliedenergistics2.FuzzyMode": "ファジー比較",
"gui.tooltips.appliedenergistics2.FZPercent_25": "スプリットダメージ 25%",
"gui.tooltips.appliedenergistics2.FZPercent_50": "スプリットダメージ 50%",
"gui.tooltips.appliedenergistics2.FZPercent_75": "スプリットダメージ 75%",
"gui.tooltips.appliedenergistics2.FZPercent_99": "スプリットダメージ 99%",
"gui.tooltips.appliedenergistics2.SortOrder": "ソート順",
"gui.tooltips.appliedenergistics2.SortBy": "並び替え",
"gui.tooltips.appliedenergistics2.FZIgnoreAll": "いずれかに一致",
"gui.tooltips.appliedenergistics2.TransferDirection": "転送方向",
"gui.tooltips.appliedenergistics2.TransferToNetwork": "ネットワークへのデータ転送",
"gui.tooltips.appliedenergistics2.TransferToStorageCell": "ストレージセルへのデータ転送",
"gui.tooltips.appliedenergistics2.ToggleSortDirection": "ソート方向を切り替え",
"gui.tooltips.appliedenergistics2.StoredItems": "保管済みアイテム",
"gui.tooltips.appliedenergistics2.StoredCraftable": "保管済み / クラフト可能",
"gui.tooltips.appliedenergistics2.View": "表示",
"gui.tooltips.appliedenergistics2.RedstoneMode": "レッドストーンモード",
"gui.tooltips.appliedenergistics2.OperationMode": "演算モード",
"gui.tooltips.appliedenergistics2.NumberOfItems": "アイテムの数",
"gui.tooltips.appliedenergistics2.ItemName": "アイテムの名前",
"gui.tooltips.appliedenergistics2.PowerUnits": "パワーユニット",
"gui.tooltips.appliedenergistics2.IOMode": "入力/出力 モード",
"gui.tooltips.appliedenergistics2.CondenserOutput": "MEコンデンサー - 出力",
"gui.tooltips.appliedenergistics2.PartitionStorage": "パーティションストレージ",
"gui.tooltips.appliedenergistics2.Clear": "消去",
"gui.tooltips.appliedenergistics2.TrashController": "Shift / Spaceによる削除。",
"gui.tooltips.appliedenergistics2.InterfaceBlockingMode": "ブロックモード",
"gui.tooltips.appliedenergistics2.InterfaceCraftingMode": "クラフトモード",
"gui.tooltips.appliedenergistics2.Trash": "アイテムを消去",
"gui.tooltips.appliedenergistics2.MatterBalls": "マターボールへの凝縮\\nアイテムごとに%s個",
"gui.tooltips.appliedenergistics2.Singularity": "特異点への凝縮\\nアイテムごとに%s個",
"gui.tooltips.appliedenergistics2.Read": "抽出のみ",
"gui.tooltips.appliedenergistics2.Write": "挿入のみ",
"gui.tooltips.appliedenergistics2.ReadWrite": "双方向",
"gui.tooltips.appliedenergistics2.AlwaysActive": "常に有効",
"gui.tooltips.appliedenergistics2.ActiveWithoutSignal": "信号無しで有効",
"gui.tooltips.appliedenergistics2.ActiveWithSignal": "信号有りで有効",
"gui.tooltips.appliedenergistics2.ActiveOnPulse": "パルスで有効",
"gui.tooltips.appliedenergistics2.EmitLevelsBelow": "レベルが制限以下の場合に放出します。",
"gui.tooltips.appliedenergistics2.EmitLevelAbove": "レベルが制限以上の場合に放出します。",
"gui.tooltips.appliedenergistics2.SearchMode_Auto": "自動検索",
"gui.tooltips.appliedenergistics2.SearchMode_Standard": "標準検索",
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "JEI自動同期",
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "JEI標準同期",
"gui.tooltips.appliedenergistics2.SearchMode_AutoKeep": "自動検索を続ける",
"gui.tooltips.appliedenergistics2.SearchMode_StandardKeep": "標準検索を続ける",
"gui.tooltips.appliedenergistics2.SearchMode_JEIAutoKeep": "JEI自動同期を続ける",
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandardKeep": "JEI標準同期を続ける",
"gui.tooltips.appliedenergistics2.SearchMode": "検索ボックスモード",
"gui.tooltips.appliedenergistics2.PartitionStorageHint": "現在保存されているアイテムに基づいてパーティションを構成します。",
"gui.tooltips.appliedenergistics2.ClearSettings": "設定の削除",
"gui.tooltips.appliedenergistics2.Craftable": "クラフト可能",
"gui.tooltips.appliedenergistics2.MoveWhenEmpty": "空の場合は出力に移行します。",
"gui.tooltips.appliedenergistics2.MoveWhenWorkIsDone": "作業が完了したら出力に移行します。",
"gui.tooltips.appliedenergistics2.MoveWhenFull": "いっぱいになったら出力に移行します。",
"gui.tooltips.appliedenergistics2.Disabled": "無効",
"gui.tooltips.appliedenergistics2.Enable": "有効",
"gui.tooltips.appliedenergistics2.Blocking": "インベントリにアイテムが含まれている場合、クラフトアイテムをプッシュしないでください。",
"gui.tooltips.appliedenergistics2.NonBlocking": "ターゲットインベントリの内容を無視します。",
"gui.tooltips.appliedenergistics2.Craft": "クラフト動作",
"gui.tooltips.appliedenergistics2.CraftOnly": "エクスポート中は、ストックされたアイテムを使用せず、クラフトアイテムのみを使用してください。",
"gui.tooltips.appliedenergistics2.CraftEither": "エクスポート中に在庫のあるアイテムまたはクラフトアイテムを使用します。",
"gui.tooltips.appliedenergistics2.LevelType": "レベルタイプ",
"gui.tooltips.appliedenergistics2.LevelType_Energy": "エネルギー",
"gui.tooltips.appliedenergistics2.LevelType_Item": "アイテム",
"gui.tooltips.appliedenergistics2.InventoryTweaks": "Inventory Tweaks",
"gui.tooltips.appliedenergistics2.Mod": "Mod",
"gui.tooltips.appliedenergistics2.TerminalStyle": "ターミナルスタイル",
"gui.tooltips.appliedenergistics2.TerminalStyle_Full": "フルスクリーンターミナル",
"gui.tooltips.appliedenergistics2.TerminalStyle_Tall": "ウインドウターミナル大",
"gui.tooltips.appliedenergistics2.TerminalStyle_Small": "ウインドウターミナル小",
"gui.tooltips.appliedenergistics2.DoesntDespawn": "このアイテムはデスポーンしません。",
"gui.tooltips.appliedenergistics2.EmitterMode": "クラフトエミッターモード",
"gui.tooltips.appliedenergistics2.CraftViaRedstone": "アイテムをクラフトしたときレッドストーン出力。",
"gui.tooltips.appliedenergistics2.EmitWhenCrafting": "アイテムをクラフト中にレッドストーン出力。",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItems": "アクセスできないアイテムの報告",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItemsYes": "はい: 抽出できないアイテムが表示されます。",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItemsNo": "いいえ: 抽出可能なアイテムのみが表示されます。",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluids": "アクセスできない液体の報告",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluidsYes": "はい: 抽出できない液体が表示されます。",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluidsNo": "いいえ: 抽出可能な液体のみが表示されます。",
"gui.tooltips.appliedenergistics2.BlockPlacement": "ブロックの設置",
"gui.tooltips.appliedenergistics2.BlockPlacementYes": "ブロックとして設置されます。",
"gui.tooltips.appliedenergistics2.BlockPlacementNo": "アイテムとしてドロップします。",
"gui.tooltips.appliedenergistics2.SchedulingMode": "スケジュールモード",
"gui.tooltips.appliedenergistics2.SchedulingModeDefault": "ネットワークが空になるまで最初のアイテムを出力し、次のアイテムを試します。",
"gui.tooltips.appliedenergistics2.SchedulingModeRoundRobin": "エクスポートにラウンドロビンモードを使います。",
"gui.tooltips.appliedenergistics2.SchedulingModeRandom": "エクスポートにランダムモードを使います。",
"gui.tooltips.appliedenergistics2.FilterMode": "検索フィルターモード",
"gui.tooltips.appliedenergistics2.FilterModeKeep": "以前の検索フィルターを復元します。",
"gui.tooltips.appliedenergistics2.FilterModeClear": "開いたときに消去します。",
"gui.tooltips.appliedenergistics2.ItemsStored": "アイテム保管済み: %s",
"gui.tooltips.appliedenergistics2.ItemsRequestable": "リクエスト可能なアイテム: %s",
"gui.tooltips.appliedenergistics2.P2PFrequency": "周波数: %s",
"gui.appliedenergistics2.units.appliedenergstics": "AE",
"gui.appliedenergistics2.units.ic2": "エネルギーユニット",
"gui.appliedenergistics2.units.rf": "レッドストーンフラックス",
"gui.appliedenergistics2.White": "白色",
"gui.appliedenergistics2.Orange": "橙色",
"gui.appliedenergistics2.Magenta": "赤紫色",
"gui.appliedenergistics2.LightBlue": "水色",
"gui.appliedenergistics2.Yellow": "黄色",
"gui.appliedenergistics2.Lime": "黄緑色",
"gui.appliedenergistics2.Pink": "桃色",
"gui.appliedenergistics2.Gray": "灰色",
"gui.appliedenergistics2.LightGray": "薄灰色",
"gui.appliedenergistics2.Cyan": "空色",
"gui.appliedenergistics2.Purple": "紫色",
"gui.appliedenergistics2.Blue": "青色",
"gui.appliedenergistics2.Brown": "茶色",
"gui.appliedenergistics2.Green": "緑色",
"gui.appliedenergistics2.Red": "赤色",
"gui.appliedenergistics2.Black": "黒色",
"gui.appliedenergistics2.Fluix": "フルーシュ",
"waila.appliedenergistics2.Crafting": "クラフト中",
"waila.appliedenergistics2.DeviceOnline": "デバイスオンライン",
"waila.appliedenergistics2.DeviceOffline": "デバイスオフライン",
"waila.appliedenergistics2.DeviceMissingChannel": "デバイスのチャンネル未探知",
"waila.appliedenergistics2.Locked": "ロックされた",
"waila.appliedenergistics2.Unlocked": "解錠された",
"waila.appliedenergistics2.Showing": "表示中",
"waila.appliedenergistics2.Contains": "含まれる",
"waila.appliedenergistics2.Channels": "%1$d / %2$dチャンネル",
"waila.appliedenergistics2.P2PUnlinked": "リンクされてない",
"waila.appliedenergistics2.P2PInputOneOutput": "リンク済み(入力側)",
"waila.appliedenergistics2.P2PInputManyOutputs": "リンク済み(入力側) - 出力: %d",
"waila.appliedenergistics2.P2POutput": "リンク済み(出力側)",
"theoneprobe.appliedenergistics2.crafting": "クラフト中: %1$s",
"theoneprobe.appliedenergistics2.device_online": "デバイスオンライン",
"theoneprobe.appliedenergistics2.device_offline": "デバイスオフライン",
"theoneprobe.appliedenergistics2.device_missing_channel": "デバイスのチャンネル未探知",
"theoneprobe.appliedenergistics2.locked": "ロックされた",
"theoneprobe.appliedenergistics2.unlocked": "解錠された",
"theoneprobe.appliedenergistics2.showing": "表示中",
"theoneprobe.appliedenergistics2.contains": "含まれる",
"theoneprobe.appliedenergistics2.channels": "%1$d / %2$dチャンネル",
"theoneprobe.appliedenergistics2.p2p_unlinked": "リンクされてない",
"theoneprobe.appliedenergistics2.p2p_input_one_output": "リンク済み(入力側)",
"theoneprobe.appliedenergistics2.p2p_input_many_outputs": "リンク済み(入力側) - 出力: %d",
"theoneprobe.appliedenergistics2.p2p_output": "リンク済み(出力側)",
"theoneprobe.appliedenergistics2.p2p_frequency": "周波数: %1$s",
"theoneprobe.appliedenergistics2.stored_energy": "%1$d / %2$d",
"item.appliedenergistics2.storage_cell_1k": "1k MEストレージセル",
"item.appliedenergistics2.storage_cell_4k": "4k MEストレージセル",
"item.appliedenergistics2.storage_cell_16k": "16k MEストレージセル",
"item.appliedenergistics2.storage_cell_64k": "64k MEストレージセル",
"item.appliedenergistics2.fluid_storage_cell_1k": "1k ME液体ストレージセル",
"item.appliedenergistics2.fluid_storage_cell_4k": "4k ME液体ストレージセル",
"item.appliedenergistics2.fluid_storage_cell_16k": "16k ME液体ストレージセル",
"item.appliedenergistics2.fluid_storage_cell_64k": "64k ME液体ストレージセル",
"item.appliedenergistics2.creative_storage_cell": "クリエイティブMEストレージセル",
"item.appliedenergistics2.encoded_pattern": "エンコード済みパターン",
"item.appliedenergistics2.view_cell": "表示セル",
"item.appliedenergistics2.facade": "外装ケーブル",
"item.appliedenergistics2.crystal_seed.certus": "ケルタスクォーツの種結晶",
"item.appliedenergistics2.crystal_seed.nether": "ネザークォーツの種結晶",
"item.appliedenergistics2.crystal_seed.fluix": "フルーシュの種結晶",
"item.appliedenergistics2.material.invalid_type": "このアイテムは無効です",
"item.appliedenergistics2.material.advanced_card": "上級カード",
"item.appliedenergistics2.material.annihilation_core": "消滅コア",
"item.appliedenergistics2.material.basic_card": "基本カード",
"item.appliedenergistics2.material.blank_pattern": "空のパターン",
"item.appliedenergistics2.material.calculation_processor": "発展プロセッサ",
"item.appliedenergistics2.material.card_capacity": "キャパシティカード",
"item.appliedenergistics2.material.card_fuzzy": "ファジーカード",
"item.appliedenergistics2.material.card_inverter": "反転カード",
"item.appliedenergistics2.material.card_redstone": "レッドストーンカード",
"item.appliedenergistics2.material.card_speed": "加速カード",
"item.appliedenergistics2.material.cell2_spatial_part": "2³空間コンポーネント",
"item.appliedenergistics2.material.cell16_spatial_part": "16³空間コンポーネント",
"item.appliedenergistics2.material.cell128_spatial_part": "128³空間コンポーネント",
"item.appliedenergistics2.material.cell1k_part": "1k MEストレージコンポーネント",
"item.appliedenergistics2.material.cell4k_part": "4k MEストレージコンポーネント",
"item.appliedenergistics2.material.cell16k_part": "16k MEストレージコンポーネント",
"item.appliedenergistics2.material.cell64k_part": "64k MEストレージコンポーネント",
"item.appliedenergistics2.material.fluid_cell1k_part": "1k ME液体ストレージコンポーネント",
"item.appliedenergistics2.material.fluid_cell4k_part": "4k ME液体ストレージコンポーネント",
"item.appliedenergistics2.material.fluid_cell16k_part": "16k ME液体ストレージコンポーネント",
"item.appliedenergistics2.material.fluid_cell64k_part": "64k ME液体ストレージコンポーネント",
"item.appliedenergistics2.material.certus_quartz_crystal": "ケルタスクォーツクリスタル",
"item.appliedenergistics2.material.certus_quartz_crystal_charged": "チャージ済みケルタスクォーツクリスタル",
"item.appliedenergistics2.material.certus_quartz_dust": "ケルタスクォーツの粉",
"item.appliedenergistics2.material.empty_storage_cell": "MEストレージハウシング",
"item.appliedenergistics2.material.ender_dust": "エンダーパールの粉",
"item.appliedenergistics2.material.engineering_processor": "上級プロセッサ",
"item.appliedenergistics2.material.flour": "小麦粉",
"item.appliedenergistics2.material.fluix_crystal": "フルーシュクリスタル",
"item.appliedenergistics2.material.fluix_dust": "フルーシュの粉",
"item.appliedenergistics2.material.fluix_pearl": "フルーシュパール",
"item.appliedenergistics2.material.formation_core": "形成コア",
"item.appliedenergistics2.material.gold_dust": "金の粉",
"item.appliedenergistics2.material.iron_dust": "鉄の粉",
"item.appliedenergistics2.material.logic_processor": "基本プロセッサ",
"item.appliedenergistics2.material.logic_processor_asm": "未完成基本プロセッサ",
"item.appliedenergistics2.material.matter_ball": "マターボール",
"item.appliedenergistics2.material.nether_quartz_dust": "ネザークォーツの粉",
"item.appliedenergistics2.material.purified_certus_quartz_crystal": "ピュアケルタスクォーツクリスタル",
"item.appliedenergistics2.material.purified_fluix_crystal": "ピュアフルーシュクリスタル",
"item.appliedenergistics2.material.purified_nether_quartz_crystal": "ピュアネザークォーツクリスタル",
"item.appliedenergistics2.material.quantum_entangled_singularity": "量子もつれ特異点",
"item.appliedenergistics2.material.silicon": "シリコン",
"item.appliedenergistics2.material.singularity": "特異点",
"item.appliedenergistics2.material.wireless": "無線受信機",
"item.appliedenergistics2.material.wireless_booster": "無線ブースター",
"item.appliedenergistics2.material.wooden_gear": "木のギア",
"item.appliedenergistics2.material.engineering_processor_press": "上級回路の金型",
"item.appliedenergistics2.material.calculation_processor_press": "発展回路の金型",
"item.appliedenergistics2.material.logic_processor_press": "基本回路の金型",
"item.appliedenergistics2.material.engineering_processor_print": "上級回路",
"item.appliedenergistics2.material.calculation_processor_print": "発展回路",
"item.appliedenergistics2.material.logic_processor_print": "基本回路",
"item.appliedenergistics2.material.silicon_press": "シリコンの金型",
"item.appliedenergistics2.material.silicon_print": "シリコン基盤",
"item.appliedenergistics2.material.name_press": "名札金型",
"item.appliedenergistics2.material.sky_dust": "スカイストーンの粉",
"item.appliedenergistics2.material.card_crafting": "クラフティングカード",
"item.appliedenergistics2.multi_part.annihilation_plane": "MEブロック消滅機",
"item.appliedenergistics2.multi_part.fluid_annihilation_plane": "ME液体消滅機",
"item.appliedenergistics2.multi_part.identity_annihilation_plane": "MEアイデンティティー消滅機",
"item.appliedenergistics2.multi_part.cable_anchor": "ケーブルアンカー",
"item.appliedenergistics2.multi_part.cable_covered": "MEカバーケーブル",
"item.appliedenergistics2.multi_part.cable_glass": "MEガラスケーブル",
"item.appliedenergistics2.multi_part.cable_smart": "MEスマートケーブル",
"item.appliedenergistics2.multi_part.cable_dense_covered": "ME濃縮カバーケーブル",
"item.appliedenergistics2.multi_part.cable_dense_smart": "ME濃縮スマートケーブル",
"item.appliedenergistics2.multi_part.storage_monitor": "MEストレージモニター",
"item.appliedenergistics2.multi_part.conversion_monitor": "ME変換モニター",
"item.appliedenergistics2.multi_part.crafting_terminal": "MEクラフトターミナル",
"item.appliedenergistics2.multi_part.semi_dark_monitor": "発光パネル",
"item.appliedenergistics2.multi_part.monitor": "明るい発光パネル",
"item.appliedenergistics2.multi_part.dark_monitor": "暗い発光パネル",
"item.appliedenergistics2.multi_part.export_bus": "ME出力バス",
"item.appliedenergistics2.multi_part.fluid_export_bus": "ME液体出力バス",
"item.appliedenergistics2.multi_part.formation_plane": "MEブロック形成機",
"item.appliedenergistics2.multi_part.fluid_formation_plane": "ME液体形成機",
"item.appliedenergistics2.multi_part.import_bus": "ME入力バス",
"item.appliedenergistics2.multi_part.fluid_import_bus": "ME液体入力バス",
"item.appliedenergistics2.multi_part.interface": "MEインターフェース",
"item.appliedenergistics2.multi_part.fluid_interface": "ME液体インターフェース",
"item.appliedenergistics2.multi_part.level_emitter": "MEレベルエミッター",
"item.appliedenergistics2.multi_part.fluid_level_emitter": "ME液体レベルエミッター",
"item.appliedenergistics2.multi_part.p2p_tunnel": "P2Pトンネル",
"item.appliedenergistics2.multi_part.pattern_terminal": "MEパターンターミナル",
"item.appliedenergistics2.multi_part.quartz_fiber": "クォーツファイバー",
"item.appliedenergistics2.multi_part.storage_bus": "MEストレージバス",
"item.appliedenergistics2.multi_part.fluid_storage_bus": "ME液体ストレージバス",
"item.appliedenergistics2.multi_part.terminal": "MEターミナル",
"item.appliedenergistics2.multi_part.inverted_toggle_bus": "ME反転トグルバス",
"item.appliedenergistics2.multi_part.toggle_bus": "MEトグルバス",
"item.appliedenergistics2.multi_part.crafting_monitor": "MEクラフトモニター",
"item.appliedenergistics2.multi_part.interface_terminal": "MEインターフェースターミナル",
"item.appliedenergistics2.multi_part.fluid_terminal": "ME液体ターミナル",
"item.appliedenergistics2.multi_part.invalid_type": "無効なアイテム",
"item.appliedenergistics2.spatial_storage_cell_128_cubed": "128³空間ストレージセル",
"item.appliedenergistics2.spatial_storage_cell_16_cubed": "16³空間ストレージセル",
"item.appliedenergistics2.spatial_storage_cell_2_cubed": "2³空間ストレージセル",
"item.appliedenergistics2.certus_quartz_axe": "ケルタスクォーツの斧",
"item.appliedenergistics2.certus_quartz_cutting_knife": "ケルタスクォーツのナイフ",
"item.appliedenergistics2.certus_quartz_hoe": "ケルタスクォーツのクワ",
"item.appliedenergistics2.certus_quartz_pickaxe": "ケルタスクォーツのピッケル",
"item.appliedenergistics2.certus_quartz_spade": "ケルタスクォーツのシャベル",
"item.appliedenergistics2.certus_quartz_sword": "ケルタスクォーツの剣",
"item.appliedenergistics2.certus_quartz_wrench": "ケルタスクォーツのレンチ",
"item.appliedenergistics2.nether_quartz_axe": "ネザークォーツの斧",
"item.appliedenergistics2.nether_quartz_cutting_knife": "ネザークォーツのナイフ",
"item.appliedenergistics2.nether_quartz_hoe": "ネザークォーツのクワ",
"item.appliedenergistics2.nether_quartz_pickaxe": "ネザークォーツのピッケル",
"item.appliedenergistics2.nether_quartz_spade": "ネザークォーツのシャベル",
"item.appliedenergistics2.nether_quartz_sword": "ネザークォーツの剣",
"item.appliedenergistics2.nether_quartz_wrench": "ネザークォーツのレンチ",
"item.appliedenergistics2.paint_ball": "ペイントボール",
"item.appliedenergistics2.portable_cell": "ポータブルセル",
"item.appliedenergistics2.network_tool": "ネットワークツール",
"item.appliedenergistics2.charged_staff": "チャージ済みのスタッフ",
"item.appliedenergistics2.entropy_manipulator": "エントロピーマニュピレーター",
"item.appliedenergistics2.matter_cannon": "マターキャノン",
"item.appliedenergistics2.memory_card": "メモリーカード",
"item.appliedenergistics2.color_applicator": "染色ブラシ",
"item.appliedenergistics2.wireless_terminal": "ワイヤレスターミナル",
"item.appliedenergistics2.biometric_card": "バイオメトリクスカード",
"item.appliedenergistics2.debug_card": "Dev.DebugCard",
"item.appliedenergistics2.debug_replicator_card": "Dev.ReplicatorCard",
"commands.ae2.usage": "Applied Energistics 2 によるコマンド - /ae2 list でリストを表示、/ae2 help _____ でヘルプを表示。",
"commands.ae2.permissions": "このコマンドを実行するための権限がありません。",
"commands.ae2.ChunkLogger": "サーバーログへのチャンクのロードとアンロードを切り替えます。 ( OP )",
"commands.ae2.ChunkLoggerOn": "チャンクロギング: オン",
"commands.ae2.ChunkLoggerOff": "チャンクロギング: オフ",
"commands.ae2.Supporters": "AE2サポーターのリストを表示",
"achievement.ae2.Root": "Applied Energistics",
"achievement.ae2.Root.desc": "チェストだけでは物足りなかったとき",
"achievement.ae2.Compass": "隕石ハンター",
"achievement.ae2.Compass.desc": "隕石コンパスをクラフトする",
"achievement.ae2.Presses": "謎のテクノロジー",
"achievement.ae2.Presses.desc": "金型を見つける",
"achievement.ae2.SpatialIO": "空間座標",
"achievement.ae2.SpatialIO.desc": "空間入出力ポートをクラフトする",
"achievement.ae2.SpatialIOExplorer": "大胆に",
"achievement.ae2.SpatialIOExplorer.desc": "空間ストレージセルに保管する",
"achievement.ae2.StorageCell": "チェストよりも優れてる",
"achievement.ae2.StorageCell.desc": "ストレージセルをクラフトする",
"achievement.ae2.IOPort": "ストレージセルシャッフル",
"achievement.ae2.IOPort.desc": "入出力ポートをクラフトする",
"achievement.ae2.CraftingTerminal": "(マジで)でかいテーブル",
"achievement.ae2.CraftingTerminal.desc": "クラフトターミナルをクラフトする",
"achievement.ae2.PatternTerminal": "巨匠をクラフト",
"achievement.ae2.PatternTerminal.desc": "パターンターミナルをクラフトする",
"achievement.ae2.ChargedQuartz": "衝撃的な出会い",
"achievement.ae2.ChargedQuartz.desc": "チャージ済みクォーツを見つける",
"achievement.ae2.Fluix": "不自然",
"achievement.ae2.Fluix.desc": "フルーシュクリスタルをクラフトする",
"achievement.ae2.Charger": "フルーシュ生産工場",
"achievement.ae2.Charger.desc": "チャージャーをクラフトする",
"achievement.ae2.CrystalGrowthAccelerator": "ゆっくりな加速器",
"achievement.ae2.CrystalGrowthAccelerator.desc": "クリスタル成長加速器をクラフトする",
"achievement.ae2.GlassCable": "フルーシュエナジー接続",
"achievement.ae2.GlassCable.desc": "MEガラスケーブルをクラフトする",
"achievement.ae2.Networking1": "ネットワーク見習い",
"achievement.ae2.Networking1.desc": "ネットワークにデバイスを使って8つのチャンネルを繋ぐ。",
"achievement.ae2.Controller": "ネットワークスイッチングハブ",
"achievement.ae2.Controller.desc": "コントローラーをクラフトする",
"achievement.ae2.Networking2": "ネットワークエンジニア",
"achievement.ae2.Networking2.desc": "ネットワークにデバイスを使って128のチャンネルを繋ぐ。",
"achievement.ae2.Networking3": "ネットワーク管理者",
"achievement.ae2.Networking3.desc": "ネットワークにデバイスを使って2048のチャンネルを繋ぐ。",
"achievement.ae2.P2P": "ポイント・トゥ・ポイント・ネットワーク",
"achievement.ae2.P2P.desc": "P2Pトンネルをクラフトする",
"achievement.ae2.Recursive": "ネットワークの再帰",
"achievement.ae2.Recursive.desc": "ストレージバスにインターフェースを設置する。",
"achievement.ae2.CraftingCPU": "次世代クラフト",
"achievement.ae2.CraftingCPU.desc": "クラフトユニットをクラフトする",
"achievement.ae2.Facade": "ネットワークの美学",
"achievement.ae2.Facade.desc": "外装ケーブルをクラフトする",
"achievement.ae2.NetworkTool": "ネットワーク診断",
"achievement.ae2.NetworkTool.desc": "ネットワークツールをクラフトする",
"achievement.ae2.PortableCell": "ストレージ放牧民",
"achievement.ae2.PortableCell.desc": "ポータブルセルをクラフトする",
"achievement.ae2.StorageBus": "無限の可能性",
"achievement.ae2.StorageBus.desc": "ストレージバスをクラフトする",
"achievement.ae2.QNB": "量子トンネル",
"achievement.ae2.QNB.desc": "クァンタムリンクをクラフトする",
"stat.ae2.ItemsInserted": "MEストレージにアイテムが追加された",
"stat.ae2.ItemsExtracted": "MEストレージからアイテムが搬出された",
"stat.ae2.TurnedCranks": "クランクが回された",
"key.appliedenergistics2.category": "Applied Energistics 2",
"key.toggle_focus.desc": "検索ボックスのフォーカスの切り替え"
}
@@ -0,0 +1,708 @@
{
"achievement.ae2.ChargedQuartz": "Chockerande",
"achievement.ae2.ChargedQuartz.desc": "Hitta uppladdad kvarts",
"achievement.ae2.Charger": "Fluixproduktion",
"achievement.ae2.Charger.desc": "Tillverka en uppladdare",
"achievement.ae2.Compass": "Meteoritjägare",
"achievement.ae2.Compass.desc": "Tillverka en meteoritkompass",
"achievement.ae2.Controller": "Kontrollpanel för nätverk",
"achievement.ae2.Controller.desc": "Tillverka en kontroll",
"achievement.ae2.CraftingCPU": "Nästa generationens tillverkning",
"achievement.ae2.CraftingCPU.desc": "Tillverka en tillverkningsenhet",
"achievement.ae2.CraftingTerminal": "Ett (mycket) större bord",
"achievement.ae2.CraftingTerminal.desc": "Tillverka en tillverkningsterminal",
"achievement.ae2.CrystalGrowthAccelerator": "Accelerering är en underdrift",
"achievement.ae2.CrystalGrowthAccelerator.desc": "Tillverka en kristallutvidgningsaccelerator",
"achievement.ae2.Facade": "Nätverksestetik",
"achievement.ae2.Facade.desc": "Tillverka en kabelfasad",
"achievement.ae2.Fluix": "Onaturligt",
"achievement.ae2.Fluix.desc": "Skapa fluixkristaller",
"achievement.ae2.GlassCable": "Fluixenergianslutning",
"achievement.ae2.GlassCable.desc": "Tillverka en ME-glaskabel",
"achievement.ae2.IOPort": "Lagringscellstango",
"achievement.ae2.IOPort.desc": "Tillverka en IO-port",
"achievement.ae2.NetworkTool": "Nätverksdiagnostik",
"achievement.ae2.NetworkTool.desc": "Tillverka ett nätverksverktyg",
"achievement.ae2.Networking1": "Nätverkslärling",
"achievement.ae2.Networking1.desc": "Låt 8 kanaler använda enheter i ett nätverk.",
"achievement.ae2.Networking2": "Nätverksingenjör",
"achievement.ae2.Networking2.desc": "Låt 128 kanaler använda enheter i ett nätverk.",
"achievement.ae2.Networking3": "Nätverksadministratör",
"achievement.ae2.Networking3.desc": "Låt 2048 kanaler använda enheter i ett nätverk.",
"achievement.ae2.P2P": "Punkt till punkt-nätverk",
"achievement.ae2.P2P.desc": "Tillverka en P2P-tunnel",
"achievement.ae2.PatternTerminal": "Tillverkningsmästare",
"achievement.ae2.PatternTerminal.desc": "Tillverka en mönsterterminal",
"achievement.ae2.PortableCell": "Lagringsnomad",
"achievement.ae2.PortableCell.desc": "Tillverka en portabel cell",
"achievement.ae2.Presses": "Okänd teknologi",
"achievement.ae2.Presses.desc": "Hitta en processorpress",
"achievement.ae2.QNB": "Kvantumtunnlar",
"achievement.ae2.QNB.desc": "Tillverka en kvantumlänk",
"achievement.ae2.Recursive": "Rekursivt nätverk",
"achievement.ae2.Recursive.desc": "Placera ett gränssnitt på en lagringsbuss.",
"achievement.ae2.Root": "Applied Energistics",
"achievement.ae2.Root.desc": "När en kista helt enkelt inte räcker till.",
"achievement.ae2.SpatialIO": "Rumskoordination",
"achievement.ae2.SpatialIO.desc": "Tillverka en spatial IO-port",
"achievement.ae2.SpatialIOExplorer": "Mot nya djärva mål",
"achievement.ae2.SpatialIOExplorer.desc": "Lagra i en spatial lagringscell",
"achievement.ae2.StorageBus": "Gränslös potential",
"achievement.ae2.StorageBus.desc": "Tillverka en lagringsbuss",
"achievement.ae2.StorageCell": "Bättre än kistor",
"achievement.ae2.StorageCell.desc": "Tillverka en lagringscell",
"appliedenergistics2.permission_denied": "Du saknar behörighet för att komma åt detta.",
"block.appliedenergistics2.cable_bus": "AE2-kabel och/eller -buss",
"block.appliedenergistics2.cell_workbench": "Cellarbetsbänk",
"block.appliedenergistics2.charged_quartz_ore": "Uppladdad certuskvartsmalm",
"block.appliedenergistics2.charger": "Uppladdare",
"block.appliedenergistics2.chest": "ME-kista",
"block.appliedenergistics2.chiseled_quartz_block": "Mejslat certuskvartsblock",
"block.appliedenergistics2.chiseled_quartz_slab": "Mejslad certuskvartsplatta",
"block.appliedenergistics2.chiseled_quartz_stairs": "Mejslad certuskvartstrappa",
"block.appliedenergistics2.condenser": "Materiakondensator",
"block.appliedenergistics2.controller": "ME-kontroll",
"block.appliedenergistics2.crafting_accelerator": "Medbearbetande tillverkningsenhet",
"block.appliedenergistics2.crafting_monitor": "Tillverkningsskärm",
"block.appliedenergistics2.16k_crafting_storage": "Tillverkningslagring (16k)",
"block.appliedenergistics2.1k_crafting_storage": "Tillverkningslagring (1k)",
"block.appliedenergistics2.4k_crafting_storage": "Tillverkningslagring (4k)",
"block.appliedenergistics2.64k_crafting_storage": "Tillverkningslagring (64k)",
"block.appliedenergistics2.crafting_unit": "Tillverkningsenhet",
"block.appliedenergistics2.crank": "Trävev",
"block.appliedenergistics2.creative_energy_cell": "Kreativ energicell",
"block.appliedenergistics2.debug_chunk_loader": "Dev.ChunkLoader",
"block.appliedenergistics2.debug_cube_gen": "Dev.CubeGen",
"block.appliedenergistics2.debug_energy_gen": "Dev.EnergyGen",
"block.appliedenergistics2.debug_item_gen": "Dev.ItemGen",
"block.appliedenergistics2.debug_phantom_node": "Dev.PhantomNode",
"block.appliedenergistics2.dense_energy_cell": "Kompakt energicell",
"block.appliedenergistics2.drive": "ME-hårddisk",
"block.appliedenergistics2.energy_acceptor": "Energiaccepterare",
"block.appliedenergistics2.energy_cell": "Energicell",
"block.appliedenergistics2.fluid_interface": "ME-gränssnitt för vätska",
"block.appliedenergistics2.fluix_block": "Fluixblock",
"block.appliedenergistics2.fluix_slab": "Fluixplatta",
"block.appliedenergistics2.fluix_stairs": "Fluixtrappa",
"block.appliedenergistics2.grindstone": "Kvartsslipsten",
"block.appliedenergistics2.inscriber": "Pressmaskin",
"block.appliedenergistics2.interface": "ME-gränssnitt",
"block.appliedenergistics2.io_port": "IO-port för ME",
"block.appliedenergistics2.light_detector": "Ljusupptäckande fixtur",
"block.appliedenergistics2.matrix_frame": "Matrisram",
"block.appliedenergistics2.molecular_assembler": "Molekylär montör",
"block.appliedenergistics2.quantum_link": "ME-kvantumlänkskammare",
"block.appliedenergistics2.quantum_ring": "ME-kvantumring",
"block.appliedenergistics2.quartz_block": "Certuskvartsblock",
"block.appliedenergistics2.quartz_fixture": "Uppladdad kvartsfixtur",
"block.appliedenergistics2.quartz_glass": "Kvartsglas",
"block.appliedenergistics2.quartz_growth_accelerator": "Kristallutvidgningsaccelerator",
"block.appliedenergistics2.quartz_ore": "Certuskvartsmalm",
"block.appliedenergistics2.quartz_pillar": "Certuskvartspelare",
"block.appliedenergistics2.quartz_pillar_slab": "Certuskvartspelarplatta",
"block.appliedenergistics2.quartz_pillar_stairs": "Certuskvartspelartrappa",
"block.appliedenergistics2.quartz_slab": "Certuskvartsplatta",
"block.appliedenergistics2.quartz_stairs": "Certuskvartstrappa",
"block.appliedenergistics2.quartz_vibrant_glass": "Livfullt kvartsglas",
"block.appliedenergistics2.security_station": "ME-säkerhetsterminal",
"block.appliedenergistics2.sky_compass": "Meteoritkompass",
"block.appliedenergistics2.sky_stone_block": "Himmelsten",
"block.appliedenergistics2.sky_stone_brick": "Himmelstenstegel",
"block.appliedenergistics2.sky_stone_brick_slab": "Himmelstenstegelplatta",
"block.appliedenergistics2.sky_stone_brick_stairs": "Himmelstenstegeltrappa",
"block.appliedenergistics2.sky_stone_chest": "Himmelstenskista",
"block.appliedenergistics2.sky_stone_slab": "Himmelstensplatta",
"block.appliedenergistics2.sky_stone_small_brick": "Himmelsten med litet tegel",
"block.appliedenergistics2.sky_stone_small_brick_slab": "Himmelstensplatta med litet tegel",
"block.appliedenergistics2.sky_stone_small_brick_stairs": "Himmelstenstrappa med litet tegel",
"block.appliedenergistics2.sky_stone_stairs": "Himmelstenstrappa",
"block.appliedenergistics2.smooth_sky_stone_block": "Himmelstensblock",
"block.appliedenergistics2.smooth_sky_stone_chest": "Himmelstensblockkista",
"block.appliedenergistics2.smooth_sky_stone_slab": "Himmelstensblockplatta",
"block.appliedenergistics2.smooth_sky_stone_stairs": "Himmelstensblocktrappa",
"block.appliedenergistics2.spatial_io_port": "Spatial IO-port",
"block.appliedenergistics2.spatial_pylon": "Spatial pylon",
"block.appliedenergistics2.tiny_tnt": "Liten dynamit",
"block.appliedenergistics2.vibration_chamber": "Vibrationskammare",
"block.appliedenergistics2.wireless_access_point": "Trådlös ME-åtkomstpunkt",
"chat.appliedenergistics2.AmmoDepleted": "Slut på ammunition.",
"chat.appliedenergistics2.ChestCannotReadStorageCell": "ME-kista kan inte läsa lagringscell.",
"chat.appliedenergistics2.CommunicationError": "Fel uppstod under kommunikation med nätverket.",
"chat.appliedenergistics2.DeviceNotLinked": "Enheten är inte länkad.",
"chat.appliedenergistics2.DeviceNotPowered": "Enheten har för lite ström.",
"chat.appliedenergistics2.DeviceNotWirelessTerminal": "Enheten är inte en trådlös terminal.",
"chat.appliedenergistics2.InvalidMachine": "Ogiltig maskin.",
"chat.appliedenergistics2.LoadedSettings": "Läste in enhetskonfiguration från minneskortet.",
"chat.appliedenergistics2.MachineNotPowered": "Maskinen har ingen energi.",
"chat.appliedenergistics2.OutOfRange": "Trådlös anslutning är utom räckhåll.",
"chat.appliedenergistics2.ResetSettings": "Ny enhetskonfiguration skapades och kopierades till minneskortet.",
"chat.appliedenergistics2.SavedSettings": "Kopierade nuvarande enhetskonfiguration till minneskortet.",
"chat.appliedenergistics2.SettingCleared": "Minneskortet rensades.",
"chat.appliedenergistics2.StationCanNotBeLocated": "Stationen kan inte hittas.",
"chat.appliedenergistics2.isNowLocked": "Skärmen är nu låst.",
"chat.appliedenergistics2.isNowUnlocked": "Skärmen är nu upplåst.",
"commands.ae2.ChunkLoggerOff": "Loggning av datablock har inaktiverats",
"commands.ae2.ChunkLoggerOn": "Loggning av datablock har aktiverats",
"commands.ae2.permissions": "Du har inte tillräckliga behörigheter för att köra detta kommando.",
"commands.ae2.usage": "Kommandon som Applied Energistics 2 tillhandahåller - använd \"/ae2 list\" för en lista och \"/ae2 help _____\" för hjälp med ett kommando.",
"gui.appliedenergistics2.And": "och",
"gui.appliedenergistics2.Automatic": "Automatisk",
"gui.appliedenergistics2.Black": "Svart",
"gui.appliedenergistics2.Blank": "Blankt",
"gui.appliedenergistics2.Blue": "Blå",
"gui.appliedenergistics2.Brown": "Brun",
"gui.appliedenergistics2.Bytes": "Lagring",
"gui.appliedenergistics2.BytesUsed": "Byte används",
"gui.appliedenergistics2.CPUs": "Processor",
"gui.appliedenergistics2.CalculatingWait": "Beräknar, var god vänta...",
"gui.appliedenergistics2.Cancel": "Avbryt",
"gui.appliedenergistics2.CellWorkbench": "Cellarbetsbänk",
"gui.appliedenergistics2.ChargedQuartz": "Uppladdad certuskvarts tillverkas genom att stoppa in en ouppladdad certuskvarts- kristall i en uppladdare och sedan förse den med energi.",
"gui.appliedenergistics2.ChargedQuartzFind": "Uppladdad certuskvarts kan hittas runt om i världen, men är ganska sällsynt och liknar vanlig certuskvarts bortsett från att den gnistrar.",
"gui.appliedenergistics2.Chest": "ME-kista",
"gui.appliedenergistics2.Clean": "Rensa",
"gui.appliedenergistics2.CoProcessors": "Medprocessorer",
"gui.appliedenergistics2.Condenser": "Materiakondensator",
"gui.appliedenergistics2.Config": "Konfiguration",
"gui.appliedenergistics2.CopyMode": "Kopieringsläge",
"gui.appliedenergistics2.CopyModeDesc": "Kontrollerar om konfigurationspanelens innehållet rensas när du tar bort cellen.",
"gui.appliedenergistics2.Crafting": "Tillverkning",
"gui.appliedenergistics2.CraftingCPU": "Tillverkningsprocessor",
"gui.appliedenergistics2.CraftingPattern": "Tillverkningsmönster",
"gui.appliedenergistics2.CraftingPlan": "Tillverkningsplan",
"gui.appliedenergistics2.CraftingStatus": "Tillverkningsstatus",
"gui.appliedenergistics2.CraftingTerminal": "Tillverkningsterminal",
"gui.appliedenergistics2.Crafts": "Tillverkar",
"gui.appliedenergistics2.Creates": "Skapar",
"gui.appliedenergistics2.Cyan": "Turkos",
"gui.appliedenergistics2.Drive": "ME-hårddisk",
"gui.appliedenergistics2.ETAFormat": "HH:mm:ss",
"gui.appliedenergistics2.Efficiency": "Effektivitet",
"gui.appliedenergistics2.Empty": "Tom",
"gui.appliedenergistics2.Unformatted": "Oformaterad",
"gui.appliedenergistics2.SerialNumber": "Serienummer: %s",
"gui.appliedenergistics2.Encoded": "Kodad",
"gui.appliedenergistics2.EnergyDrain": "Passiv dränering",
"gui.appliedenergistics2.Excluded": "Exkluderad",
"gui.appliedenergistics2.ExportBus": "ME-exportbuss",
"gui.appliedenergistics2.ExportBusFluids": "ME-exportbuss för vätska",
"gui.appliedenergistics2.FacadeCrafting": "Fasadtillverkning",
"gui.appliedenergistics2.FluidFormationPlane": "Formationsplatta för vätska",
"gui.appliedenergistics2.FluidInterface": "ME-gränssnitt för vätska",
"gui.appliedenergistics2.FluidLevelEmitter": "ME-nivåavgivare för vätska",
"gui.appliedenergistics2.Fluix": "Fluix",
"gui.appliedenergistics2.FormationPlane": "Formationsplatta",
"gui.appliedenergistics2.FromStorage": "Tillgänglig",
"gui.appliedenergistics2.Fuzzy": "Suddig",
"gui.appliedenergistics2.Gray": "Grå",
"gui.appliedenergistics2.Green": "Grön",
"gui.appliedenergistics2.GrindStone": "Slipsten",
"gui.appliedenergistics2.IOBuses": "ME-import/exportbuss",
"gui.appliedenergistics2.IOBusesFluids": "ME-import/exportbuss för vätska",
"gui.appliedenergistics2.IOPort": "IO-port för ME",
"gui.appliedenergistics2.ImportBus": "ME-importbuss",
"gui.appliedenergistics2.ImportBusFluids": "ME-importbuss för vätska",
"gui.appliedenergistics2.InWorldCrafting": "Tillverka i världen med AE2",
"gui.appliedenergistics2.Included": "Inkluderad",
"gui.appliedenergistics2.Inscriber": "Pressmaskin",
"gui.appliedenergistics2.Installed": "Installerad",
"gui.appliedenergistics2.Interface": "ME-gränssnitt",
"gui.appliedenergistics2.InterfaceTerminal": "Gränssnittsterminal",
"gui.appliedenergistics2.InterfaceTerminalHint": "Visa eller dölj i gränssnittsterminal.",
"gui.appliedenergistics2.InvalidPattern": "Ogiltigt mönster",
"gui.appliedenergistics2.LargeFontCraft": "+",
"gui.appliedenergistics2.LevelEmitter": "ME-nivåavgivare",
"gui.appliedenergistics2.LightBlue": "Ljusblå",
"gui.appliedenergistics2.LightGray": "Ljusgrå",
"gui.appliedenergistics2.Lime": "Limegrön",
"gui.appliedenergistics2.Linked": "Länkad",
"gui.appliedenergistics2.Lumen": "Lumen",
"gui.appliedenergistics2.Magenta": "Ljuslila",
"gui.appliedenergistics2.MaxPower": "Maximal ström",
"gui.appliedenergistics2.Missing": "Saknas",
"gui.appliedenergistics2.MolecularAssembler": "Molekylmontör",
"gui.appliedenergistics2.MultipleOutputs": "%1$d %% sekundär, %2$d %% tertiär utmatning.",
"gui.appliedenergistics2.NetworkDetails": "Nätverksdetaljer",
"gui.appliedenergistics2.NetworkTool": "Nätverksverktyg",
"gui.appliedenergistics2.Next": "Nästa",
"gui.appliedenergistics2.No": "Nej",
"gui.appliedenergistics2.NoCraftingCPUs": "Inga tillgängliga tillverkningsprocessorer",
"gui.appliedenergistics2.NoCraftingJobs": "Inga aktiva tillverkningsjobb",
"gui.appliedenergistics2.NoPermissions": "Inga behörigheter har valts",
"gui.appliedenergistics2.NoSecondOutput": "Ingen sekundär utmatning",
"gui.appliedenergistics2.Nothing": "Ingenting",
"gui.appliedenergistics2.OCTunnel": "OpenComputers",
"gui.appliedenergistics2.Of": "av",
"gui.appliedenergistics2.OfSecondOutput": "%1$d %% chans för sekundär utmatning.",
"gui.appliedenergistics2.Orange": "Orange",
"gui.appliedenergistics2.Partitioned": "Partitionerad",
"gui.appliedenergistics2.PatternTerminal": "Mönsterterminal",
"gui.appliedenergistics2.Patterns": "Mönster",
"gui.appliedenergistics2.Pink": "Rosa",
"gui.appliedenergistics2.PortableCell": "Portabel cell",
"gui.appliedenergistics2.PowerInputRate": "Energigenerering",
"gui.appliedenergistics2.PowerUsageRate": "Energianvändning",
"gui.appliedenergistics2.Precise": "Exakt",
"gui.appliedenergistics2.PressureTunnel": "Tryck",
"gui.appliedenergistics2.Priority": "Prioritet",
"gui.appliedenergistics2.ProcessingPattern": "Bearbetningsmönster",
"gui.appliedenergistics2.Purple": "Lila",
"gui.appliedenergistics2.QuantumLinkChamber": "Kvantumlänkskammare",
"gui.appliedenergistics2.QuartzCuttingKnife": "Kvartskniv",
"gui.appliedenergistics2.Range": "Intervall",
"gui.appliedenergistics2.Red": "Röd",
"gui.appliedenergistics2.RequiredPower": "Nödvändig ström",
"gui.appliedenergistics2.SCSInvalid": "Ogiltig",
"gui.appliedenergistics2.SCSSize": "SCS-storlek",
"gui.appliedenergistics2.Scheduled": "Schemalagd",
"gui.appliedenergistics2.Security": "Säk.terminal",
"gui.appliedenergistics2.SecurityCardEditor": "Biometrisk kortredigerare",
"gui.appliedenergistics2.SelectAmount": "Välj mängd",
"gui.appliedenergistics2.Simulation": "Simulering",
"gui.appliedenergistics2.SkyChest": "Himmelstenskista",
"gui.appliedenergistics2.SmallFontCraft": "Tillverka",
"gui.appliedenergistics2.SpatialIOPort": "Spatial IO-port",
"gui.appliedenergistics2.Start": "Start",
"gui.appliedenergistics2.StorageBus": "Lagringsbuss",
"gui.appliedenergistics2.StorageBusFluids": "Lagringsbuss för vätska",
"gui.appliedenergistics2.StorageCells": "ME-lagringsceller",
"gui.appliedenergistics2.Stored": "Lagrad",
"gui.appliedenergistics2.StoredEnergy": "Lagrad energi",
"gui.appliedenergistics2.StoredFluids": "Lagrad vätska",
"gui.appliedenergistics2.StoredItems": "Lagrade föremål",
"gui.appliedenergistics2.StoredPower": "Lagrad ström",
"gui.appliedenergistics2.StoredSize": "Lagrad storlek: %dx%dx%d",
"gui.appliedenergistics2.SpatialCapacity": "Kapacitet: %dx%dx%d",
"gui.appliedenergistics2.Stores": "Lagrar",
"gui.appliedenergistics2.Substitute": "Använder ersättning:",
"gui.appliedenergistics2.Terminal": "Terminal",
"gui.appliedenergistics2.ToCraft": "Att tillverka",
"gui.appliedenergistics2.TransparentFacades": "Genomskinliga fasader",
"gui.appliedenergistics2.TransparentFacadesHint": "Kontrollerar synligheten för fasader när nätverksverktyget är inuti din föremålsmeny.",
"gui.appliedenergistics2.Types": "typer",
"gui.appliedenergistics2.Unlinked": "Olänkad",
"gui.appliedenergistics2.VibrationChamber": "Vibrationskammare",
"gui.appliedenergistics2.White": "Vit",
"gui.appliedenergistics2.Wireless": "Trådlös åtkomstpunkt",
"gui.appliedenergistics2.WirelessTerminal": "Trådlös terminal",
"gui.appliedenergistics2.With": "med",
"gui.appliedenergistics2.Yellow": "Gul",
"gui.appliedenergistics2.Yes": "Ja",
"gui.appliedenergistics2.inWorldCraftingPresses": "Tillverkningspressar finns inuti meteoriter som kan hittas runtomkring i världen, vilket i sin tur kan hittas med hjälp av en meteoritkompass.",
"gui.appliedenergistics2.inWorldFluix": "Släpp 1 uppladdad certus- kvartskristall + 1 netherkvarts + redstonedamm i en vattenpöl och vänta en stund för att få 2 fluixkristaller.",
"gui.appliedenergistics2.inWorldPurificationCertus": "Släpp ett certuskvartsfrö som skapas ifrån certuskvartdamm och sand i en vattenpöl; lägg till kristallutvidgnings- acceleratorer för att snabba på processen.",
"gui.appliedenergistics2.inWorldPurificationFluix": "Släpp ett fluixfrö som skapas ifrån fluixdamm och sand i en vattenpöl; lägg till kristall- utvidgningsacceleratorer för att snabba på processen.",
"gui.appliedenergistics2.inWorldPurificationNether": "Släpp ett netherkvartsfrö som skapas ifrån netherkvartdamm och sand i en vattenpöl; lägg till kristallutvidgnings- acceleratorer för att snabba på processen.",
"gui.appliedenergistics2.inWorldSingularity": "Släpp 1 singularitet samt 1 enderdamm på marken och orsaka sedan en explosion i närheten av föremålen.",
"gui.appliedenergistics2.security.build.name": "Bygga",
"gui.appliedenergistics2.security.build.tip": "Användare kan ändra nätverkets fysiska struktur och ändra konfigurationen.",
"gui.appliedenergistics2.security.craft.name": "Tillverka",
"gui.appliedenergistics2.security.craft.tip": "Användare kan starta nya tillverkningsjobb.",
"gui.appliedenergistics2.security.extract.name": "Ta ut",
"gui.appliedenergistics2.security.extract.tip": "Användare får ta bort föremål från lagringen.",
"gui.appliedenergistics2.security.inject.name": "Sätta in",
"gui.appliedenergistics2.security.inject.tip": "Användare får lagra nya föremål i lagringen.",
"gui.appliedenergistics2.security.security.name": "Säkerhet",
"gui.appliedenergistics2.security.security.tip": "Användare kan komma åt och ändra nätverkets säkerhetsterminal.",
"gui.appliedenergistics2.units.appliedenergstics": "AE",
"gui.appliedenergistics2.units.ic2": "Energy Units",
"gui.appliedenergistics2.units.rf": "Redstone Flux",
"gui.tooltips.appliedenergistics2.ActiveOnPulse": "Aktivera en gång per puls",
"gui.tooltips.appliedenergistics2.ActiveWithSignal": "Aktiv med signal",
"gui.tooltips.appliedenergistics2.ActiveWithoutSignal": "Aktiv utan signal",
"gui.tooltips.appliedenergistics2.AlwaysActive": "Alltid aktiv",
"gui.tooltips.appliedenergistics2.BlockPlacement": "Blockplacering",
"gui.tooltips.appliedenergistics2.BlockPlacementNo": "Blocken kommer att släppas som föremål.",
"gui.tooltips.appliedenergistics2.BlockPlacementYes": "Blocken kommer att placeras som block.",
"gui.tooltips.appliedenergistics2.Blocking": "Flytta inte tillverkningsföremål om utrustning innehåller föremål.",
"gui.tooltips.appliedenergistics2.Clear": "Rensa",
"gui.tooltips.appliedenergistics2.ClearSettings": "Rensa konfigurationer/inställningar",
"gui.tooltips.appliedenergistics2.CondenserOutput": "ME-kondensator - Utmatning",
"gui.tooltips.appliedenergistics2.Craft": "Tillverkningsbeteende",
"gui.tooltips.appliedenergistics2.CraftEither": "Använd lagrade föremål eller tillverka föremål under export.",
"gui.tooltips.appliedenergistics2.CraftOnly": "Använd inte lagrade föremål, tillverka endast föremål under export.",
"gui.tooltips.appliedenergistics2.CraftViaRedstone": "Avge redstone för att tillverka föremål.",
"gui.tooltips.appliedenergistics2.Craftable": "Tillverkningsbara",
"gui.tooltips.appliedenergistics2.Disabled": "Inaktiverad",
"gui.tooltips.appliedenergistics2.DoesntDespawn": "Detta föremål kommer inte försvinna.",
"gui.tooltips.appliedenergistics2.EmitLevelAbove": "Avge när nivåerna är ovan eller lika med gränsen.",
"gui.tooltips.appliedenergistics2.EmitLevelsBelow": "Avge när nivåerna är under gränsen.",
"gui.tooltips.appliedenergistics2.EmitWhenCrafting": "Avge redstone när föremål tillverkas.",
"gui.tooltips.appliedenergistics2.EmitterMode": "Tillverkaravgivarläge",
"gui.tooltips.appliedenergistics2.Enable": "Aktiverad",
"gui.tooltips.appliedenergistics2.Encode": "Kodningsmönster",
"gui.tooltips.appliedenergistics2.EncodeDescription": "Skriv det angivna mönstret till det nuvarande kodade mönstret eller till tillgängliga blanka mönster.",
"gui.tooltips.appliedenergistics2.FZIgnoreAll": "Matcha allting",
"gui.tooltips.appliedenergistics2.FZPercent_25": "Fördela skada vid 25 %%",
"gui.tooltips.appliedenergistics2.FZPercent_50": "Fördela skada vid 50 %%",
"gui.tooltips.appliedenergistics2.FZPercent_75": "Fördela skada vid 75 %%",
"gui.tooltips.appliedenergistics2.FZPercent_99": "Fördela skada vid 99 %%",
"gui.tooltips.appliedenergistics2.FilterMode": "Sökfiltersläge",
"gui.tooltips.appliedenergistics2.FilterModeClear": "Rensa vid varje öppning.",
"gui.tooltips.appliedenergistics2.FilterModeKeep": "Återställ föregående sökfilter.",
"gui.tooltips.appliedenergistics2.FuzzyMode": "Suddig jämförelse",
"gui.tooltips.appliedenergistics2.IOMode": "In-/utmatningsläge",
"gui.tooltips.appliedenergistics2.InterfaceBlockingMode": "Blockeringsläge",
"gui.tooltips.appliedenergistics2.InterfaceCraftingMode": "Tillverkningsläge",
"gui.tooltips.appliedenergistics2.InventoryTweaks": "Utrustningsjusteringar",
"gui.tooltips.appliedenergistics2.ItemName": "Föremålsnamn",
"gui.tooltips.appliedenergistics2.ItemsRequestable": "Begärbara föremål: %s",
"gui.tooltips.appliedenergistics2.ItemsStored": "Lagrade föremål: %s",
"gui.tooltips.appliedenergistics2.LevelType": "Nivåtyp",
"gui.tooltips.appliedenergistics2.LevelType_Energy": "Energi",
"gui.tooltips.appliedenergistics2.LevelType_Item": "Föremål",
"gui.tooltips.appliedenergistics2.MatterBalls": "Kondenseras till materiabollar %s per föremål",
"gui.tooltips.appliedenergistics2.Mod": "Mod",
"gui.tooltips.appliedenergistics2.MoveWhenEmpty": "Flytta till utmatning när den är tom.",
"gui.tooltips.appliedenergistics2.MoveWhenFull": "Flytta till utmatning när den är full.",
"gui.tooltips.appliedenergistics2.MoveWhenWorkIsDone": "Flytta till utmatning när arbetet är färdigt.",
"gui.tooltips.appliedenergistics2.NonBlocking": "Ignorera innehållet i målutrustningen.",
"gui.tooltips.appliedenergistics2.NumberOfItems": "Antal föremål",
"gui.tooltips.appliedenergistics2.OperationMode": "Operationsläge",
"gui.tooltips.appliedenergistics2.P2PFrequency": "Frekvens: %s",
"gui.tooltips.appliedenergistics2.PartitionStorage": "Partitionslagring",
"gui.tooltips.appliedenergistics2.PartitionStorageHint": "Konfigurerar partitionen baserat på nuvarande lagrade föremål.",
"gui.tooltips.appliedenergistics2.PowerUnits": "Strömenheter",
"gui.tooltips.appliedenergistics2.Read": "Extrahera bara",
"gui.tooltips.appliedenergistics2.ReadWrite": "Båda riktningar",
"gui.tooltips.appliedenergistics2.RedstoneMode": "Redstoneläge",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluids": "Rapportera oåtkomliga vätskor",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluidsNo": "Nej: Endast vätskor som kan extraheras kommer att vara synliga.",
"gui.tooltips.appliedenergistics2.ReportInaccessibleFluidsYes": "Ja: Vätskor som inte kan extraeras kommer vara synliga.",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItems": "Rapportera oåtkomliga föremål",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItemsNo": "Nej: Endast föremål som kan extraheras kommer vara synliga.",
"gui.tooltips.appliedenergistics2.ReportInaccessibleItemsYes": "Ja: Föremål som inte kan extraheras kommer vara synliga.",
"gui.tooltips.appliedenergistics2.SchedulingMode": "Schemaläge",
"gui.tooltips.appliedenergistics2.SchedulingModeDefault": "Exportera det första föremålet tills nätverket är tomt, försök sedan med de nästkommande.",
"gui.tooltips.appliedenergistics2.SchedulingModeRandom": "Exportera föremål i slumpartat läge.",
"gui.tooltips.appliedenergistics2.SchedulingModeRoundRobin": "Exportera med \"round robin\"-läget.",
"gui.tooltips.appliedenergistics2.SearchMode": "Läge för sökfältet",
"gui.tooltips.appliedenergistics2.SearchMode_Auto": "Automatisk sökning",
"gui.tooltips.appliedenergistics2.SearchMode_AutoKeep": "Automatisk sökning, behåll inmatningen",
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "Synkronisera automatiskt med JEI",
"gui.tooltips.appliedenergistics2.SearchMode_JEIAutoKeep": "Synkronisera automatiskt med JEI, behåll inmatningen",
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "Standardsynkronisera med JEI",
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandardKeep": "Standardsynkronisera med JEI, behåll inmatningen",
"gui.tooltips.appliedenergistics2.SearchMode_Standard": "Standardsökning",
"gui.tooltips.appliedenergistics2.SearchMode_StandardKeep": "Standardsökning, behåll inmatningen",
"gui.tooltips.appliedenergistics2.Singularity": "Kondenseras till singulariteter %s per föremål",
"gui.tooltips.appliedenergistics2.SortBy": "Sortera efter",
"gui.tooltips.appliedenergistics2.SortOrder": "Sorteringsordning",
"gui.tooltips.appliedenergistics2.Stash": "Lagra föremål",
"gui.tooltips.appliedenergistics2.StashDesc": "Returnera föremål i tillverkningsrutan till nätverkslagringen.",
"gui.tooltips.appliedenergistics2.StoredCraftable": "Lagrade / Tillverkningsbara",
"gui.tooltips.appliedenergistics2.StoredItems": "Lagrade föremål",
"gui.tooltips.appliedenergistics2.Substitutions": "Ersättningsföremål",
"gui.tooltips.appliedenergistics2.SubstitutionsDescDisabled": "Förhindrar att ersättningsföremål används som inmatningskomponenter.",
"gui.tooltips.appliedenergistics2.SubstitutionsDescEnabled": "Tillåter att ersättningsföremål används som inmatningskomponenter.",
"gui.tooltips.appliedenergistics2.SubstitutionsOff": "Ersättningar inaktiverades",
"gui.tooltips.appliedenergistics2.SubstitutionsOn": "Ersättningar aktiverades",
"gui.tooltips.appliedenergistics2.TerminalStyle": "Terminalstil",
"gui.tooltips.appliedenergistics2.TerminalStyle_Full": "Helskärmsterminal",
"gui.tooltips.appliedenergistics2.TerminalStyle_Small": "Liten centrerad terminal",
"gui.tooltips.appliedenergistics2.TerminalStyle_Tall": "Lång centrerad terminal",
"gui.tooltips.appliedenergistics2.ToggleSortDirection": "Växla sorteringsriktning",
"gui.tooltips.appliedenergistics2.TransferDirection": "Överförningsriktning",
"gui.tooltips.appliedenergistics2.TransferToNetwork": "Överför data till nätverk",
"gui.tooltips.appliedenergistics2.TransferToStorageCell": "Överför data till lagringscell",
"gui.tooltips.appliedenergistics2.Trash": "Förstör föremål",
"gui.tooltips.appliedenergistics2.TrashController": "Radera genom att Shift-/mellanslagsklicka.",
"gui.tooltips.appliedenergistics2.View": "Visa",
"gui.tooltips.appliedenergistics2.Write": "Infoga bara",
"item.appliedenergistics2.advanced_card": "Avancerat kort",
"item.appliedenergistics2.annihilation_core": "Annihilationskärna",
"item.appliedenergistics2.annihilation_plane": "ME-annihilationsplatta",
"item.appliedenergistics2.basic_card": "Enkelt kort",
"item.appliedenergistics2.biometric_card": "Biometriskt kort",
"item.appliedenergistics2.black_covered_cable": "Svart täckt ME-kabel",
"item.appliedenergistics2.black_covered_dense_cable": "Svart kompakt täckt ME-kabel",
"item.appliedenergistics2.black_glass_cable": "Svart ME-glaskabel",
"item.appliedenergistics2.black_lumen_paint_ball": "Svart lumenfärgboll",
"item.appliedenergistics2.black_paint_ball": "Svart färgboll",
"item.appliedenergistics2.black_smart_cable": "Svart smart ME-kabel",
"item.appliedenergistics2.black_smart_dense_cable": "Svart kompakt smart ME-kabel",
"item.appliedenergistics2.blank_pattern": "Blankt mönster",
"item.appliedenergistics2.blue_covered_cable": "Blå täckt ME-kabel",
"item.appliedenergistics2.blue_covered_dense_cable": "Blå kompakt täckt ME-kabel",
"item.appliedenergistics2.blue_glass_cable": "Blå ME-glaskabel",
"item.appliedenergistics2.blue_lumen_paint_ball": "Blå lumenfärgboll",
"item.appliedenergistics2.blue_paint_ball": "Blå färgboll",
"item.appliedenergistics2.blue_smart_cable": "Blå smart ME-kabel",
"item.appliedenergistics2.blue_smart_dense_cable": "Blå kompakt smart ME-kabel",
"item.appliedenergistics2.brown_covered_cable": "Brun täckt ME-kabel",
"item.appliedenergistics2.brown_covered_dense_cable": "Brun kompakt täckt ME-kabel",
"item.appliedenergistics2.brown_glass_cable": "Brun ME-glaskabel",
"item.appliedenergistics2.brown_lumen_paint_ball": "Brun lumenfärgboll",
"item.appliedenergistics2.brown_paint_ball": "Brun färgboll",
"item.appliedenergistics2.brown_smart_cable": "Brun smart ME-kabel",
"item.appliedenergistics2.brown_smart_dense_cable": "Brun kompakt smart ME-kabel",
"item.appliedenergistics2.cable_anchor": "Kabelankare",
"item.appliedenergistics2.cable_fluid_interface": "ME-gränssnitt för vätska",
"item.appliedenergistics2.cable_interface": "ME-gränssnitt",
"item.appliedenergistics2.calculation_processor": "Beräkningsprocessor",
"item.appliedenergistics2.calculation_processor_press": "Beräkningspressform",
"item.appliedenergistics2.printed_calculation_processor": "Pressad beräkningskrets",
"item.appliedenergistics2.capacity_card": "Kapacitetskort",
"item.appliedenergistics2.16k_cell_component": "ME-lagringskomponent (16k)",
"item.appliedenergistics2.1k_cell_component": "ME-lagringskomponent (1k)",
"item.appliedenergistics2.4k_cell_component": "ME-lagringskomponent (4k)",
"item.appliedenergistics2.64k_cell_component": "ME-lagringskomponent (64k)",
"item.appliedenergistics2.certus_crystal_seed": "Certuskvartsfrö",
"item.appliedenergistics2.certus_quartz_axe": "Certuskvartsyxa",
"item.appliedenergistics2.certus_quartz_crystal": "Certuskvartskristall",
"item.appliedenergistics2.certus_quartz_cutting_knife": "Certuskvartskniv",
"item.appliedenergistics2.certus_quartz_dust": "Certuskvartsdamm",
"item.appliedenergistics2.certus_quartz_hoe": "Certuskvartsflåhacka",
"item.appliedenergistics2.certus_quartz_pickaxe": "Certuskvartshacka",
"item.appliedenergistics2.certus_quartz_shovel": "Certuskvartsspade",
"item.appliedenergistics2.certus_quartz_sword": "Certuskvartssvärd",
"item.appliedenergistics2.certus_quartz_wrench": "Certuskvartsblocknyckel",
"item.appliedenergistics2.charged_certus_quartz_crystal": "Uppladdad certuskvartskristall",
"item.appliedenergistics2.charged_staff": "Uppladdad stav",
"item.appliedenergistics2.color_applicator": "Färgpåstrykare",
"item.appliedenergistics2.conversion_monitor": "ME-omvandlingsskärm",
"item.appliedenergistics2.crafting_card": "Tillverkningskort",
"item.appliedenergistics2.crafting_monitor": "ME-tillverkningsskärm",
"item.appliedenergistics2.crafting_terminal": "ME-tillverkningsterminal",
"item.appliedenergistics2.creative_storage_cell": "Kreativ ME-lagringscell",
"item.appliedenergistics2.cyan_covered_cable": "Turkos täckt ME-kabel",
"item.appliedenergistics2.cyan_covered_dense_cable": "Turkos kompakt täckt ME-kabel",
"item.appliedenergistics2.cyan_glass_cable": "Turkos ME-glaskabel",
"item.appliedenergistics2.cyan_lumen_paint_ball": "Turkos lumenfärgboll",
"item.appliedenergistics2.cyan_paint_ball": "Turkos färgboll",
"item.appliedenergistics2.cyan_smart_cable": "Turkos smart ME-kabel",
"item.appliedenergistics2.cyan_smart_dense_cable": "Turkos kompakt smart ME-kabel",
"item.appliedenergistics2.dark_monitor": "Mörk upplyst panel",
"item.appliedenergistics2.debug_card": "Dev.DebugCard",
"item.appliedenergistics2.debug_eraser": "Dev.Eraser",
"item.appliedenergistics2.debug_meteorite_placer": "Dev.MeteoritePlacer",
"item.appliedenergistics2.debug_part_placer": "Dev.PartPlacer",
"item.appliedenergistics2.debug_replicator_card": "Dev.ReplicatorCard",
"item.appliedenergistics2.empty_storage_cell": "ME-lagringsmagasinering",
"item.appliedenergistics2.encoded_pattern": "Kodat mönster",
"item.appliedenergistics2.ender_dust": "Enderdamm",
"item.appliedenergistics2.engineering_processor": "Ingenjörsprocessor",
"item.appliedenergistics2.engineering_processor_press": "Ingenjörspressform",
"item.appliedenergistics2.printed_engineering_processor": "Pressad ingenjörskrets",
"item.appliedenergistics2.entropy_manipulator": "Entropimanipulerare",
"item.appliedenergistics2.export_bus": "ME-exportbuss",
"item.appliedenergistics2.facade": "Kabelfasad",
"item.appliedenergistics2.fe_p2p_tunnel": "P2P-tunnel för FE",
"item.appliedenergistics2.flour": "Mjöl",
"item.appliedenergistics2.fluid_annihilation_plane": "ME-annihilationsplatta för vätska",
"item.appliedenergistics2.16k_fluid_cell_component": "ME-lagringskomponent för vätska (16k)",
"item.appliedenergistics2.1k_fluid_cell_component": "ME-lagringskomponent för vätska (1k)",
"item.appliedenergistics2.4k_fluid_cell_component": "ME-lagringskomponent för vätska (4k)",
"item.appliedenergistics2.64k_fluid_cell_component": "ME-lagringskomponent för vätska (64k)",
"item.appliedenergistics2.fluid_export_bus": "ME-exportbuss för vätska",
"item.appliedenergistics2.fluid_formation_plane": "ME-formationsplatta för vätska",
"item.appliedenergistics2.fluid_import_bus": "ME-importbuss för vätska",
"item.appliedenergistics2.fluid_level_emitter": "ME-nivåavgivare för vätska",
"item.appliedenergistics2.fluid_p2p_tunnel": "P2P-tunnel för vätska",
"item.appliedenergistics2.fluid_storage_bus": "ME-lagringsbuss för vätska",
"item.appliedenergistics2.16k_fluid_storage_cell": "ME-lagringscell för vätska (16k)",
"item.appliedenergistics2.1k_fluid_storage_cell": "ME-lagringscell för vätska (1k)",
"item.appliedenergistics2.4k_fluid_storage_cell": "ME-lagringscell för vätska (4k)",
"item.appliedenergistics2.64k_fluid_storage_cell": "ME-lagringscell för vätska (64k)",
"item.appliedenergistics2.fluid_terminal": "ME-terminal för vätska",
"item.appliedenergistics2.fluix_covered_cable": "Täckt ME-fluixkabel",
"item.appliedenergistics2.fluix_covered_dense_cable": "Kompakt täckt ME-fluixkabel",
"item.appliedenergistics2.fluix_crystal": "Fluixkristall",
"item.appliedenergistics2.fluix_crystal_seed": "Fluixfrö",
"item.appliedenergistics2.fluix_dust": "Fluixdamm",
"item.appliedenergistics2.fluix_glass_cable": "ME-fluixglaskabel",
"item.appliedenergistics2.fluix_lumen_paint_ball": "Fluixlumenfärgboll",
"item.appliedenergistics2.fluix_paint_ball": "Fluixfärgboll",
"item.appliedenergistics2.fluix_pearl": "Fluixpärla",
"item.appliedenergistics2.fluix_smart_cable": "Smart ME-fluixkabel",
"item.appliedenergistics2.fluix_smart_dense_cable": "Kompakt smart ME-fluixkabel",
"item.appliedenergistics2.formation_core": "Formationskärna",
"item.appliedenergistics2.formation_plane": "ME-formationsplatta",
"item.appliedenergistics2.fuzzy_card": "Suddigt kort",
"item.appliedenergistics2.gold_dust": "Gulddamm",
"item.appliedenergistics2.gray_covered_cable": "Grå täckt ME-kabel",
"item.appliedenergistics2.gray_covered_dense_cable": "Grå kompakt täckt ME-kabel",
"item.appliedenergistics2.gray_glass_cable": "Grå ME-glaskabel",
"item.appliedenergistics2.gray_lumen_paint_ball": "Grå lumenfärgboll",
"item.appliedenergistics2.gray_paint_ball": "Grå färgboll",
"item.appliedenergistics2.gray_smart_cable": "Grå smart ME-kabel",
"item.appliedenergistics2.gray_smart_dense_cable": "Grå kompakt smart ME-kabel",
"item.appliedenergistics2.green_covered_cable": "Grön täckt ME-kabel",
"item.appliedenergistics2.green_covered_dense_cable": "Grön kompakt täckt ME-kabel",
"item.appliedenergistics2.green_glass_cable": "Grön ME-glaskabel",
"item.appliedenergistics2.green_lumen_paint_ball": "Grön lumenfärgboll",
"item.appliedenergistics2.green_paint_ball": "Grön färgboll",
"item.appliedenergistics2.green_smart_cable": "Grön smart ME-kabel",
"item.appliedenergistics2.green_smart_dense_cable": "Grön kompakt smart ME-kabel",
"item.appliedenergistics2.ic2_p2p_tunnel": "P2P-tunnel för EU",
"item.appliedenergistics2.identity_annihilation_plane": "ME-annihilationsplatta för identiteter",
"item.appliedenergistics2.import_bus": "ME-importbuss",
"item.appliedenergistics2.interface_terminal": "ME-gränssnittsterminal",
"item.appliedenergistics2.invalid_type": "Inaktiverat föremål",
"item.appliedenergistics2.inverted_toggle_bus": "Inverterad ME-strömbrytarbuss",
"item.appliedenergistics2.inverter_card": "Inverteringskort",
"item.appliedenergistics2.iron_dust": "Järndamm",
"item.appliedenergistics2.item_p2p_tunnel": "P2P-tunnel för föremål",
"item.appliedenergistics2.level_emitter": "ME-nivåavgivare",
"item.appliedenergistics2.light_blue_covered_cable": "Ljusblå täckt ME-kabel",
"item.appliedenergistics2.light_blue_covered_dense_cable": "Ljusblå kompakt täckt ME-kabel",
"item.appliedenergistics2.light_blue_glass_cable": "Ljusblå ME-glaskabel",
"item.appliedenergistics2.light_blue_lumen_paint_ball": "Ljusblå lumenfärgboll",
"item.appliedenergistics2.light_blue_paint_ball": "Ljusblå färgboll",
"item.appliedenergistics2.light_blue_smart_cable": "Ljusblå smart ME-kabel",
"item.appliedenergistics2.light_blue_smart_dense_cable": "Ljusblå kompakt smart ME-kabel",
"item.appliedenergistics2.light_gray_covered_cable": "Ljusgrå täckt ME-kabel",
"item.appliedenergistics2.light_gray_covered_dense_cable": "Ljusgrå kompakt täckt ME-kabel",
"item.appliedenergistics2.light_gray_glass_cable": "Ljusgrå ME-glaskabel",
"item.appliedenergistics2.light_gray_lumen_paint_ball": "Ljusgrå lumenfärgboll",
"item.appliedenergistics2.light_gray_paint_ball": "Ljusgrå färgboll",
"item.appliedenergistics2.light_gray_smart_cable": "Ljusgrå smart ME-kabel",
"item.appliedenergistics2.light_gray_smart_dense_cable": "Ljusgrå kompakt smart ME-kabel",
"item.appliedenergistics2.light_p2p_tunnel": "P2P-tunnel för ljus",
"item.appliedenergistics2.lime_covered_cable": "Limegrön täckt ME-kabel",
"item.appliedenergistics2.lime_covered_dense_cable": "Limegrön kompakt täckt ME-kabel",
"item.appliedenergistics2.lime_glass_cable": "Limegrön ME-glaskabel",
"item.appliedenergistics2.lime_lumen_paint_ball": "Limegrön lumenfärgboll",
"item.appliedenergistics2.lime_paint_ball": "Limegrön färgboll",
"item.appliedenergistics2.lime_smart_cable": "Limegrön smart ME-kabel",
"item.appliedenergistics2.lime_smart_dense_cable": "Limegrön kompakt smart ME-kabel",
"item.appliedenergistics2.logic_processor": "Logikprocessor",
"item.appliedenergistics2.logic_processor_asm": "Ofärdig logikprocessor",
"item.appliedenergistics2.logic_processor_press": "Logikpressform",
"item.appliedenergistics2.printed_logic_processor": "Pressad logikkrets",
"item.appliedenergistics2.magenta_covered_cable": "Ljuslila täckt ME-kabel",
"item.appliedenergistics2.magenta_covered_dense_cable": "Ljuslila kompakt täckt ME-kabel",
"item.appliedenergistics2.magenta_glass_cable": "Ljuslila ME-glaskabel",
"item.appliedenergistics2.magenta_lumen_paint_ball": "Ljuslila lumenfärgboll",
"item.appliedenergistics2.magenta_paint_ball": "Ljuslila färgboll",
"item.appliedenergistics2.magenta_smart_cable": "Ljuslila smart ME-kabel",
"item.appliedenergistics2.magenta_smart_dense_cable": "Ljuslila kompakt smart ME-kabel",
"item.appliedenergistics2.matter_ball": "Materiaboll",
"item.appliedenergistics2.matter_cannon": "Materiakanon",
"item.appliedenergistics2.me_p2p_tunnel": "P2P-tunnel för ME",
"item.appliedenergistics2.memory_card": "Minneskort",
"item.appliedenergistics2.monitor": "Ljus upplyst panel",
"item.appliedenergistics2.name_press": "Namnpressform",
"item.appliedenergistics2.nether_quartz_axe": "Netherkvartsyxa",
"item.appliedenergistics2.nether_quartz_cutting_knife": "Netherkvartskniv",
"item.appliedenergistics2.nether_quartz_dust": "Netherkvartsdamm",
"item.appliedenergistics2.nether_quartz_hoe": "Netherkvartsflåhacka",
"item.appliedenergistics2.nether_quartz_pickaxe": "Netherkvartshacka",
"item.appliedenergistics2.nether_quartz_seed": "Netherkvartsfrö",
"item.appliedenergistics2.nether_quartz_shovel": "Netherkvartsspade",
"item.appliedenergistics2.nether_quartz_sword": "Netherkvartssvärd",
"item.appliedenergistics2.nether_quartz_wrench": "Netherkvartsblocknyckel",
"item.appliedenergistics2.network_tool": "Nätverksverktyg",
"item.appliedenergistics2.orange_covered_cable": "Orange täckt ME-kabel",
"item.appliedenergistics2.orange_covered_dense_cable": "Orange kompakt täckt ME-kabel",
"item.appliedenergistics2.orange_glass_cable": "Orange smart ME-kabel",
"item.appliedenergistics2.orange_lumen_paint_ball": "Orange lumenfärgboll",
"item.appliedenergistics2.orange_paint_ball": "Orange färgboll",
"item.appliedenergistics2.orange_smart_cable": "Orange smart ME-kabel",
"item.appliedenergistics2.orange_smart_dense_cable": "Orange kompakt smart ME-kabel",
"item.appliedenergistics2.pattern_terminal": "ME-mönsterterminal",
"item.appliedenergistics2.pink_covered_cable": "Rosa täckt ME-kabel",
"item.appliedenergistics2.pink_covered_dense_cable": "Rosa kompakt täckt ME-kabel",
"item.appliedenergistics2.pink_glass_cable": "Rosa ME-glaskabel",
"item.appliedenergistics2.pink_lumen_paint_ball": "Rosa lumenfärgboll",
"item.appliedenergistics2.pink_paint_ball": "Rosa färgboll",
"item.appliedenergistics2.pink_smart_cable": "Rosa smart ME-kabel",
"item.appliedenergistics2.pink_smart_dense_cable": "Rosa kompakt smart ME-kabel",
"item.appliedenergistics2.portable_cell": "Portabel cell",
"item.appliedenergistics2.purified_certus_quartz_crystal": "Ren certuskvartskristall",
"item.appliedenergistics2.purified_fluix_crystal": "Ren fluixkristall",
"item.appliedenergistics2.purified_nether_quartz_crystal": "Ren netherkvartskristall",
"item.appliedenergistics2.purple_covered_cable": "Lila täckt ME-kabel",
"item.appliedenergistics2.purple_covered_dense_cable": "Lila kompakt täckt ME-kabel",
"item.appliedenergistics2.purple_glass_cable": "Lila ME-glaskabel",
"item.appliedenergistics2.purple_lumen_paint_ball": "Lila lumenfärgboll",
"item.appliedenergistics2.purple_paint_ball": "Lila färgboll",
"item.appliedenergistics2.purple_smart_cable": "Lila smart ME-kabel",
"item.appliedenergistics2.purple_smart_dense_cable": "Lila kompakt smart ME-kabel",
"item.appliedenergistics2.quantum_entangled_singularity": "Kvantumbunden singularitet",
"item.appliedenergistics2.quartz_fiber": "Kvartsfiber",
"item.appliedenergistics2.red_covered_cable": "Röd täckt ME-kabel",
"item.appliedenergistics2.red_covered_dense_cable": "Röd kompakt täckt ME-kabel",
"item.appliedenergistics2.red_glass_cable": "Röd ME-glaskabel",
"item.appliedenergistics2.red_lumen_paint_ball": "Röd lumenfärgboll",
"item.appliedenergistics2.red_paint_ball": "Röd färgboll",
"item.appliedenergistics2.red_smart_cable": "Röd smart ME-kabel",
"item.appliedenergistics2.red_smart_dense_cable": "Röd kompakt smart ME-kabel",
"item.appliedenergistics2.redstone_card": "Redstonekort",
"item.appliedenergistics2.redstone_p2p_tunnel": "P2P-tunnel för redstone",
"item.appliedenergistics2.semi_dark_monitor": "Upplyst panel",
"item.appliedenergistics2.silicon": "Silikon",
"item.appliedenergistics2.silicon_press": "Silikonpressform",
"item.appliedenergistics2.printed_silicon": "Pressat silikon",
"item.appliedenergistics2.singularity": "Singularitet",
"item.appliedenergistics2.sky_dust": "Himmelstensdamm",
"item.appliedenergistics2.128_cubed_spatial_cell_component": "Spatial komponent (128³)",
"item.appliedenergistics2.16_cubed_spatial_cell_component": "Spatial komponent (16³)",
"item.appliedenergistics2.2_cubed_spatial_cell_component": "Spatial komponent (2³)",
"item.appliedenergistics2.128_cubed_spatial_storage_cell": "Spatial lagringscell (128³)",
"item.appliedenergistics2.16_cubed_spatial_storage_cell": "Spatial lagringscell (16³)",
"item.appliedenergistics2.2_cubed_spatial_storage_cell": "Spatial lagringscell (2³)",
"item.appliedenergistics2.speed_card": "Accelereringskort",
"item.appliedenergistics2.storage_bus": "ME-lagringsbuss",
"item.appliedenergistics2.16k_storage_cell": "ME-lagringscell (16k)",
"item.appliedenergistics2.1k_storage_cell": "ME-lagringscell (1k)",
"item.appliedenergistics2.4k_storage_cell": "ME-lagringscell (4k)",
"item.appliedenergistics2.64k_storage_cell": "ME-lagringscell (64k)",
"item.appliedenergistics2.storage_monitor": "ME-lagringsskärm",
"item.appliedenergistics2.terminal": "ME-terminal",
"item.appliedenergistics2.toggle_bus": "ME-strömbrytarbuss",
"item.appliedenergistics2.view_cell": "Visningscell",
"item.appliedenergistics2.white_covered_cable": "Vit täckt ME-kabel",
"item.appliedenergistics2.white_covered_dense_cable": "Vit kompakt täckt ME-kabel",
"item.appliedenergistics2.white_glass_cable": "Vit ME-glaskabel",
"item.appliedenergistics2.white_lumen_paint_ball": "Vit lumenfärgboll",
"item.appliedenergistics2.white_paint_ball": "Vit färgboll",
"item.appliedenergistics2.white_smart_cable": "Vit smart ME-kabel",
"item.appliedenergistics2.white_smart_dense_cable": "Vit kompakt smart ME-kabel",
"item.appliedenergistics2.wireless_booster": "Trådlös förstärkning",
"item.appliedenergistics2.wireless_receiver": "Trådlös mottagare",
"item.appliedenergistics2.wireless_terminal": "Trådlös terminal",
"item.appliedenergistics2.wooden_gear": "Träkugghjul",
"item.appliedenergistics2.yellow_covered_cable": "Gul täckt ME-kabel",
"item.appliedenergistics2.yellow_covered_dense_cable": "Gul kompakt täckt ME-kabel",
"item.appliedenergistics2.yellow_glass_cable": "Gul ME-glaskabel",
"item.appliedenergistics2.yellow_lumen_paint_ball": "Gul lumenfärgboll",
"item.appliedenergistics2.yellow_paint_ball": "Gul färgboll",
"item.appliedenergistics2.yellow_smart_cable": "Gul smart ME-kabel",
"item.appliedenergistics2.yellow_smart_dense_cable": "Gul kompakt smart ME-kabel",
"itemGroup.appliedenergistics2": "Applied Energistics 2",
"itemGroup.appliedenergistics2.facades": "Applied Energistics 2 - Fasader",
"key.appliedenergistics2.category": "Applied Energistics 2",
"key.toggle_focus.desc": "Växla fokus för sökfältet",
"stat.appliedenergistics2.items_extracted": "Extraherade föremål från ME-lagringar",
"stat.appliedenergistics2.items_inserted": "Inmatade föremål i ME-lagringar",
"stat.appliedenergistics2.turned_cranks": "Vridna vevar",
"theoneprobe.appliedenergistics2.channels": "%1$d av %2$d kanaler",
"theoneprobe.appliedenergistics2.contains": "Innehåller",
"theoneprobe.appliedenergistics2.crafting": "Tillverkar: %1$s",
"theoneprobe.appliedenergistics2.device_missing_channel": "Enheten saknar kanal",
"theoneprobe.appliedenergistics2.device_offline": "Enheten är frånkopplad",
"theoneprobe.appliedenergistics2.device_online": "Enheten är uppkopplad",
"theoneprobe.appliedenergistics2.locked": "Låst",
"theoneprobe.appliedenergistics2.p2p_frequency": "Frekvens: %1$s",
"theoneprobe.appliedenergistics2.p2p_input_many_outputs": "Länkad (inmatningssida) - %d utmatningar",
"theoneprobe.appliedenergistics2.p2p_input_one_output": "Länkad (inmatningssida)",
"theoneprobe.appliedenergistics2.p2p_output": "Länkad (utmatningssida)",
"theoneprobe.appliedenergistics2.p2p_unlinked": "Olänkad",
"theoneprobe.appliedenergistics2.showing": "Visas",
"theoneprobe.appliedenergistics2.stored_energy": "%1$d / %2$d",
"theoneprobe.appliedenergistics2.unlocked": "Upplåst",
"waila.appliedenergistics2.Channels": "%1$d av %2$d kanaler",
"waila.appliedenergistics2.Contains": "Innehåller",
"waila.appliedenergistics2.Crafting": "Tillverkning",
"waila.appliedenergistics2.DeviceMissingChannel": "Enheten saknar kanal",
"waila.appliedenergistics2.DeviceOffline": "Enheten är frånkopplad",
"waila.appliedenergistics2.DeviceOnline": "Enheten är uppkopplad",
"waila.appliedenergistics2.Locked": "Låst",
"waila.appliedenergistics2.P2PInputManyOutputs": "Länkad (inmatningssida) - %d utmatningar",
"waila.appliedenergistics2.P2PInputOneOutput": "Länkad (inmatningssida)",
"waila.appliedenergistics2.P2POutput": "Länkad (utmatningssida)",
"waila.appliedenergistics2.P2PUnlinked": "Olänkad",
"waila.appliedenergistics2.Showing": "Visas",
"waila.appliedenergistics2.Unlocked": "Upplåst"
}
@@ -1,12 +1,109 @@
{
"parent": "block/cube",
"credit": "Made with Blockbench",
"textures": {
"particle": "appliedenergistics2:block/chest/side",
"4": "appliedenergistics2:block/drive/drive_inside",
"up": "appliedenergistics2:block/chest/top",
"down": "appliedenergistics2:block/chest/bottom",
"north": "appliedenergistics2:block/chest/front",
"east": "appliedenergistics2:block/chest/side",
"south": "appliedenergistics2:block/chest/side",
"west": "appliedenergistics2:block/chest/side"
}
"particle": "appliedenergistics2:block/chest/side",
"east": "appliedenergistics2:block/chest/side"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": { "uv": [0, 0, 16, 16], "texture": "#north" },
"east": { "uv": [0, 0, 16, 16], "texture": "#east" },
"south": { "uv": [0, 0, 16, 16], "texture": "#east" },
"west": { "uv": [0, 0, 16, 16], "texture": "#east" },
"up": { "uv": [0, 0, 16, 16], "texture": "#up" },
"down": { "uv": [0, 0, 16, 16], "texture": "#down" }
}
},
{
"name": "inside_back",
"from": [5, 4, 7],
"to": [11, 7, 10],
"rotation": { "angle": 0, "axis": "y", "origin": [19, 11, 8] },
"faces": {
"north": { "uv": [4, 1, 16, 14], "texture": "#4" }
}
},
{
"name": "inside_left",
"from": [11, 1, 1],
"to": [14, 12, 11],
"rotation": { "angle": 0, "axis": "y", "origin": [18, 11, 3] },
"faces": {
"north": { "uv": [2, 5, 2, 5], "texture": "#4" },
"west": { "uv": [5, 1, 14, 12], "texture": "#4" }
}
},
{
"name": "inside_top",
"from": [5, 6, 1],
"to": [11, 9, 11],
"rotation": { "angle": 0, "axis": "y", "origin": [15, 16, 3] },
"faces": {
"north": { "uv": [2, 7, 2, 7], "texture": "#4" },
"down": { "uv": [6, 4, 6, 4], "texture": "#4" }
}
},
{
"name": "inside_bottom",
"from": [5, 1, 1],
"to": [11, 4, 11],
"rotation": { "angle": 0, "axis": "y", "origin": [15, 11, 3] },
"faces": {
"north": { "uv": [2, 7, 2, 7], "texture": "#4" },
"up": { "uv": [6, 3, 6, 3], "texture": "#4" }
}
},
{
"name": "inside_border_bottom",
"from": [4, 0, 0],
"to": [12, 3, 9],
"rotation": { "angle": 0, "axis": "y", "origin": [15, 10, 1] },
"faces": {
"up": { "uv": [0, 4, 9, 13], "rotation": 90, "texture": "#4" }
}
},
{
"name": "inside_border_top",
"from": [5, 7, 0],
"to": [12, 10, 9],
"rotation": { "angle": 0, "axis": "y", "origin": [15, 17, 1] },
"faces": {
"down": { "uv": [0, 4, 9, 13], "rotation": 270, "texture": "#4" }
}
},
{
"name": "inside_border_left",
"from": [11, 3, 0],
"to": [12, 8, 1],
"rotation": { "angle": 0, "axis": "y", "origin": [15, 13, 1] },
"faces": {
"west": { "uv": [0, 8, 1, 13], "texture": "#4" }
}
},
{
"name": "inside_border_right",
"from": [4, 3, 0],
"to": [5, 8, 1],
"rotation": { "angle": 0, "axis": "y", "origin": [8, 13, 1] },
"faces": {
"east": { "uv": [0, 6, 1, 11], "rotation": 180, "texture": "#4" }
}
},
{
"name": "inside_right",
"from": [2, 1, 1],
"to": [5, 12, 11],
"rotation": { "angle": 0, "axis": "y", "origin": [9, 11, 3] },
"faces": {
"east": { "uv": [5, 2, 14, 13], "texture": "#4" }
}
}
]
}
@@ -1,16 +0,0 @@
{
"textures": {
"state": "appliedenergistics2:block/chest/cell_state_empty"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state"
}
}
}
]
}
@@ -1,31 +0,0 @@
{
"loader": "appliedenergistics2:uvlightmap",
"textures": {
"backdrop": "appliedenergistics2:block/chest/cell_state_backdrop",
"state": "appliedenergistics2:block/chest/cell_state_full"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#backdrop"
}
}
},
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state",
"uvlightmap": {
"block": 0.007,
"sky": 0.007
}
}
}
}
]
}
@@ -1,31 +0,0 @@
{
"loader": "appliedenergistics2:uvlightmap",
"textures": {
"backdrop": "appliedenergistics2:block/chest/cell_state_backdrop",
"state": "appliedenergistics2:block/chest/cell_state_not_empty"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#backdrop"
}
}
},
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state",
"uvlightmap": {
"block": 0.007,
"sky": 0.007
}
}
}
}
]
}
@@ -1,16 +0,0 @@
{
"textures": {
"state": "appliedenergistics2:block/chest/cell_state_offline"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state"
}
}
}
]
}
@@ -1,31 +0,0 @@
{
"loader": "appliedenergistics2:uvlightmap",
"textures": {
"backdrop": "appliedenergistics2:block/chest/cell_state_backdrop",
"state": "appliedenergistics2:block/chest/cell_state_online"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#backdrop"
}
}
},
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state",
"uvlightmap": {
"block": 0.007,
"sky": 0.007
}
}
}
}
]
}
@@ -1,31 +0,0 @@
{
"loader": "appliedenergistics2:uvlightmap",
"textures": {
"backdrop": "appliedenergistics2:block/chest/cell_state_backdrop",
"state": "appliedenergistics2:block/chest/cell_state_types_full"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#backdrop"
}
}
},
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {
"texture": "#state",
"uvlightmap": {
"block": 0.007,
"sky": 0.007
}
}
}
}
]
}
@@ -1,12 +1,13 @@
{
"ambientocclusion": false,
"textures": {
"cell": "appliedenergistics2:block/drive/cells/default_cell"
},
"elements": [
{
"name": "Cell Backdrop",
"from": [9, 13, 1],
"to": [15, 15, 3],
"from": [0, 0, 0],
"to": [6, 2, 2],
"rotation": { "angle": 0, "axis": "y", "origin": [9, 8, 8] },
"faces": {
"north": {
@@ -1,55 +0,0 @@
{
"loader": "appliedenergistics2:uvlightmap",
"textures": {
"front": "appliedenergistics2:block/drive/drive/cell_state_offline"
},
"elements": [
{
"name": "Cell Light",
"from": [9.0, 13.0, 0.0],
"to": [14.0, 15.0, 1.0],
"faces": {
"north": {
"texture": "#front",
"uv": [0, 0, 16, 16],
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
},
"up": {
"texture": "#front",
"uv": [0, 0, 16, 16],
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
},
"down": {
"texture": "#front",
"uv": [0, 0, 16, 16],
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
},
"west": {
"texture": "#front",
"uv": [0, 0, 16, 16],
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
},
"east": {
"texture": "#front",
"uv": [0, 0, 16, 16],
"uvlightmap": {
"sky": 0.007,
"block": 0.007
}
}
}
}
]
}
@@ -4,8 +4,8 @@
"particle": "appliedenergistics2:block/wireless_access_point_inside",
"inside": "appliedenergistics2:block/wireless_access_point_inside",
"1": "appliedenergistics2:block/wireless_access_point",
"sides": "appliedenergistics2:parts/monitor_sides",
"sidesStatus": "appliedenergistics2:parts/monitor_sides_status"
"sides": "appliedenergistics2:part/monitor_sides",
"sidesStatus": "appliedenergistics2:part/monitor_sides_status"
},
"elements": [
{
@@ -1,6 +1,6 @@
{
"textures": {
"indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel"
"indicator": "appliedenergistics2:part/monitor_sides_status_has_channel"
},
"elements": [
{
@@ -1,6 +1,6 @@
{
"textures": {
"indicator": "appliedenergistics2:parts/monitor_sides_status_off"
"indicator": "appliedenergistics2:part/monitor_sides_status_off"
},
"elements": [
{
@@ -1,6 +1,6 @@
{
"textures": {
"indicator": "appliedenergistics2:parts/monitor_sides_status_on"
"indicator": "appliedenergistics2:part/monitor_sides_status_on"
},
"elements": [
{
@@ -1,8 +1,8 @@
{
"parent": "appliedenergistics2:item/part_base",
"textures": {
"sides": "appliedenergistics2:parts/plane_sides",
"plane": "appliedenergistics2:item/part/annihilation_plane"
"sides": "appliedenergistics2:part/plane_sides",
"plane": "appliedenergistics2:part/annihilation_plane"
},
"elements": [
{
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/covered_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/covered/black"
"base": "appliedenergistics2:part/cable/covered/black"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/covered_dense_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/dense_covered/black"
"base": "appliedenergistics2:part/cable/dense_covered/black"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/glass_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/glass/black"
"base": "appliedenergistics2:part/cable/glass/black"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/smart_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/smart/black"
"base": "appliedenergistics2:part/cable/smart/black"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/smart_dense_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/dense_smart/black"
"base": "appliedenergistics2:part/cable/dense_smart/black"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/covered_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/covered/blue"
"base": "appliedenergistics2:part/cable/covered/blue"
}
}
@@ -1,6 +1,6 @@
{
"parent": "appliedenergistics2:item/covered_dense_cable_base",
"textures": {
"base": "appliedenergistics2:parts/cable/dense_covered/blue"
"base": "appliedenergistics2:part/cable/dense_covered/blue"
}
}

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