Merge branch 'HbmMods:master' into rulang121

This commit is contained in:
Raaaaaaaaaay 2026-06-08 20:37:04 +03:00 committed by GitHub
commit 7775915bbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 368 additions and 170 deletions

View File

@ -163,6 +163,9 @@ task sourceJar(type: Jar) {
}
task devJar(type: Jar) {
// hack: artificially depend on the reobf task here to get the normal jar to be overwritten before publishing
dependsOn reobf
from(sourceSets.main.output) {
include "**"
}
@ -212,8 +215,6 @@ if(Files.exists(Paths.get("maven.properties"))) {
artifactId archivesBaseName
version version_name
from components.java
artifact sourceJar {
classifier "src"
}
@ -222,13 +223,7 @@ if(Files.exists(Paths.get("maven.properties"))) {
classifier "dev"
}
pom.withXml {
// NTM doesn't really feature any special runtime dependencies anyone would need, so blast those away
def node = asNode()
def dependencies = node.get("dependencies")
node.remove(dependencies)
node
}
artifact jar
}
}
repositories {

View File

@ -9,10 +9,20 @@
* Renamed "worker's alloy" to "desh" to avoid confusion
* Seriously why did this have two names?
* Industrial grade and minecraft grade copper ingots now have the "ingot" suffix
* Changed the microchip assembler recipe duration so that it matches with the demand of one soldering station
* Blast furnace speed with hot air blast can now be increased to 500% (uses the same amount of hot air blast as before)
## Fixed
* Fixed AUTOCAL's `listen` command failing if the buffer is empty
* AUTOCAL
* Fixed `listen` command failing if the buffer is empty
* Fixed variable substitution failing when there is a trailing $ sign
* Fixed concat prefixing all output with "t " for some reason
* Eval(r) now uses a special mode for variable substitution that forces empty variables to be interpreted as "0"
* Fixed things not intended to be used in the blast furnace (scrap, lava) being usable fuels
* Fixed blast furnace swallowing container items left behind by fuels, instead fuels with containers will not be accepted at all
* Fixed the blast furnace NEI screen listing "0 HE" for every recipe even though it's not an electric machine
* Fixed flue gas not having an inventory texture
* Fixed flue gas not having an inventory texture
* Potentially fixed issue with Angelica where tile entity culling would cause cargo elevators to not render on certain angles
* Fixed the blast furnace not performing stack size checks correctly, outputting items when it shouldn't
* Fixed cargo elevators not rendering past a distance of 100 blocks
* Fixed cargo elevator syncing range being only 100 blocks, meaning that elevators taller than that don't work properly

View File

@ -1,6 +1,6 @@
mod_version=1.0.27
# Empty build number makes a release type
mod_build_number=5714
mod_build_number=5719
credits=HbMinecraft,\
\ rodolphito (explosion algorithms),\

View File

@ -101,10 +101,8 @@ public class StackCache {
}
public void removeMonitor(SlotMonitor monitor) {
System.out.println("Trying to remove...");
if(this.monitors.remove(monitor)) {
this.changeAmounts(-monitor.stacksize);
System.out.println("Removed!");
}
}

View File

@ -63,10 +63,10 @@ public class ArmorRecipes {
CraftingManager.addRecipeAuto(new ItemStack(ModItems.t51_plate, 1), new Object[] { "MPM", "TBT", "PPP", 'M', ModItems.motor, 'P', ModItems.plate_armor_titanium, 'T', ModItems.gas_empty, 'B', ModItems.titanium_plate });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.t51_legs, 1), new Object[] { "MPM", "PBP", "P P", 'M', ModItems.motor, 'P', ModItems.plate_armor_titanium, 'B', ModItems.titanium_legs });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.t51_boots, 1), new Object[] { "P P", "PBP", 'P', ModItems.plate_armor_titanium, 'B', ModItems.titanium_boots });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_helmet, 1), new Object[] { "PPC", "PBP", "IXI", 'P', ModItems.plate_armor_ajr, 'C', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.BASIC), 'I', ANY_PLASTIC.ingot(), 'X', ModItems.gas_mask_m65, 'B', ModItems.alloy_helmet });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_plate, 1), new Object[] { "MPM", "TBT", "PPP", 'M', ModItems.motor_desh, 'P', ModItems.plate_armor_ajr, 'T', ModItems.gas_empty, 'B', ModItems.alloy_plate });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_legs, 1), new Object[] { "MPM", "PBP", "P P", 'M', ModItems.motor_desh, 'P', ModItems.plate_armor_ajr, 'B', ModItems.alloy_legs });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_boots, 1), new Object[] { "P P", "PBP", 'P', ModItems.plate_armor_ajr, 'B', ModItems.alloy_boots });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_helmet, 1), new Object[] { "PPC", "PBP", "IXI", 'P', ModItems.plate_armor_ajr, 'C', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.BASIC), 'I', ANY_PLASTIC.ingot(), 'X', ModItems.gas_mask_m65, 'B', ModItems.titanium_helmet });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_plate, 1), new Object[] { "MPM", "TBT", "PPP", 'M', ModItems.motor_desh, 'P', ModItems.plate_armor_ajr, 'T', ModItems.gas_empty, 'B', ModItems.titanium_plate });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_legs, 1), new Object[] { "MPM", "PBP", "P P", 'M', ModItems.motor_desh, 'P', ModItems.plate_armor_ajr, 'B', ModItems.titanium_legs });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ajr_boots, 1), new Object[] { "P P", "PBP", 'P', ModItems.plate_armor_ajr, 'B', ModItems.titanium_boots });
CraftingManager.addShapelessAuto(new ItemStack(ModItems.ajro_helmet, 1), new Object[] { ModItems.ajr_helmet, KEY_RED, KEY_BLACK });
CraftingManager.addShapelessAuto(new ItemStack(ModItems.ajro_plate, 1), new Object[] { ModItems.ajr_plate, KEY_RED, KEY_BLACK });
CraftingManager.addShapelessAuto(new ItemStack(ModItems.ajro_legs, 1), new Object[] { ModItems.ajr_legs, KEY_RED, KEY_BLACK });

