diff --git a/build.gradle b/build.gradle index 4e7e8f7f4..3338f7135 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ import java.nio.file.StandardCopyOption buildscript { repositories { + maven { url = 'https://maven.ntmr.dev/proxy/' } maven { url = 'https://maven.minecraftforge.net/' } maven { url = 'https://plugins.gradle.org/m2' } mavenCentral() @@ -67,6 +68,10 @@ eclipse.classpath.file.whenMerged { cp -> } repositories { + maven { + name = 'Blerg' + url = 'https://maven.ntmr.dev/proxy/' + } maven { name = 'ModMaven' url = 'https://modmaven.dev' diff --git a/changelog b/changelog index 0a380e1fd..e28799b15 100644 --- a/changelog +++ b/changelog @@ -25,4 +25,5 @@ * Fixed crash caused by the balefire bomb * Fixed JSON gun reload animations becoming faster and faster with the trenchmaster set * Fixed heat transfer rate labels on the boilers and coker unit being off by a magnitude of 10 -* Fixed crucible not having a heat transfer rate tooltip \ No newline at end of file +* Fixed crucible not having a heat transfer rate tooltip +* Fixed certain heliostat mirror rotations not showing the mirror \ No newline at end of file diff --git a/src/main/java/com/hbm/inventory/gui/GUICalculator.java b/src/main/java/com/hbm/inventory/gui/GUICalculator.java index a8816e188..9ac4bbda0 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICalculator.java +++ b/src/main/java/com/hbm/inventory/gui/GUICalculator.java @@ -1,23 +1,29 @@ package com.hbm.inventory.gui; -import com.hbm.lib.RefStrings; +import com.hbm.util.Tuple; + import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; -import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; import java.math.BigDecimal; import java.math.MathContext; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; import java.util.Locale; import java.util.Stack; public class GUICalculator extends GuiScreen { - private static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID, "textures/gui/calculator.png"); private int xSize = 220; private int ySize = 50; + private int borderWidth = 2; private GuiTextField inputField; + private int selectedHist = -1; + private static final int maxHistory = 6; + private static Deque> history = new ArrayDeque<>(); private String latestResult = "?"; @Override @@ -46,15 +52,31 @@ public class GUICalculator extends GuiScreen { String input = inputField.getText().replaceAll("[^\\d+\\-*/^!.()\\sA-Za-z]+", ""); if (p_73869_1_ == 13 || p_73869_1_ == 10) { // when pressing enter (CR or LF) - try { - double result = evaluateExpression(input); - String plainStringRepresentation = (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString(); - GuiScreen.setClipboardString(plainStringRepresentation); - inputField.setText(plainStringRepresentation); - inputField.setCursorPositionEnd(); - inputField.setSelectionPos(0); - } catch (Exception ignored) {} - return; + if (selectedHist != -1) { + input = new ArrayList<>(history).get(selectedHist).key; + inputField.setText(input); + selectedHist = -1; + } else { + try { + double result = evaluateExpression(input); + history.addFirst(new Tuple.Pair(input, result)); + if (history.size() > maxHistory) history.removeLast(); + String plainStringRepresentation = (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString(); + GuiScreen.setClipboardString(plainStringRepresentation); + inputField.setText(plainStringRepresentation); + inputField.setCursorPositionEnd(); + inputField.setSelectionPos(0); + } catch (Exception ignored) {} + return; + } + } + + if (p_73869_2_ == 200) { // up arrow + selectedHist = Math.max(selectedHist - 1, -1); + } else if (p_73869_2_ == 208) { // down arrow + selectedHist = Math.min(selectedHist + 1, history.size() - 1); + } else { + selectedHist = -1; } if (input.isEmpty()) { @@ -72,14 +94,27 @@ public class GUICalculator extends GuiScreen { super.drawScreen(mouseX, mouseY, partialTicks); GL11.glColor4f(1F, 1F, 1F, 1F); - mc.getTextureManager().bindTexture(texture); int x = (width - xSize) / 2; int y = (height - ySize) / 2; + int histHeight = (fontRendererObj.FONT_HEIGHT + 2) * maxHistory; + int histStart = y + 30 + fontRendererObj.FONT_HEIGHT + 8; - drawTexturedModalRect(x, y, 0, 0, xSize, ySize); + drawRect(x, y, x+xSize, y+ySize+histHeight, 0xFF2d2d2d); + drawRect(x+borderWidth, y+borderWidth, x+xSize-borderWidth, y+ySize-borderWidth+histHeight, 0xFF3d3d3d); + drawRect(x, histStart - 5, x+xSize, histStart - 3, 0xFF2d2d2d); inputField.drawTextBox(); fontRendererObj.drawString("=" + latestResult, x + 5, y + 30, -1); + + int i = 0; + for (Tuple.Pair prevInput : history) { + int hy = y + 50 + (fontRendererObj.FONT_HEIGHT+1)*i; + if (i == selectedHist) { + drawRect(x + 4, hy - 1, x + 4 + xSize - 9, hy + fontRendererObj.FONT_HEIGHT, 0xFF111111); + } + fontRendererObj.drawString(prevInput.key + " = " + prevInput.value, x + 5, hy, -1); + i++; + } } /** diff --git a/src/main/java/com/hbm/render/block/RenderMirror.java b/src/main/java/com/hbm/render/block/RenderMirror.java index 957512f0d..1b0b4de33 100644 --- a/src/main/java/com/hbm/render/block/RenderMirror.java +++ b/src/main/java/com/hbm/render/block/RenderMirror.java @@ -66,17 +66,15 @@ public class RenderMirror implements ISimpleBlockRenderingHandler { GroupObject go = null; for(GroupObject obj : ((WavefrontObject)ResourceManager.solar_mirror).groupObjects) { - if(obj.name.equals("Mirror")) - go = obj; + if(obj.name.equals("Mirror")) go = obj; } - if(go == null) - return; + if(go == null) return; Tessellator tes = Tessellator.instance; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - double pitch = -Math.asin((dy + 0.5) / dist) + Math.PI / 2D; + double pitch = -Math.asin(dy / dist) + Math.PI / 2D; double yaw = -Math.atan2(dz, dx) - Math.PI / 2D; for(Face f : go.faces) { diff --git a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java index c07254103..aac5d52a7 100644 --- a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java +++ b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java @@ -2,6 +2,7 @@ package com.hbm.uninos.networkproviders; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -34,11 +35,11 @@ public class PneumaticNetwork extends NodeNet { protected static final int timeout = 1_000; public static final int ITEMS_PER_TRANSFER = 64; - + // while the system has parts that expects IInventires to be TileEntities to work properly (mostly range checks), // it can actually handle non-TileEntities just fine. public HashMap> receivers = new HashMap(); - + public void addReceiver(IInventory inventory, ForgeDirection pipeDir, TileEntityPneumoTube endpoint) { receivers.put(inventory, new Triplet(pipeDir, System.currentTimeMillis(), endpoint)); } @@ -51,7 +52,7 @@ public class PneumaticNetwork extends NodeNet { long timestamp = System.currentTimeMillis(); receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getY() > timeout) || NodeNet.isBadLink(x.getKey()); }); } - + public boolean send(IInventory source, TileEntityPneumoTube tube, ForgeDirection accessDir, int sendOrder, int receiveOrder, int maxRange, int nextReceiver) { // turns out there may be a short time window where the cleanup hasn't happened yet, but chunkloading has already caused tiles to go invalid @@ -67,114 +68,144 @@ public class PneumaticNetwork extends NodeNet { if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess); if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess); + ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null; + boolean hasItem = false; + + for(int i : sourceSlotAccess) { + ItemStack stack = source.getStackInSlot(i); + if(stack != null) { + if(sidedSource != null && !sidedSource.canExtractItem(i, stack, sourceSide)) continue; + boolean match = tube.matchesFilter(stack); + if((match && !tube.whitelist) || (!match && tube.whitelist)) continue; + hasItem = true; + break; + } + } + + // return early if there arent any items in the source inventory, saves on some cpu usage for idle networks + if(!hasItem) return false; + // for round robin, receivers are ordered by proximity to the source ReceiverComparator comparator = new ReceiverComparator(tube); List>> receiverList = new ArrayList(receivers.size()); receiverList.addAll(receivers.entrySet()); - receiverList.sort(comparator); - - int index = nextReceiver % receivers.size(); - Entry> chosenReceiverEntry = null; - if(receiveOrder == RECEIVE_ROBIN) chosenReceiverEntry = receiverList.get(index); - if(receiveOrder == RECEIVE_RANDOM) chosenReceiverEntry = receiverList.get(rand.nextInt(receiverList.size())); - - if(chosenReceiverEntry == null) return false; - - IInventory dest = chosenReceiverEntry.getKey(); - TileEntityPneumoTube endpointTile = chosenReceiverEntry.getValue().getZ(); - ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null; - ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null; - + if(receiveOrder == RECEIVE_ROBIN) receiverList.sort(comparator); + if(receiveOrder == RECEIVE_RANDOM) Collections.shuffle(receiverList); + TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null; - TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null; - - // range check for our compression level, skip if either source or dest aren't tile entities - if(tile1 != null && tile2 != null) { - int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord); - if(sq > maxRange * maxRange) { - return false; - } - } - - int destSide = chosenReceiverEntry.getValue().getX().getOpposite().ordinal(); - int[] destSlotAccess = getSlotAccess(dest, destSide); - int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size - int itemHardCap = dest instanceof TileEntityMachineAutocrafter ? 1 : ITEMS_PER_TRANSFER; - boolean didSomething = false; - - for(int sourceIndex : sourceSlotAccess) { - ItemStack sourceStack = source.getStackInSlot(sourceIndex); - if(sourceStack == null) continue; - if(sidedSource != null && !sidedSource.canExtractItem(sourceIndex, sourceStack, sourceSide)) continue; - // filter of the source - boolean match = tube.matchesFilter(sourceStack); - if((match && !tube.whitelist) || (!match && tube.whitelist)) continue; - // filter of the receiver, only if the sender and receiver aren't the same block - if(endpointTile != null && endpointTile != tube) { - match = endpointTile.matchesFilter(sourceStack); - if((match && !endpointTile.whitelist) || (!match && endpointTile.whitelist)) continue; - } - // the "mass" of an item. something that only stacks to 4 has a "mass" of 16. max transfer mass is 64, i.e. one standard stack, or one single unstackable item - int proportionalValue = MathHelper.clamp_int(64 / sourceStack.getMaxStackSize(), 1, 64); - - // try to fill partial stacks first - for(int destIndex : destSlotAccess) { - ItemStack destStack = dest.getStackInSlot(destIndex); - if(destStack == null) continue; - if(!ItemStackUtil.areStacksCompatible(sourceStack, destStack)) continue; - int toMove = BobMathUtil.min(sourceStack.stackSize, destStack.getMaxStackSize() - destStack.stackSize, dest.getInventoryStackLimit() - destStack.stackSize, itemsLeftToSend / proportionalValue, itemHardCap); - if(toMove <= 0) continue; - - ItemStack checkStack = destStack.copy(); - checkStack.stackSize += toMove; - if(!dest.isItemValidForSlot(destIndex, checkStack)) continue; - if(sidedDest != null && !sidedDest.canInsertItem(destIndex, checkStack, destSide)) continue; - - sourceStack.stackSize -= toMove; - if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); - destStack.stackSize += toMove; - itemsLeftToSend -= toMove * proportionalValue; - didSomething = true; - if(itemsLeftToSend <= 0) break; - } - - // if there's stuff left to send, occupy empty slots - if(itemsLeftToSend > 0 && sourceStack.stackSize > 0) for(int destIndex : destSlotAccess) { - if(dest.getStackInSlot(destIndex) != null) continue; - int toMove = BobMathUtil.min(sourceStack.stackSize, dest.getInventoryStackLimit(), itemsLeftToSend / proportionalValue, itemHardCap); - if(toMove <= 0) continue; - - ItemStack checkStack = sourceStack.copy(); - checkStack.stackSize = toMove; - if(!dest.isItemValidForSlot(destIndex, checkStack)) continue; - if(sidedDest != null && !sidedDest.canInsertItem(destIndex, checkStack, destSide)) continue; - ItemStack newStack = sourceStack.copy(); - newStack.stackSize = toMove; - sourceStack.stackSize -= toMove; - if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); - dest.setInventorySlotContents(destIndex, newStack); - itemsLeftToSend -= toMove * proportionalValue; - didSomething = true; + int attempts = 0; + int maxAttempts = receiverList.size(); + + // try all receivers for both modes, in an attempts based system. + // instead of bailing out of trying after the first failure (which means you have to wait 0.25 seconds), we just try the next one. + while(attempts < maxAttempts) { + int index = (receiveOrder == RECEIVE_ROBIN) ? (nextReceiver + attempts) % receiverList.size() : attempts; + + Entry> candidate = receiverList.get(index); + + if(NodeNet.isBadLink(candidate.getKey())) { + receivers.remove(candidate.getKey()); + attempts++; + continue; + } + + IInventory dest = candidate.getKey(); + TileEntityPneumoTube endpointTile = candidate.getValue().getZ(); + TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null; + + // range check for our compression level, skip if either source or dest aren't tile entities + if(tile1 != null && tile2 != null) { + int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord); + if(sq > maxRange * maxRange) { + attempts++; + continue; + } + } + + ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null; + int destSide = candidate.getValue().getX().getOpposite().ordinal(); + int[] destSlotAccess = getSlotAccess(dest, destSide); + int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size + int itemHardCap = dest instanceof TileEntityMachineAutocrafter ? 1 : ITEMS_PER_TRANSFER; + boolean didSomething = false; + + for(int sourceIndex : sourceSlotAccess) { + ItemStack sourceStack = source.getStackInSlot(sourceIndex); + if(sourceStack == null) continue; + if(sidedSource != null && !sidedSource.canExtractItem(sourceIndex, sourceStack, sourceSide)) continue; + // filter of the source + boolean match = tube.matchesFilter(sourceStack); + if((match && !tube.whitelist) || (!match && tube.whitelist)) continue; + // filter of the receiver, only if the sender and receiver aren't the same block + if(endpointTile != null && endpointTile != tube) { + match = endpointTile.matchesFilter(sourceStack); + if((match && !endpointTile.whitelist) || (!match && endpointTile.whitelist)) continue; + } + // the "mass" of an item. something that only stacks to 4 has a "mass" of 16. max transfer mass is 64, i.e. one standard stack, or one single unstackable item + int proportionalValue = MathHelper.clamp_int(64 / sourceStack.getMaxStackSize(), 1, 64); + + // try to fill partial stacks first + for(int destIndex : destSlotAccess) { + ItemStack destStack = dest.getStackInSlot(destIndex); + if(destStack == null) continue; + if(!ItemStackUtil.areStacksCompatible(sourceStack, destStack)) continue; + int toMove = BobMathUtil.min(sourceStack.stackSize, destStack.getMaxStackSize() - destStack.stackSize, dest.getInventoryStackLimit() - destStack.stackSize, itemsLeftToSend / proportionalValue, itemHardCap); + if(toMove <= 0) continue; + + ItemStack checkStack = destStack.copy(); + checkStack.stackSize += toMove; + if(!dest.isItemValidForSlot(destIndex, checkStack)) continue; + if(sidedDest != null && !sidedDest.canInsertItem(destIndex, checkStack, destSide)) continue; + + sourceStack.stackSize -= toMove; + if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); + destStack.stackSize += toMove; + itemsLeftToSend -= toMove * proportionalValue; + didSomething = true; + if(itemsLeftToSend <= 0) break; + } + + // if there's stuff left to send, occupy empty slots + if(itemsLeftToSend > 0 && sourceStack.stackSize > 0) for(int destIndex : destSlotAccess) { + if(dest.getStackInSlot(destIndex) != null) continue; + int toMove = BobMathUtil.min(sourceStack.stackSize, dest.getInventoryStackLimit(), itemsLeftToSend / proportionalValue, itemHardCap); + if(toMove <= 0) continue; + + ItemStack checkStack = sourceStack.copy(); + checkStack.stackSize = toMove; + if(!dest.isItemValidForSlot(destIndex, checkStack)) continue; + if(sidedDest != null && !sidedDest.canInsertItem(destIndex, checkStack, destSide)) continue; + + ItemStack newStack = sourceStack.copy(); + newStack.stackSize = toMove; + sourceStack.stackSize -= toMove; + if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null); + dest.setInventorySlotContents(destIndex, newStack); + itemsLeftToSend -= toMove * proportionalValue; + didSomething = true; + if(itemsLeftToSend <= 0) break; + } + if(itemsLeftToSend <= 0) break; } - - if(itemsLeftToSend <= 0) break; + + // make sure both parties are saved to disk and increment the counter for round robin + if(didSomething) { + source.markDirty(); + dest.markDirty(); + return true; + } + + attempts++; } - - // make sure both parties are saved to disk and increment the counter for round robin - if(didSomething) { - source.markDirty(); - dest.markDirty(); - } - - return didSomething; + return false; } - + /** Returns an array of accessible slots from the given side of an IInventory. If it's an ISidedInventory, uses the sided restrictions instead. */ public static int[] getSlotAccess(IInventory inventory, int dir) { - + if(inventory instanceof ISidedInventory) { int[] slotAccess = ((ISidedInventory) inventory).getAccessibleSlotsFromSide(dir); return Arrays.copyOf(slotAccess, slotAccess.length); //we mess with the order, so better not use the original array @@ -184,12 +215,12 @@ public class PneumaticNetwork extends NodeNet { return slotAccess; } } - + /** Compares IInventory by distance, going off the assumption that they are TileEntities. Uses positional data for tie-breaking if the distance is the same. */ public static class ReceiverComparator implements Comparator>> { - + private TileEntityPneumoTube origin; - + public ReceiverComparator(TileEntityPneumoTube origin) { this.origin = origin; } @@ -204,11 +235,11 @@ public class PneumaticNetwork extends NodeNet { if(tile1 == null && tile2 != null) return 1; if(tile1 != null && tile2 == null) return -1; if(tile1 == null && tile2 == null) return 0; - + // calculate distances from origin int dist1 = (tile1.xCoord - origin.xCoord) * (tile1.xCoord - origin.xCoord) + (tile1.yCoord - origin.yCoord) * (tile1.yCoord - origin.yCoord) + (tile1.zCoord - origin.zCoord) * (tile1.zCoord - origin.zCoord); int dist2 = (tile2.xCoord - origin.xCoord) * (tile2.xCoord - origin.xCoord) + (tile2.yCoord - origin.yCoord) * (tile2.yCoord - origin.yCoord) + (tile2.zCoord - origin.zCoord) * (tile2.zCoord - origin.zCoord); - + // tier-breaker: use hash value instead if(dist1 == dist2) { return TileEntityPneumoTube.getIdentifier(tile1.xCoord, tile1.yCoord, tile1.zCoord) - TileEntityPneumoTube.getIdentifier(tile2.xCoord, tile2.yCoord, tile2.zCoord); diff --git a/src/main/resources/assets/hbm/lang/ru_RU.lang b/src/main/resources/assets/hbm/lang/ru_RU.lang index 849ae90ec..d4bd8a17e 100644 --- a/src/main/resources/assets/hbm/lang/ru_RU.lang +++ b/src/main/resources/assets/hbm/lang/ru_RU.lang @@ -2222,16 +2222,16 @@ item.ballistite.name=Баллистит item.bandaid.name=Пластырь Вельвет item.bathwater.name=Токсичная мыльная вода item.bathwater_mk2.name=Токсичная мыльная вода (Лошадиный аромат) -item.battery_advanced.name=Продвинутый аккумулятор -item.battery_advanced_cell.name=Усовершенствованная энергоячейка -item.battery_advanced_cell_12.name=Двенадцатикратный массив из усовершенствованных энергоячеек -item.battery_advanced_cell_4.name=Счетверённая усовершенствованная энергоячейка +item.battery_advanced.name=Продвинутый аккумулятор (LEGACY) +item.battery_advanced_cell.name=Усовершенствованная энергоячейка (LEGACY) +item.battery_advanced_cell_12.name=Двенадцатикратный массив из усовершенствованных энергоячеек (LEGACY) +item.battery_advanced_cell_4.name=Счетверённая усовершенствованная энергоячейка (LEGACY) item.battery_creative.name=Бесконечная батарейка -item.battery_generic.name=Аккумулятор -item.battery_lithium.name=Литий-ионный аккумулятор -item.battery_lithium_cell.name=Литий-ионная энергоячейка -item.battery_lithium_cell_3.name=Строенная литий-ионная энергоячейка -item.battery_lithium_cell_6.name=Сшестерённая литий-ионная энергоячейка +item.battery_generic.name=Аккумулятор (LEGACY) +item.battery_lithium.name=Литий-ионный аккумулятор (LEGACY) +item.battery_lithium_cell.name=Литий-ионная энергоячейка (LEGACY) +item.battery_lithium_cell_3.name=Строенная литий-ионная энергоячейка (LEGACY) +item.battery_lithium_cell_6.name=Сшестерённая литий-ионная энергоячейка (LEGACY) item.battery_pack.battery_lead.name=Свинцово-серная батарея item.battery_pack.battery_lithium.name=Литий-ионная батарея item.battery_pack.battery_quantum.name=Квантовая батарея @@ -2246,30 +2246,33 @@ item.battery_pack.capacitor_spark.name=Спарк-конденсатор item.battery_pack.capacitor_tantalum.name=Танталовый конденсатор item.battery_potato.name=Картофельная батарейка item.battery_potatos.name=КартошкОС -item.battery_red_cell.name=Энергоячейка из красной пыли -item.battery_red_cell_24.name=Двадцатичетырёхкратный массив из краснопыльных энергоячеек -item.battery_red_cell_6.name=Сшестёренная энергоячейка из красной пыли -item.battery_sc_americium.name=Самозаряжающаяся батарея с америцием-241 -item.battery_sc_gold.name=Самозаряжающаяся батарея с золотом-198 -item.battery_sc_lead.name=Самозаряжающаяся батарея со свинцом-209 -item.battery_sc_plutonium.name=Самозаряжающаяся батарея с плутонием-238 -item.battery_sc_polonium.name=Самозаряжающаяся батарея с полонием-210 -item.battery_sc_technetium.name=Самозаряжающаяся батарея с технецием-98 -item.battery_sc_uranium.name=Самозаряжающаяся батарея с ураном-238 -item.battery_schrabidium.name=Шрабидиевая батарея -item.battery_schrabidium_cell.name=Шрабидиевая энергоячейка -item.battery_schrabidium_cell_2.name=Сдвоенная шрабидиевая энергоячейка -item.battery_schrabidium_cell_4.name=Счетверённая шрабидиевая энергоячейка -item.battery_spark.name=Спарк-батарея -item.battery_spark_cell_100.name=Спарк-Магический массив хранения энергии -item.battery_spark_cell_1000.name=Спарк-Магическая масс-энергетическая пустота -item.battery_spark_cell_10000.name=Устойчивый пространственно-временной спарк-кристалл -item.battery_spark_cell_25.name=Спарк-магический аккумулятор -item.battery_spark_cell_2500.name=Спарк-магическое море Дирака -item.battery_spark_cell_6.name=Спарк-энергоячейка -item.battery_spark_cell_power.name=Абсурдный физический спарк-блок накопления энергии -item.battery_steam.name=Паровой бак для хранения энергии -item.battery_steam_large.name=Большой паровой бак для хранения энергии +item.battery_red_cell.name=Энергоячейка из красной пыли (LEGACY) +item.battery_red_cell_24.name=Двадцатичетырёхкратный массив из краснопыльных энергоячеек (LEGACY) +item.battery_red_cell_6.name=Сшестёренная энергоячейка из красной пыли (LEGACY) +item.battery_sc.am241.name=Самозаряжающаяся батарея Америций-241 +item.battery_sc.au198.name=Самозаряжающаяся батарея Золото-198 +item.battery_sc.co60.name=Самозаряжающаяся батарея Кобальт-60 +item.battery_sc.pb209.name=Самозаряжающаяся батарея Свинец-209 +item.battery_sc.po210.name=Самозаряжающаяся батарея Полоний-210 +item.battery_sc.pu238.name=Самозаряжающаяся батарея Плутоний-238 +item.battery_sc.ra226.name=Самозаряжающаяся батарея Радий-226 +item.battery_sc.tc99.name=Самозаряжающаяся батарея Технеций-99 +item.battery_sc.empty.name=Самозаряжающаяся батарея пустая +item.battery_sc.waste.name=Самозаряжающаяся батарея отработаного топлива +item.battery_schrabidium.name=Шрабидиевая батарея (LEGACY) +item.battery_schrabidium_cell.name=Шрабидиевая энергоячейка (LEGACY) +item.battery_schrabidium_cell_2.name=Сдвоенная шрабидиевая энергоячейка (LEGACY) +item.battery_schrabidium_cell_4.name=Счетверённая шрабидиевая энергоячейка (LEGACY) +item.battery_spark.name=Спарк-батарея (LEGACY) +item.battery_spark_cell_100.name=Спарк-Магический массив хранения энергии (LEGACY) +item.battery_spark_cell_1000.name=Спарк-Магическая масс-энергетическая пустота (LEGACY) +item.battery_spark_cell_10000.name=Устойчивый пространственно-временной спарк-кристалл (LEGACY) +item.battery_spark_cell_25.name=Спарк-магический аккумулятор (LEGACY) +item.battery_spark_cell_2500.name=Спарк-магическое море Дирака (LEGACY) +item.battery_spark_cell_6.name=Спарк-энергоячейка (LEGACY) +item.battery_spark_cell_power.name=Абсурдный физический спарк-блок накопления энергии (LEGACY) +item.battery_steam.name=Паровой бак для хранения энергии (LEGACY) +item.battery_steam_large.name=Большой паровой бак для хранения энергии (LEGACY) item.battery_su.name=Одноразовая батарейка item.battery_su_l.name=Большая одноразовая батарейка item.battery_trixite.name=Безымянная спарк-батарея @@ -6017,7 +6020,7 @@ tile.machine_battery_redd.name=ЭМЭХ tile.machine_battery_socket.name=Аккумуляторный массив tile.machine_battery_socket.desc=Позволяет подключать аккумуляторы$напрямую к энергосети.$Выступает в качестве кабеля, все порты$подключены к одной сети. tile.machine_boiler.name=Бойлер -tile.machine_boiler.desc=Большой бойлер для кипячения воды или нагрева нефти.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.01 TU/t +tile.machine_boiler.desc=Большой бойлер для кипячения воды или нагрева нефти.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.1 TU/t tile.machine_boiler_electric_off.name=Электрический нагреватель нефти tile.machine_boiler_electric_on.name=Электрический нагреватель нефти tile.machine_boiler_off.name=Нагревательнефти @@ -6034,7 +6037,7 @@ tile.machine_chungus.desc=Эффективность: 85%% tile.machine_coal_off.name=Генератор внутреннего сгорания tile.machine_coal_on.name=Генератор внутреннего сгорания tile.machine_coker.name=Коксовая установка -tile.machine_coker.desc=Коксует жидкость, создавая жидкую побочку.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.025 TU/t +tile.machine_coker.desc=Коксует жидкость, создавая жидкую побочку.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.25 TU/t tile.machine_combine_factory.name=Печь для стали Альянса tile.machine_combustion_engine.name=Промышленный двигатель внутреннего сгорания tile.machine_compressor.name=Компрессор @@ -6047,6 +6050,7 @@ tile.machine_converter_rf_he.name=Конвертер энергии RF в HE tile.machine_conveyor_press.name=Конвейерный пресс tile.machine_conveyor_press.desc=Лента двигается слева направо$ПКМ, чтобы установить штамп$ПКМ отвёрткой, чтобы снять штамп tile.machine_crucible.name=Плавильня +tile.machine_crucible.desc=Скорость передачи тепла: ΔT*0,25 TU/t tile.machine_crystallizer.name=Рудный окислитель tile.machine_cyclotron.name=Циклотрон tile.machine_detector.name=Детектор мощности @@ -6083,7 +6087,7 @@ tile.machine_hephaestus.name=Геотермальный теплообменик tile.machine_icf_press.name=Топливный пресс ICF tile.machine_icf_press.desc=Наполняет топливные пеллеты ICF$Левый топливный слот принимается сверху/снизу, правый - по бокам$Мюоны и пеллеты могут подаваться с любой стороны tile.machine_industrial_boiler.name=Промышленный бойлер -tile.machine_industrial_boiler.desc=Большой бойлер, в котором можно вскипятить воду или разогреть нефть.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.01 TU/t$Не может взорваться +tile.machine_industrial_boiler.desc=Большой бойлер, в котором можно вскипятить воду или разогреть нефть.$Требует внешний источник тепла.$Скорость передачи тепла: ΔT*0.1 TU/t$Не может взорваться tile.machine_industrial_generator.name=Промышленный генератор tile.machine_intake.name=Воздухозаборник tile.machine_keyforge.name=Стол мастера по замкам @@ -6835,5 +6839,6 @@ desc.gui.upgrade.speed= * §4Скорость§r: Стакается до 3-х + diff --git a/src/main/resources/assets/hbm/textures/gui/calculator.png b/src/main/resources/assets/hbm/textures/gui/calculator.png deleted file mode 100644 index fa6fd968f..000000000 Binary files a/src/main/resources/assets/hbm/textures/gui/calculator.png and /dev/null differ