View File

@ -61,10 +61,11 @@ public class GUIBlastFurnace extends GuiInfoContainer {
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
int prog = (int) Math.round(furnace.progress * 88D);
drawTexturedModalRect(guiLeft + 62, guiTop + 106 - prog, 176, 102 - prog, 56, prog);
int fuel = (int) Math.round((double) furnace.fuel * 26D / (double) furnace.MAX_FUEL);
int prog = (int) Math.round(furnace.progress * (88D - fuel));
drawTexturedModalRect(guiLeft + 62, guiTop + 106 - prog - fuel, 176, 102 - prog - fuel, 56, prog);
drawTexturedModalRect(guiLeft + 62, guiTop + 106 - fuel, 176, 128 - fuel, 56, fuel);
if(furnace.isProgressing) {

View File

@ -1,14 +1,21 @@
package com.hbm.inventory.gui;
import java.util.List;
import org.lwjgl.opengl.GL11;
import static com.hbm.inventory.gui.element.GUIElements.*;
import com.hbm.inventory.container.ContainerPneumoStorageAccess;
import com.hbm.inventory.gui.element.GUIElements;
import com.hbm.lib.RefStrings;
import com.hbm.tileentity.network.pneumatic.TileEntityPneumoStorageAccess;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GUIPneumoStorageAccess extends GuiInfoContainer {
@ -48,4 +55,21 @@ public class GUIPneumoStorageAccess extends GuiInfoContainer {
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
}
@Override
protected void renderToolTip(ItemStack stack, int x, int y) {
List list = stack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
for(int line = 0; line < list.size(); ++line) {
if(line == 0) {
list.set(line, stack.getRarity().rarityColor + (String) list.get(line));
} else {
list.set(line, EnumChatFormatting.GRAY + (String) list.get(line));
}
}
FontRenderer font = stack.getItem().getFontRenderer(stack);
if(font == null) font = this.fontRendererObj;
GUIElements.drawHoveringText(list, x, y, font, itemRender, width, height, STANDARD_HEADER_OFFSET, STANDARD_LINE_DIST, STANDARD_COLOR_BACKGROUND, STANDARD_COLOR_BACKGROUND, 0xD57C4F, 0xAB4223);
}
}

View File

@ -121,7 +121,7 @@ public class AssemblyMachineRecipes extends GenericRecipes<GenericRecipe> {
// crafting parts
if(!GeneralConfig.enable528) { // precass otherwise
this.register(new GenericRecipe("ass.chip").setup(100, 250).outputItems(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP))
this.register(new GenericRecipe("ass.chip").setup(50, 250).outputItems(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP))
.inputItems(new ComparableStack(ModItems.plate_polymer), new ComparableStack(ModItems.circuit, 1, EnumCircuitType.SILICON), new OreDictStack(GOLD.wireFine())));
this.register(new GenericRecipe("ass.chipBismoid").setup(100, 1_500).outputItems(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_BISMOID))
.inputItems(new ComparableStack(ModItems.plate_polymer, 2), new ComparableStack(ModItems.circuit, 2, EnumCircuitType.SILICON), new OreDictStack(ANY_BISMOID.nugget()), new OreDictStack(GOLD.wireFine(), 2)));

View File

@ -3,7 +3,7 @@ package com.hbm.lib;
public class RefStrings {
public static final String MODID = "hbm";
public static final String NAME = "Hbm's Nuclear Tech Mod";
public static final String VERSION = "1.0.27 BETA (5714)";
public static final String VERSION = "1.0.27 BETA (5719)";
//HBM's Beta Naming Convention:
//V T (X)
//V -> next release version

View File

@ -37,7 +37,7 @@ public class ParseMSES1 implements IParse {
// sets the script index to the jump point
if(lower.startsWith("jmp ")) {
if(line.length() <= 4) return EnumStatementReturn.PARAMETER_ERROR;
String jmpKey = substitute(ctx, line.substring(4));
String jmpKey = substitute(ctx, line.substring(4), false);
if(ctx.jmp.containsKey(jmpKey)) {
ctx.current = ctx.jmp.get(jmpKey);
return EnumStatementReturn.OK;
@ -49,7 +49,7 @@ public class ParseMSES1 implements IParse {
if(lower.startsWith("jmpif ")) {
if(line.length() <= 6) return EnumStatementReturn.PARAMETER_ERROR;
if(!ctx.buffer.equals("true")) return EnumStatementReturn.OK;
String jmpKey = substitute(ctx, line.substring(6));
String jmpKey = substitute(ctx, line.substring(6), false);
if(ctx.jmp.containsKey(jmpKey)) {
ctx.current = ctx.jmp.get(jmpKey);
return EnumStatementReturn.OK;
@ -61,7 +61,7 @@ public class ParseMSES1 implements IParse {
if(lower.startsWith("jmpnot ")) {
if(line.length() <= 7) return EnumStatementReturn.PARAMETER_ERROR;
if(ctx.buffer.equals("true")) return EnumStatementReturn.OK;
String jmpKey = substitute(ctx, line.substring(7));
String jmpKey = substitute(ctx, line.substring(7), false);
if(ctx.jmp.containsKey(jmpKey)) {
ctx.current = ctx.jmp.get(jmpKey);
return EnumStatementReturn.OK;
@ -103,7 +103,7 @@ public class ParseMSES1 implements IParse {
// runs the calculation, allows string substitution, saves result to buffer
if(lower.startsWith("eval ")) {
if(line.length() <= 5) return EnumStatementReturn.PARAMETER_ERROR;
String statement = substitute(ctx, line.substring(5));
String statement = substitute(ctx, line.substring(5), true);
try {
double result = Calculator.evaluateExpression(statement);
ctx.buffer = "" + result;
@ -114,7 +114,7 @@ public class ParseMSES1 implements IParse {
// runs the calculation, allows string substitution, rounds, saves result to buffer,
if(lower.startsWith("evalr ")) {
if(line.length() <= 6) return EnumStatementReturn.PARAMETER_ERROR;
String statement = substitute(ctx, line.substring(6));
String statement = substitute(ctx, line.substring(6), true);
try {
double result = Calculator.evaluateExpression(statement);
ctx.buffer = "" + (int) Math.round(result);
@ -125,7 +125,7 @@ public class ParseMSES1 implements IParse {
// runs the calculation from the buffer, allows string substitution, saves result to buffer
if(lower.equals("evalr")) {
if(ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
String statement = substitute(ctx, ctx.buffer);
String statement = substitute(ctx, ctx.buffer, true);
try {
double result = Calculator.evaluateExpression(statement);
ctx.buffer = "" + (int) Math.round(result);
@ -166,7 +166,7 @@ public class ParseMSES1 implements IParse {
// concatenate, same as buffer but evaluates $var$ substitutions
if(lower.startsWith("concat ")) {
if(line.length() <= 7 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
String concat = substitute(ctx, line.substring(5));
String concat = substitute(ctx, line.substring(7), false);
ctx.buffer = concat;
return EnumStatementReturn.OK;
}
@ -174,7 +174,7 @@ public class ParseMSES1 implements IParse {
// compares the buffer with a value, allows substitutions
if(lower.startsWith("eq ")) {
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
ctx.buffer = ctx.buffer.equals(substitute(ctx, line.substring(3))) ? "true" : "false";
ctx.buffer = ctx.buffer.equals(substitute(ctx, line.substring(3), false)) ? "true" : "false";
return EnumStatementReturn.OK;
}
@ -225,14 +225,14 @@ public class ParseMSES1 implements IParse {
// sends an RoR signal using the buffer's contents as the message over the supplied channel
if(lower.startsWith("send ")) {
if(line.length() <= 5 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
RTTYSystem.broadcast(ctx.world, substitute(ctx, line.substring(5)), ctx.buffer);
RTTYSystem.broadcast(ctx.world, substitute(ctx, line.substring(5), false), ctx.buffer);
return EnumStatementReturn.OK;
}
// listens to an RoR signal using the supplied channel name and saves it to the buffer
if(lower.startsWith("listen ")) {
if(line.length() <= 7) return EnumStatementReturn.PARAMETER_ERROR;
RTTYChannel chan = RTTYSystem.listen(ctx.world, substitute(ctx, line.substring(7)));
RTTYChannel chan = RTTYSystem.listen(ctx.world, substitute(ctx, line.substring(7), false));
if(chan != null) ctx.buffer = chan.signal + "";
return EnumStatementReturn.OK;
}
@ -240,26 +240,39 @@ public class ParseMSES1 implements IParse {
return EnumStatementReturn.UNRECOGNIZED_COMMAND;
}
public String substitute(ParseContext ctx, String statement) {
public String substitute(ParseContext ctx, String statement, boolean forceNumber) {
if(!statement.contains("$")) return statement;
String[] frags = statement.split("\\$");
if(frags.length % 2 == 0 || frags.length < 3) return statement;
StringBuilder joined = new StringBuilder("");
StringBuilder var = new StringBuilder("");
boolean readingVar = false;
// since var names are enclosed with $ signs, we assume that every evenly numbered fragment is a var name
// example: 5 + $val1$ * $val2$ / (-$val3$)
// equals "5 + ", "val1", "* ", "val2", "/ (-", "val3", ")"
// 1 2 3 4 5 6 7
for(int i = 1; i < frags.length; i += 2) {
// special case, if we try to substitute $buffer$ then read the literal buffer
if(frags[i].equals("buffer")) {
frags[i] = ctx.buffer;
for(char c : statement.toCharArray()) {
if(c == '$') {
if(!readingVar) {
readingVar = true;
} else {
if("buffer".equals(var)) {
joined.append(ctx.buffer);
} else {
String variable = ctx.variables.getString(var.toString());
if(forceNumber && variable.isEmpty()) variable = "0";
joined.append(variable);
var.delete(0, var.length());
readingVar = false;
}
}
} else {
frags[i] = ctx.variables.getString(frags[i]);
if(readingVar) {
var.append(c);
} else {
joined.append(c);
}
}
}
return String.join("", frags);
return joined.toString();
}
@Override

View File

@ -25,18 +25,18 @@ public class RenderBigAssTank extends TileEntitySpecialRenderer implements IItem
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float interp) {
TileEntityMachineBigAssTank bat = (TileEntityMachineBigAssTank) te;
GL11.glPushMatrix();
GL11.glTranslated(x + 0.5D, y, z + 0.5D);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_CULL_FACE);
if(bat.tilted) {
GL11.glTranslated(0, -1, 0);
GL11.glRotated(10, 0, 0, 1);
GL11.glRotated(5, 0, 1, 0);
}
switch(te.getBlockMetadata() - 10) {
case 2: GL11.glRotatef(270, 0F, 1F, 0F); break;
case 4: GL11.glRotatef(0, 0F, 1F, 0F); break;
@ -49,11 +49,11 @@ public class RenderBigAssTank extends TileEntitySpecialRenderer implements IItem
GL11.glShadeModel(GL11.GL_SMOOTH);
ResourceManager.bigasstank.renderAll();
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glDisable(GL11.GL_LIGHTING);
FluidType type = bat.tank.getTankType();
if(type != null && type != Fluids.NONE) {
GL11.glPushMatrix();
@ -61,11 +61,11 @@ public class RenderBigAssTank extends TileEntitySpecialRenderer implements IItem
int flammability = type.flammability;
int reactivity = type.reactivity;
EnumSymbol symbol = type.symbol;
GL11.glRotatef(22.5F, 0, 1, 0);
for(int j = 0; j < 2; j++) {
GL11.glPushMatrix();
GL11.glTranslated(5.5, 2, 0);
DiamondPronter.pront(poison, flammability, reactivity, symbol);
@ -76,7 +76,7 @@ public class RenderBigAssTank extends TileEntitySpecialRenderer implements IItem
}
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_BLEND);
GL11.glAlphaFunc(GL11.GL_GREATER, 0);
@ -84,33 +84,34 @@ public class RenderBigAssTank extends TileEntitySpecialRenderer implements IItem
GL11.glColor3f(1F, 1F, 1F);
bindTexture(bat.tank.getTankType().getTexture());
Tessellator tess = Tessellator.instance;
double height = bat.tank.getFill() * 1.5D / bat.tank.getMaxFill();
double off = 5.9375;
double speed = 250D;
double scaleFactor = 0.5D; // small number make it zoom in, big number make it zoom out
double minU = -((te.getWorldObj().getTotalWorldTime() % speed + interp) / speed) % 1D;
double maxU = minU + 1;
double maxU = minU + 1 * scaleFactor;
tess.startDrawingQuads();
tess.addVertexWithUV(-off, 1.75, -0.25, minU, 0);
tess.addVertexWithUV(-off, 1.75 + height, -0.25, minU, -height * 2);
tess.addVertexWithUV(-off, 1.75 + height, 0.25, maxU, -height * 2);
tess.addVertexWithUV(-off, 1.75 + height, -0.25, minU, -height * 2 * scaleFactor);
tess.addVertexWithUV(-off, 1.75 + height, 0.25, maxU, -height * 2 * scaleFactor);
tess.addVertexWithUV(-off, 1.75, 0.25, maxU, 0);
tess.addVertexWithUV(off, 1.75, -0.25, maxU, 0);
tess.addVertexWithUV(off, 1.75 + height, -0.25, maxU, -height * 2);
tess.addVertexWithUV(off, 1.75 + height, 0.25, minU, -height * 2);
tess.addVertexWithUV(off, 1.75 + height, -0.25, maxU, -height * 2 * scaleFactor);
tess.addVertexWithUV(off, 1.75 + height, 0.25, minU, -height * 2 * scaleFactor);
tess.addVertexWithUV(off, 1.75, 0.25, minU, 0);
tess.draw();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glPopMatrix();
}

View File

@ -5,7 +5,10 @@ import java.util.List;
import com.hbm.blocks.BlockDummyable;
import com.hbm.blocks.ModBlocks;
import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.util.Compat;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
@ -59,7 +62,7 @@ public class TileEntityCargoElevator extends TileEntityLoadedBase {
// exist for at least one tick before the main portion gets rendered, fixes the short flickering platform that instantly despawns
renderPlatform = true;
this.networkPackNT(100);
this.networkPackNT(300);
} else {
if(this.sync > 0) {
@ -141,7 +144,8 @@ public class TileEntityCargoElevator extends TileEntityLoadedBase {
@Override
public AxisAlignedBB getRenderBoundingBox() {
int h = 1 + this.height;
// workaround for angelica, extend AABB to build height by default instead of dynamically scaling
int h = Compat.isModLoaded(Compat.MOD_ANG) ? 256 - yCoord : 1 + this.height;
if(bb == null || bb.maxY - bb.minY < h) {
bb = AxisAlignedBB.getBoundingBox(
@ -156,4 +160,10 @@ public class TileEntityCargoElevator extends TileEntityLoadedBase {
return bb;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
}

View File

@ -87,9 +87,9 @@ public class TileEntityMachineBlastFurnace extends TileEntityMachineBase impleme
this.speed = 0F;
GenericRecipe recipe = BlastFurnaceRecipesNT.INSTANCE.getRecipe(slots[1], slots[2]);
if(!this.tilted && recipe != null && this.fuel >= FUEL_RATE && this.canOutput(recipe)) {
if(!this.tilted && recipe != null && this.fuel >= FUEL_RATE && this.hasQuantities(recipe) && this.canOutput(recipe)) {
this.speed = MathHelper.clamp_float(0.5F + this.tanks[0].getFill() * 4F / this.tanks[0].getMaxFill(), 0.5F, 3F);
this.speed = MathHelper.clamp_float(0.5F + this.tanks[0].getFill() * 8F / this.tanks[0].getMaxFill(), 0.5F, 5F);
this.isProgressing = true;
this.progress += speed / recipe.duration;
@ -158,6 +158,12 @@ public class TileEntityMachineBlastFurnace extends TileEntityMachineBase impleme
};
}
public boolean hasQuantities(GenericRecipe recipe) {
if(recipe.inputItem[0].matchesRecipe(slots[1], false) && recipe.inputItem[1].matchesRecipe(slots[2], false)) return true;
if(recipe.inputItem[0].matchesRecipe(slots[2], false) && recipe.inputItem[1].matchesRecipe(slots[1], false)) return true;
return false;
}
public boolean canOutput(GenericRecipe recipe) {
for(int i = 0; i < recipe.outputItem.length; i++) {

View File

@ -7,6 +7,7 @@ import java.util.Random;
import com.hbm.blocks.ModBlocks;
import com.hbm.entity.projectile.EntityShrapnel;
import com.hbm.handler.radiation.ChunkRadiationManager;
import com.hbm.handler.CompatHandler;
import com.hbm.interfaces.IControlReceiver;
import com.hbm.inventory.container.ContainerWatz;
import com.hbm.inventory.fluid.Fluids;
@ -29,10 +30,17 @@ import com.hbm.util.fauxpointtwelve.DirPos;
import com.hbm.util.function.Function;
import api.hbm.fluid.IFluidStandardTransceiver;
import cpw.mods.fml.common.Optional;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import api.hbm.redstoneoverradio.IRORInteractive;
import api.hbm.redstoneoverradio.IRORValueProvider;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.SimpleComponent;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
@ -45,7 +53,8 @@ import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityWatz extends TileEntityMachineBase implements IFluidStandardTransceiver, IControlReceiver, IGUIProvider, IFluidCopiable {
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
public class TileEntityWatz extends TileEntityMachineBase implements IFluidStandardTransceiver, IControlReceiver, IGUIProvider, IFluidCopiable, CompatHandler.OCComponent, IRORValueProvider, IRORInteractive {
public FluidTank[] tanks;
public FluidTank[] sharedTanks;
@ -54,11 +63,11 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
public double fluxLastReaction; //flux created by the previous reaction, used for the next reaction
public double fluxDisplay;
public boolean isOn;
/* lock types for item IO */
public boolean isLocked = false;
public ItemStack[] locks;
public TileEntityWatz() {
super(24);
this.locks = new ItemStack[slots.length];
@ -73,7 +82,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
public String getName() {
return "container.watz";
}
protected void resetSharedTanks() {
this.sharedTanks = new FluidTank[3];
this.sharedTanks[0] = new FluidTank(Fluids.COOLANT, 64_000);
@ -86,16 +95,16 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
@Override
public void updateEntity() {
if(!worldObj.isRemote) resetSharedTanks();
if(!worldObj.isRemote && !updateLock()) {
boolean turnedOn = worldObj.getBlock(xCoord, yCoord + 3, zCoord) == ModBlocks.watz_pump && worldObj.getIndirectPowerLevelTo(xCoord, yCoord + 5, zCoord, 0) > 0;
List<TileEntityWatz> segments = new ArrayList();
segments.add(this);
this.subscribeToTop();
/* accumulate all segments */
for(int y = yCoord - 3; y >= 0; y -= 3) {
TileEntity tile = Compat.getTileStandard(worldObj, xCoord, y, zCoord);
@ -105,11 +114,11 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
break;
}
}
/* set up shared tanks */
FluidTank[] sharedTanks = new FluidTank[3];
for(int i = 0; i < 3; i++) sharedTanks[i] = new FluidTank(tanks[i].getTankType(), 0);
for(TileEntityWatz segment : segments) {
segment.setupCoolant();
for(int i = 0; i < 3; i++) {
@ -117,13 +126,13 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
sharedTanks[i].setFill(sharedTanks[i].getFill() + segment.tanks[i].getFill());
}
}
//update coolant, bottom to top
for(int i = segments.size() - 1; i >= 0; i--) {
TileEntityWatz segment = segments.get(i);
segment.updateCoolant(sharedTanks);
}
/* update reaction, top to bottom */
this.updateReaction(null, sharedTanks, turnedOn);
for(int i = 1; i < segments.size(); i++) {
@ -131,7 +140,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
TileEntityWatz above = segments.get(i - 1);
segment.updateReaction(above, sharedTanks, turnedOn);
}
/* send sync packets (order doesn't matter) */
for(TileEntityWatz segment : segments) {
segment.sharedTanks[0] = sharedTanks[0];
@ -141,7 +150,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
segment.networkPackNT(25);
segment.heat *= 0.99; //cool 1% per tick
}
/* re-distribute fluid from shared tanks back into actual tanks, bottom to top */
for(int i = segments.size() - 1; i >= 0; i--) {
TileEntityWatz segment = segments.get(i);
@ -151,9 +160,9 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
segment.tanks[j].setFill(min);
}
}
segments.get(segments.size() - 1).sendOutBottom();
/* explode on mud overflow */
if(sharedTanks[2].getFill() > 0) {
for(int x = -3; x <= 3; x++) {
@ -164,39 +173,39 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
}
}
this.disassemble();
ChunkRadiationManager.proxy.incrementRad(worldObj, xCoord, yCoord + 1, zCoord, 1_000F);
worldObj.playSoundEffect(xCoord + 0.5, yCoord + 2, zCoord + 0.5, "hbm:block.rbmk_explosion", 50.0F, 1.0F);
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "rbmkmush");
data.setFloat("scale", 5);
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, xCoord + 0.5, yCoord + 2, zCoord + 0.5), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 250));
MainRegistry.proxy.effectNT(data);
return;
}
}
}
/** basic sanity checking, usually wouldn't do anything except when NBT loading borks */
public void setupCoolant() {
tanks[0].setTankType(Fluids.COOLANT);
tanks[1].setTankType(tanks[0].getTankType().getTrait(FT_Heatable.class).getFirstStep().typeProduced);
}
public void updateCoolant(FluidTank[] tanks) {
double coolingFactor = 0.2D; //20% per tick
double heatToUse = this.heat * coolingFactor;
FT_Heatable trait = tanks[0].getTankType().getTrait(FT_Heatable.class);
HeatingStep step = trait.getFirstStep();
int heatCycles = (int) (heatToUse / step.heatReq);
int coolCycles = tanks[0].getFill() / step.amountReq;
int hotCycles = (tanks[1].getMaxFill() - tanks[1].getFill()) / step.amountProduced;
int cycles = Math.min(heatCycles, Math.min(hotCycles, coolCycles));
this.heat -= cycles * step.heatReq;
tanks[0].setFill(tanks[0].getFill() - cycles * step.amountReq);
@ -205,34 +214,34 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
/** enforces strict top to bottom update order (instead of semi-random based on placement) */
public void updateReaction(TileEntityWatz above, FluidTank[] tanks, boolean turnedOn) {
if(turnedOn) {
List<ItemStack> pellets = new ArrayList();
for(int i = 0; i < 24; i++) {
ItemStack stack = slots[i];
if(stack != null && stack.getItem() == ModItems.watz_pellet) {
pellets.add(stack);
}
}
double baseFlux = 0D;
/* init base flux */
for(ItemStack stack : pellets) {
EnumWatzType type = EnumUtil.grabEnumSafely(EnumWatzType.class, stack.getItemDamage());
baseFlux += type.passive;
}
double inputFlux = baseFlux + fluxLastReaction;
double addedFlux = 0D;
double addedHeat = 0D;
for(ItemStack stack : pellets) {
EnumWatzType type = EnumUtil.grabEnumSafely(EnumWatzType.class, stack.getItemDamage());
Function burnFunc = type.burnFunc;
Function heatDiv = type.heatDiv;
if(burnFunc != null) {
double div = heatDiv != null ? heatDiv.effonix(heat) : 1D;
double burn = burnFunc.effonix(inputFlux) / div;
@ -242,11 +251,11 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
tanks[2].setFill(tanks[2].getFill() + (int) Math.round(type.mudContent * burn));
}
}
for(ItemStack stack : pellets) {
EnumWatzType type = EnumUtil.grabEnumSafely(EnumWatzType.class, stack.getItemDamage());
Function absorbFunc = type.absorbFunc;
if(absorbFunc != null) {
double absorb = absorbFunc.effonix(baseFlux + fluxLastReaction);
addedHeat += absorb;
@ -254,38 +263,38 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
tanks[2].setFill(tanks[2].getFill() + (int) Math.round(type.mudContent * absorb));
}
}
this.heat += addedHeat;
this.fluxLastBase = baseFlux;
this.fluxLastReaction = addedFlux;
} else {
this.fluxLastBase = 0;
this.fluxLastReaction = 0;
}
for(int i = 0; i < 24; i++) {
ItemStack stack = slots[i];
/* deplete */
if(stack != null && stack.getItem() == ModItems.watz_pellet && ItemWatzPellet.getEnrichment(stack) <= 0) {
slots[i] = new ItemStack(ModItems.watz_pellet_depleted, 1, stack.getItemDamage());
continue; // depleted pellets may persist for one tick
}
}
if(above != null) {
for(int i = 0; i < 24; i++) {
ItemStack stackBottom = slots[i];
ItemStack stackTop = above.slots[i];
/* items fall down if the bottom slot is empty */
if(stackBottom == null && stackTop != null) {
slots[i] = stackTop.copy();
above.decrStackSize(i, stackTop.stackSize);
}
/* items switch places if the top slot is depleted */
if(stackBottom != null && stackBottom.getItem() == ModItems.watz_pellet && stackTop != null && stackTop.getItem() == ModItems.watz_pellet_depleted) {
ItemStack buf = stackTop.copy();
@ -319,12 +328,12 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
tank.deserialize(buf);
}
}
/** Prevent manual updates when another segment is above this one */
public boolean updateLock() {
return Compat.getTileStandard(worldObj, xCoord, yCoord + 3, zCoord) instanceof TileEntityWatz;
}
protected void subscribeToTop() {
this.trySubscribe(tanks[0].getTankType(), worldObj, xCoord, yCoord + 3, zCoord, ForgeDirection.UP);
this.trySubscribe(tanks[0].getTankType(), worldObj, xCoord + 2, yCoord + 3, zCoord, ForgeDirection.UP);
@ -332,15 +341,15 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
this.trySubscribe(tanks[0].getTankType(), worldObj, xCoord, yCoord + 3, zCoord + 2, ForgeDirection.UP);
this.trySubscribe(tanks[0].getTankType(), worldObj, xCoord, yCoord + 3, zCoord - 2, ForgeDirection.UP);
}
protected void sendOutBottom() {
for(DirPos pos : getSendingPos()) {
if(tanks[1].getFill() > 0) this.sendFluid(tanks[1], worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
if(tanks[2].getFill() > 0) this.sendFluid(tanks[2], worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
}
}
protected DirPos[] getSendingPos() {
return new DirPos[] {
new DirPos(xCoord, yCoord - 1, zCoord, ForgeDirection.DOWN),
@ -350,13 +359,13 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
new DirPos(xCoord, yCoord - 1, zCoord - 2, ForgeDirection.DOWN)
};
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
NBTTagList list = nbt.getTagList("locks", 10);
for(int i = 0; i < list.tagCount(); i++) {
NBTTagCompound nbt1 = list.getCompoundTagAt(i);
byte b0 = nbt1.getByte("slot");
@ -364,21 +373,21 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
locks[b0] = ItemStack.loadItemStackFromNBT(nbt1);
}
}
for(int i = 0; i < tanks.length; i++) tanks[i].readFromNBT(nbt, "t" + i);
this.heat = nbt.getInteger("heat");
this.fluxLastBase = nbt.getDouble("lastFluxB");
this.fluxLastReaction = nbt.getDouble("lastFluxR");
this.isLocked = nbt.getBoolean("isLocked");
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
NBTTagList list = new NBTTagList();
for(int i = 0; i < locks.length; i++) {
if(locks[i] != null) {
NBTTagCompound nbt1 = new NBTTagCompound();
@ -388,12 +397,12 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
}
}
nbt.setTag("locks", list);
for(int i = 0; i < tanks.length; i++) tanks[i].writeToNBT(nbt, "t" + i);
nbt.setInteger("heat", this.heat);
nbt.setDouble("lastFluxB", fluxLastBase);
nbt.setDouble("lastFluxR", fluxLastReaction);
nbt.setBoolean("isLocked", isLocked);
}
@ -404,9 +413,9 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
@Override
public void receiveControl(NBTTagCompound data) {
if(data.hasKey("lock")) {
if(this.isLocked) {
this.locks = new ItemStack[slots.length];
} else {
@ -414,7 +423,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
this.locks[i] = slots[i];
}
}
this.isLocked = !this.isLocked;
this.markChanged();
}
@ -426,7 +435,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
if(!this.isLocked) return true;
return this.locks[i] != null && this.locks[i].getItem() == stack.getItem() && locks[i].getItemDamage() == stack.getItemDamage();
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
@ -443,10 +452,10 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
}
AxisAlignedBB bb = null;
@Override
public AxisAlignedBB getRenderBoundingBox() {
if(bb == null) {
bb = AxisAlignedBB.getBoundingBox(
xCoord - 3,
@ -457,16 +466,16 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
zCoord + 4
);
}
return bb;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
private void disassemble() {
int count = 20;
@ -486,7 +495,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
worldObj.setBlock(xCoord, yCoord, zCoord, ModBlocks.mud_block);
worldObj.setBlock(xCoord, yCoord + 1, zCoord, ModBlocks.mud_block);
worldObj.setBlock(xCoord, yCoord + 2, zCoord, ModBlocks.mud_block);
setBrokenColumn(0, ModBlocks.watz_element, 0, 1, 0);
setBrokenColumn(0, ModBlocks.watz_element, 0, 2, 0);
setBrokenColumn(0, ModBlocks.watz_element, 0, 0, 1);
@ -507,7 +516,7 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
setBrokenColumn(0, ModBlocks.watz_cooler, 0, -2, -1);
setBrokenColumn(0, ModBlocks.watz_cooler, 0, 1, -2);
setBrokenColumn(0, ModBlocks.watz_cooler, 0, -1, -2);
for(int j = -1; j < 2; j++) {
setBrokenColumn(1, ModBlocks.watz_end, 1, 3, j);
setBrokenColumn(1, ModBlocks.watz_end, 1, j, 3);
@ -518,20 +527,20 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
setBrokenColumn(1, ModBlocks.watz_end, 1, 2, -2);
setBrokenColumn(1, ModBlocks.watz_end, 1, -2, 2);
setBrokenColumn(1, ModBlocks.watz_end, 1, -2, -2);
List<EntityPlayer> players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5).expand(50, 50, 50));
for(EntityPlayer player : players) {
player.triggerAchievement(MainRegistry.achWatzBoom);
}
}
private void setBrokenColumn(int minHeight, Block b, int meta, int x, int z) {
int height = minHeight + worldObj.rand.nextInt(3 - minHeight);
for(int i = 0; i < 3; i++) {
if(i <= height) {
worldObj.setBlock(xCoord + x, yCoord + i, zCoord + z, b, meta, 3);
} else {
@ -570,4 +579,104 @@ public class TileEntityWatz extends TileEntityMachineBase implements IFluidStand
public FluidTank getTankToPaste() {
return null;
}
// opencomputers stuff
@Override
@Optional.Method(modid = "OpenComputers")
public String getComponentName() {
return "watz_reactor";
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getHeat(Context context, Arguments args) {
return new Object[] {heat};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getFlux(Context context, Arguments args) {
return new Object[] {fluxLastBase + fluxLastReaction};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getCoolantInfo(Context context, Arguments args) {
return new Object[] {tanks[0].getFill(), tanks[0].getMaxFill(), tanks[1].getFill(), tanks[1].getMaxFill()};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getWasteInfo(Context context, Arguments args) {
return new Object[] {tanks[2].getFill(), tanks[2].getMaxFill()};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] isOn(Context context, Arguments args) {
return new Object[] {isOn};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getInfo(Context context, Arguments args) {
return new Object[] {tanks[0].getFill(), tanks[0].getMaxFill(), tanks[1].getFill(), tanks[1].getMaxFill(), tanks[2].getFill(), tanks[2].getMaxFill(), heat, fluxLastBase + fluxLastReaction, isOn};
}
@Override
@Optional.Method(modid = "OpenComputers")
public String[] methods() {
return new String[] {
"getComponentName",
"getHeat",
"getFlux",
"getCoolantInfo",
"getWasteInfo",
"isOn",
"getInfo"
};
}
@Override
@Optional.Method(modid = "OpenComputers")
public Object[] invoke(String method, Context context, Arguments args) throws Exception {
switch (method) {
case "getHeat": return getHeat(context, args);
case "getFlux": return getFlux(context, args);
case "getCoolantInfo": return getCoolantInfo(context, args);
case "getWasteInfo": return getWasteInfo(context, args);
case "isOn": return isOn(context, args);
case "getInfo": return getInfo(context, args);
}
throw new NoSuchMethodException();
}
public static final String[] ROR = new String[] { // not to be confused with RUR
PREFIX_VALUE + "heat",
PREFIX_VALUE + "flux",
PREFIX_VALUE + "mud",
PREFIX_VALUE + "coolant_hot",
PREFIX_VALUE + "coolant_cold",
};
@Override
public String[] getFunctionInfo() {
return ROR;
}
@Override
public String runRORFunction(String name, String[] params) {
// TODO Auto-generated method stub
return null;
}
@Override
public String provideRORValue(String name) {
if((PREFIX_VALUE + "heat").equals(name)) return "" + this.heat;
if((PREFIX_VALUE + "flux").equals(name)) return "" + (int) (this.fluxLastBase + this.fluxLastReaction);
if((PREFIX_VALUE + "mud").equals(name)) return "" + this.tanks[2].getFill();
if((PREFIX_VALUE + "coolant_hot").equals(name)) return "" + this.tanks[1].getFill();
if((PREFIX_VALUE + "coolant_cold").equals(name)) return "" + this.tanks[0].getFill();
return null;
}
}

View File

@ -37,7 +37,7 @@ public class TileEntityPneumoStorageAccess extends TileEntityLoadedBase implemen
}
}
if(this.cache == null) {
if(this.cache == null || this.cache.hasExpired) {
this.cache = new StackCache(xCoord, yCoord, zCoord);
}

View File

@ -45,6 +45,15 @@ public class PneumaticNetwork extends NodeNet {
public LinkedHashSet<StackCache> accessors = new LinkedHashSet();
public LinkedHashSet<ISlotMonitorProvider> storages = new LinkedHashSet();
@Override
public void destroy() {
super.destroy();
receivers.clear();
for(StackCache cache : accessors) cache.dissolveCache();
accessors.clear();
storages.clear();
}
public void addReceiver(IInventory inventory, ForgeDirection pipeDir, TileEntityPneumoTube endpoint) {
receivers.put(inventory, new Triplet(pipeDir, System.currentTimeMillis(), endpoint));

View File

@ -1476,15 +1476,15 @@ item.ajro_boots.name=AJR动力装甲靴子
item.ajro_helmet.name=AJR 动力装甲头盔
item.ajro_legs.name=AJR 动力装甲护腿
item.ajro_plate.name=AJR 动力装甲胸甲
item.alloy_axe.name=高级合金斧
item.alloy_boots.name=高级合金靴子
item.alloy_helmet.name=高级合金头盔
item.alloy_hoe.name=高级合金锄
item.alloy_legs.name=高级合金护腿
item.alloy_pickaxe.name=高级合金镐
item.alloy_plate.name=高级合金胸甲
item.alloy_shovel.name=高级合金锹
item.alloy_sword.name=高级合金剑
item.alloy_axe.name=高级合金斧(遗留)
item.alloy_boots.name=高级合金靴子(遗留)
item.alloy_helmet.name=高级合金头盔(遗留)
item.alloy_hoe.name=高级合金锄(遗留)
item.alloy_legs.name=高级合金护腿(遗留)
item.alloy_pickaxe.name=高级合金镐(遗留)
item.alloy_plate.name=高级合金胸甲(遗留)
item.alloy_shovel.name=高级合金锹(遗留)
item.alloy_sword.name=高级合金剑(遗留)
item.ammo_arty.name=16英寸炮弹
item.ammo_arty_cargo.name=16英寸快递炮弹
item.ammo_arty_chlorine.name=16英寸氯气炮弹
@ -2323,11 +2323,11 @@ item.defuser.name=高科技拆弹装置
item.defuser_gold.name=黄金剪线钳
item.demon_core_closed.name=封闭的恶魔核心
item.demon_core_open.name=打开的恶魔核心
item.desh_axe.name=工人合金
item.desh_hoe.name=工人合金
item.desh_pickaxe.name=工人合金
item.desh_shovel.name=工人合金
item.desh_sword.name=工人合金
item.desh_axe.name=Desh
item.desh_hoe.name=Desh
item.desh_pickaxe.name=Desh
item.desh_shovel.name=Desh
item.desh_sword.name=Desh
item.designator.name=短程目标指示器
item.designator_arty_range.name=远程火炮遥控器
item.designator_manual.name=手动目标指示器
@ -4600,7 +4600,7 @@ tile.cluster_depth_tungsten.name=深层钨矿簇
tile.cluster_iron.name=铁矿簇
tile.cluster_titanium.name=钛矿簇
tile.custom_machine_anchor.name=自定义机器结构定位锚
tile.cm_block.alloy.name=高级合金机器外壳
tile.cm_block.alloy.name=青铜机器外壳
tile.cm_block.desh.name=Desh机器外壳
tile.cm_block.steel.name=钢制机器外壳
tile.cm_block.tcalloy.name=锝钢机器外壳
@ -4614,15 +4614,15 @@ tile.cm_engine.desh.name=Desh电机组
tile.cm_engine.standard.name=电机组
tile.cm_flux.name=中子接收器
tile.cm_heat.name=热量接收器
tile.cm_port.alloy.name=高级合金端口
tile.cm_port.alloy.name=青铜端口
tile.cm_port.desh.name=Desh端口
tile.cm_port.steel.name=钢制端口
tile.cm_port.tcalloy.name=锝钢端口
tile.cm_sheet.alloy.name=高级合金建筑板
tile.cm_sheet.alloy.name=青铜建筑板
tile.cm_sheet.desh.name=Desh建筑板
tile.cm_sheet.steel.name=钢建筑板
tile.cm_sheet.tcalloy.name=锝钢建筑板
tile.cm_tank.alloy.name=高级合金储罐
tile.cm_tank.alloy.name=青铜储罐
tile.cm_tank.desh.name=Desh储罐
tile.cm_tank.steel.name=钢制储罐
tile.cm_tank.tcalloy.name=锝钢储罐
@ -4988,7 +4988,7 @@ tile.machine_assemfac.name=装配厂 (遗留)
tile.machine_autocrafter.name=自动工作台
tile.machine_autosaw.name=自动嗡嗡锯
tile.machine_autosaw.desc=砍伐附近的植物,重新种植树木$接受:$-木油$-乙醇$-鱼油$-重油$-煤焦杂酚油
tile.machine_bat9000.name=巨尻-9000 储罐
tile.machine_bat9000.name=巨尻-9000 储罐(遗留)
tile.machine_battery.name=蓄电池(遗留)
tile.machine_battery_potato.name=马铃薯电池组(遗留)
tile.machine_boiler.name=大型锅炉
@ -5024,11 +5024,11 @@ tile.machine_detector.name=功率检测器
tile.machine_deuterium_extractor.name=氘提取器
tile.machine_deuterium_tower.name=氘萃取塔
tile.machine_diesel.name=柴油发电机
tile.machine_difurnace_extension.name=高炉烟道
tile.machine_difurnace_off.name=高炉
tile.machine_difurnace_on.name=高炉
tile.machine_difurnace_rtg_off.name=核高炉
tile.machine_difurnace_rtg_on.name=核高炉
tile.machine_difurnace_extension.name=高炉烟道(遗留)
tile.machine_difurnace_off.name=高炉(遗留)
tile.machine_difurnace_on.name=高炉(遗留)
tile.machine_difurnace_rtg_off.name=核高炉(遗留)
tile.machine_difurnace_rtg_on.name=核高炉(遗留)
tile.machine_dineutronium_battery.name=Spark蓄电池遗留
tile.machine_drain.name=排液管
tile.machine_drill.name=自动采矿钻机
@ -6356,3 +6356,25 @@ tile.pneumatic_tube_paintable.desc=用实心方块右键改变涂装。$螺丝
tile.rbmk_terminal.name=无线红石信号发信终端
tile.rbmk_terminal.desc=所有无线红石信号命令均需要手动发送。
tile.red_cable_paintable.desc=用实心方块右键改变涂装。$螺丝刀可以清除涂装。$拆弹器可以去除电线端口。$涂装可以用设定工具复制。
ass.analogAlt=模拟电路板装配
ass.atomicClockAlt=铯原子钟生产
ass.factorioChip=集成电路板生产
ass.nitra=Nitra转化为弹药
autoswitch.cyclotron=回旋加速器粉盒生产
chem.aggregate=快速生产混凝土骨料
container.bigAssTank=“巨尻”超大型储罐
container.blastFurnace=高炉
hbmfluid.airblast=热空气射流
hbmfluid.flue=烟道气
item.coin_token.name=自动售货机
item.gun_mk108.name=榴弹机枪
tile.fan.suckOn=风扇正在吸气
tile.fan.suckOff=风扇正在吹风
tile.machine_bigasstank.name=“巨尻”超大型储罐
tile.machine_blast_furnace.name=高炉
tile.machine_thresher.name=自动脱粒机
tile.machine_thresher.desc=收割并重新种植作物,$可接受:$-木油$-乙醇$-鱼油$-重油$-煤焦杂酚油
tile.machine_thresher.suspended=暂停
tile.nospawn=生物不会在这个方块上生成!
tile.radio_autocal.name=AUTOCAL自动计算机
tile.vending_machine.name= 自动售货机