Merge branch 'HbmMods:master' into master

This commit is contained in:
Raaaaaaaaaay 2025-12-08 22:55:35 +02:00 committed by GitHub
commit 10585527ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 565 additions and 146 deletions

View File

@ -1,5 +1,6 @@
## Added
* Precision assembler
* Annihilator
## Changed
* New fusion reactor and particle accelerator parts now have OpenComputers compat
@ -27,6 +28,7 @@
* Bedrock coltan is no longer a dedicated bedrock ore type
* Alt fire is now available for 10ga double barrel shotguns, allowing only a single barrel to be fired at once
* The custom mapping function on RoR torches now supports up to 32 characters instead of 15
* Drainage pipes, flare stacks and the annihilator now have the default fluid priority of LOW, meaning that excess removal using those no longer requires flow control pumps
## Fixed
* Fixed gamebreaking issue causing crashes and world corruption where the multi detonator had its tooltip misspelled

View File

@ -22,6 +22,12 @@ public class ContainerMachineAnnihilator extends ContainerBase {
this.addSlotToContainer(new SlotNonRetarded(annihilator, 1, 35, 45));
// Output
this.addOutputSlots(invPlayer.player, annihilator, 2, 80, 36, 2, 3);
// Monitor
this.addSlotToContainer(new SlotNonRetarded(annihilator, 8, 152, 18));
// Payout Request
this.addSlotToContainer(new SlotNonRetarded(annihilator, 9, 152, 62));
// Payout Item
this.addSlotToContainer(new SlotCraftingOutput(invPlayer.player, annihilator, 10, 152, 80));
this.playerInv(invPlayer, 8, 126);
}
@ -43,9 +49,9 @@ public class ContainerMachineAnnihilator extends ContainerBase {
} else {
if(slotOriginal.getItem() instanceof IItemFluidIdentifier) {
if(!this.mergeItemStack(slotStack, 0, 1, false)) return null;
if(!this.mergeItemStack(slotStack, 1, 2, false)) return null;
} else {
if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 1, 2, false)) return null;
if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 0, 1, false)) return null;
}
}

View File

@ -1,8 +1,13 @@
package com.hbm.inventory.gui;
import java.util.Arrays;
import java.util.Locale;
import org.lwjgl.opengl.GL11;
import com.hbm.inventory.container.ContainerMachineAnnihilator;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.items.machine.IItemFluidIdentifier;
import com.hbm.lib.RefStrings;
import com.hbm.tileentity.machine.TileEntityMachineAnnihilator;
@ -14,21 +19,36 @@ import net.minecraft.util.ResourceLocation;
public class GUIMachineAnnihilator extends GuiInfoContainer {
private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_annihilator.png");
private TileEntityMachineAnnihilator assembler;
private TileEntityMachineAnnihilator annihilator;
public GUIMachineAnnihilator(InventoryPlayer invPlayer, TileEntityMachineAnnihilator tedf) {
super(new ContainerMachineAnnihilator(invPlayer, tedf));
assembler = tedf;
annihilator = tedf;
this.xSize = 176;
this.ySize = 208;
}
@Override
protected void drawGuiContainerForegroundLayer(int i, int j) {
String name = this.assembler.hasCustomInventoryName() ? this.assembler.getInventoryName() : I18n.format(this.assembler.getInventoryName());
public void drawScreen(int x, int y, float interp) {
super.drawScreen(x, y, interp);
this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752);
if(annihilator.slots[8] != null && this.checkClick(x, y, 151, 35, 18, 18)) {
String name = annihilator.slots[8].getDisplayName();
if(annihilator.slots[8].getItem() instanceof IItemFluidIdentifier) {
IItemFluidIdentifier id = (IItemFluidIdentifier) annihilator.slots[8].getItem();
FluidType type = id.getType(null, 0, 0, 0, annihilator.slots[8]);
name = type.getLocalizedName();
}
this.func_146283_a(Arrays.asList(new String[] { name + ":", String.format(Locale.US, "%,d", annihilator.monitorBigInt) }), x, y);
}
}
@Override
protected void drawGuiContainerForegroundLayer(int i, int j) {
String name = this.annihilator.hasCustomInventoryName() ? this.annihilator.getInventoryName() : I18n.format(this.annihilator.getInventoryName());
this.fontRendererObj.drawString(name, 70 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
}

View File

@ -0,0 +1,206 @@
package com.hbm.inventory.recipes;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.recipes.loader.SerializableRecipe;
import com.hbm.items.machine.IItemFluidIdentifier;
import com.hbm.util.ItemStackUtil;
import com.hbm.util.Tuple.Pair;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class AnnihilatorRecipes extends SerializableRecipe {
public static HashMap<Object, AnnihilatorRecipe> recipes = new HashMap();
@Override
public void registerDefaults() {
recipes.put(Items.iron_ingot, new AnnihilatorRecipe(
new Pair(new BigInteger("128"), new ItemStack(Items.gold_ingot)),
new Pair(new BigInteger("256"), new ItemStack(Items.gold_ingot, 3)),
new Pair(new BigInteger("512"), new ItemStack(Items.gold_ingot, 5))
));
}
@Override public String getFileName() { return "hbmAnnihilator.json"; }
@Override public Object getRecipeObject() { return recipes; }
@Override public void deleteRecipes() { recipes.clear(); }
/**
* If prevAmount is null, a payout is guaranteed if the currentAmount matches or exceeds the requirement.
* Otherwise, the prevAmount needs to be smaller than the requirement to count.
* @param stack
* @param prevAmount
* @param currentAmount
* @return
*/
public static ItemStack getHighestPayoutFromKey(Object key, BigInteger prevAmount, BigInteger currentAmount) {
AnnihilatorRecipe recipe = recipes.get(key);
if(recipe != null) {
ItemStack payout = getHighestPayoutFromRecipe(recipe, prevAmount, currentAmount);
if(payout != null) return payout;
}
return null;
}
public static ItemStack getHighestPayoutFromStack(ItemStack stack, BigInteger prevAmount, BigInteger currentAmount) {
if(stack.getItem() instanceof IItemFluidIdentifier) {
IItemFluidIdentifier id = (IItemFluidIdentifier) stack.getItem();
return getHighestPayoutFromFluid(id.getType(null, 0, 0, 0, stack), prevAmount, currentAmount);
}
List<String> dictKeys = ItemStackUtil.getOreDictNames(stack);
AnnihilatorRecipe recipe;
for(String key : dictKeys) {
recipe = recipes.get(key);
if(recipe != null) {
ItemStack payout = getHighestPayoutFromRecipe(recipe, prevAmount, currentAmount);
if(payout != null) return payout;
}
}
ComparableStack comp = new ComparableStack(stack).makeSingular();
recipe = recipes.get(comp);
if(recipe != null) {
ItemStack payout = getHighestPayoutFromRecipe(recipe, prevAmount, currentAmount);
if(payout != null) return payout;
}
recipe = recipes.get(stack.getItem());
if(recipe != null) {
ItemStack payout = getHighestPayoutFromRecipe(recipe, prevAmount, currentAmount);
if(payout != null) return payout;
}
return null;
}
public static ItemStack getHighestPayoutFromFluid(FluidType fluid, BigInteger prevAmount, BigInteger currentAmount) {
AnnihilatorRecipe recipe = recipes.get(fluid);
if(recipe != null) {
ItemStack payout = getHighestPayoutFromRecipe(recipe, prevAmount, currentAmount);
if(payout != null) return payout;
}
return null;
}
public static ItemStack getHighestPayoutFromRecipe(AnnihilatorRecipe recipe, BigInteger prevAmount, BigInteger currentAmount) {
BigInteger highestYet = BigInteger.ZERO;
ItemStack highestPayout = null;
for(Pair<BigInteger, ItemStack> milestone : recipe.milestones) {
if(prevAmount != null && prevAmount.compareTo(milestone.getKey()) != -1) continue; // if prevAmount is set and GEQUAL the requirement, skip
if(currentAmount.compareTo(highestYet) != 1) continue; // if currentAmount is GEQUAL to the largest already existing step, skip
if(currentAmount.compareTo(milestone.getKey()) != -1) { // if currentAmount is GEQUAL to the milestone, accept it
highestYet = milestone.getKey();
highestPayout = milestone.getValue();
}
}
return highestPayout != null ? highestPayout.copy() : null;
}
@Override
public void readRecipe(JsonElement recipe) {
JsonObject obj = (JsonObject) recipe;
JsonObject key = obj.get("key").getAsJsonObject();
Object keyObject = null;
String keyType = key.get("type").getAsString();
if("item".equals(keyType)) {
keyObject = Item.itemRegistry.getObject(key.get("item").getAsString());
}
if("comp".equals(keyType)) {
keyObject = new ComparableStack((Item) Item.itemRegistry.getObject(key.get("item").getAsString()), 1, key.get("meta").getAsInt());
}
if("fluid".equals(keyType)) {
keyObject = Fluids.fromName(key.get("fluid").getAsString());
}
if("dict".equals(keyType)) {
keyObject = key.get("dict").getAsString();
}
JsonArray milestones = obj.get("milestones").getAsJsonArray();
List<Pair<BigInteger, ItemStack>> milestoneList = new ArrayList();
for(JsonElement e : milestones) {
JsonObject milestone = e.getAsJsonObject();
milestoneList.add(new Pair(milestone.get("amount").getAsBigInteger(), this.readItemStack(milestone.get("payout").getAsJsonArray())));
}
if(keyObject != null) {
AnnihilatorRecipe newRecipe = new AnnihilatorRecipe();
newRecipe.milestones.addAll(milestoneList);
this.recipes.put(keyObject, newRecipe);
}
}
@Override
public void writeRecipe(Object recipe, JsonWriter writer) throws IOException {
Entry<Object, AnnihilatorRecipe> rec = (Entry<Object, AnnihilatorRecipe>) recipe;
writer.name("key").beginObject();
if(rec.getKey() instanceof Item) {
Item item = (Item) rec.getKey();
writer.name("type").value("item");
writer.name("item").value(Item.itemRegistry.getNameForObject(item));
}
if(rec.getKey() instanceof ComparableStack) {
ComparableStack comp = (ComparableStack) rec.getKey();
writer.name("type").value("comp");
writer.name("item").value(Item.itemRegistry.getNameForObject(comp.item));
writer.name("meta").value(comp.meta);
}
if(rec.getKey() instanceof FluidType) {
FluidType fluid = (FluidType) rec.getKey();
writer.name("type").value("fluid");
writer.name("fluid").value(fluid.getUnlocalizedName());
}
if(rec.getKey() instanceof String) {
writer.name("type").value("dict");
writer.name("dict").value((String) rec.getKey());
}
writer.endObject();
writer.name("milestones").beginArray();
for(Pair<BigInteger, ItemStack> milestone : rec.getValue().milestones) {
writer.beginObject();
writer.name("amount").value(milestone.getKey());
writer.name("payout");
this.writeItemStack(milestone.getValue(), writer);
writer.endObject();
}
writer.endArray();
}
public static class AnnihilatorRecipe {
public List<Pair<BigInteger, ItemStack>> milestones = new ArrayList();
public AnnihilatorRecipe(Pair<BigInteger, ItemStack>... milestones) {
for(Pair<BigInteger, ItemStack> milestone : milestones) this.milestones.add(milestone);
}
}
}

View File

@ -2,6 +2,7 @@ package com.hbm.inventory.recipes;
import static com.hbm.inventory.OreDictManager.*;
import com.hbm.config.GeneralConfig;
import com.hbm.inventory.FluidStack;
import com.hbm.inventory.OreDictManager.DictFrame;
import com.hbm.inventory.RecipesCommon.ComparableStack;
@ -33,7 +34,33 @@ public class PrecAssRecipes extends GenericRecipes<GenericRecipe> {
@Override
public void registerDefaults() {
int min = 1_200;
// i cast: bleeding anus
// i cast: XL horse dildo (unlubed)
// i cast: salted lemon juice in stab wound
// i cast: ovorial torsion
// i cast: perpetually breaking and healing kneecaps
// i cast: used needle sandwich
if(GeneralConfig.enable528) {
registerPair(new GenericRecipe("precass.chip").setup(100, 200L)
.inputItems(new ComparableStack(ModItems.circuit, 1, EnumCircuitType.SILICON),
new ComparableStack(ModItems.plate_polymer, 3),
new OreDictStack(GOLD.wireFine(), 4)).setPools(POOL_PREFIX_528 + "chip"),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP), 50, GeneralConfig.enableExpensiveMode ? 10 : 90);
registerPair(new GenericRecipe("precass.chip_bismoid").setup(200, 1_000L)
.inputItems(new ComparableStack(ModItems.circuit, 4, EnumCircuitType.SILICON),
new ComparableStack(ModItems.plate_polymer, 8),
new OreDictStack(ANY_BISMOID.nugget(), 2),
new OreDictStack(GOLD.wireFine(), 4)).setPools(POOL_PREFIX_528 + "chip_bismoid"),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_BISMOID), 50, GeneralConfig.enableExpensiveMode ? 10 : 75);
registerPair(new GenericRecipe("precass.chip_quantum").setup(300, 20_000L)
.inputItems(new ComparableStack(ModItems.circuit, 8, EnumCircuitType.SILICON),
new OreDictStack(BSCCO.wireDense(), 2),
new OreDictStack(ANY_HARDPLASTIC.ingot(), 8),
new ComparableStack(ModItems.pellet_charged, 4),
new OreDictStack(GOLD.wireFine(), 8)).setPools(POOL_PREFIX_528 + "chip_quantum"),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_QUANTUM), 50, GeneralConfig.enableExpensiveMode ? 10 : 50);
registerPair(new GenericRecipe("precass.controller").setup(400, 15_000L)
.inputItems(new ComparableStack(ModItems.circuit, 32, EnumCircuitType.CHIP),
@ -43,13 +70,36 @@ public class PrecAssRecipes extends GenericRecipes<GenericRecipe> {
new ComparableStack(ModItems.upgrade_speed_1),
new OreDictStack(PB.wireFine(), 16))
.inputFluids(new FluidStack(Fluids.PERFLUOROMETHYL, 1_000)),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER), 10, 25);
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER), 10, GeneralConfig.enableExpensiveMode ? 50 : 90);
registerPair(new GenericRecipe("precass.controller_advanced").setup(600, 25_000)
.inputItems(new ComparableStack(ModItems.circuit, 16, EnumCircuitType.CHIP_BISMOID),
new ComparableStack(ModItems.circuit, 48, EnumCircuitType.CAPACITOR_TANTALIUM),
new ComparableStack(ModItems.circuit, 1, EnumCircuitType.ATOMIC_CLOCK),
new ComparableStack(ModItems.circuit, 1, EnumCircuitType.CONTROLLER_CHASSIS),
new ComparableStack(ModItems.upgrade_speed_3),
new OreDictStack(PB.wireFine(), 24))
.inputFluids(new FluidStack(Fluids.PERFLUOROMETHYL, 1_000)),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER_ADVANCED), 10, GeneralConfig.enableExpensiveMode ? 33 : 75);
registerPair(new GenericRecipe("precass.controller_quantum").setup(600, 250_000)
.inputItems(new ComparableStack(ModItems.circuit, 16, EnumCircuitType.CHIP_QUANTUM),
new ComparableStack(ModItems.circuit, 48, EnumCircuitType.CHIP_BISMOID),
new ComparableStack(ModItems.circuit, 8, EnumCircuitType.ATOMIC_CLOCK),
new ComparableStack(ModItems.circuit, 2, EnumCircuitType.CONTROLLER_ADVANCED),
new ComparableStack(ModItems.upgrade_overdrive_1),
new OreDictStack(PB.wireFine(), 32))
.inputFluids(new FluidStack(Fluids.PERFLUOROMETHYL, 1_000)),
DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER_QUANTUM), 5, GeneralConfig.enableExpensiveMode ? 10 : 50);
}
int min = 1_200;
// all hail the pufferfish, driver of all innovation
this.register(new GenericRecipe("precass.blueprints").setup(5 * min, 20_000L)
.inputItems(new ComparableStack(Items.paper, 16),
new OreDictStack(KEY_BLUE, 16),
new ComparableStack(Items.fish, 16, FishType.PUFFERFISH))
new ComparableStack(Items.fish, 4, FishType.PUFFERFISH))
.outputItems(new ChanceOutputMulti(
new ChanceOutput(new ItemStack(ModItems.blueprint_folder, 1, 0), 10),
new ChanceOutput(new ItemStack(Items.paper, 16, 0), 90))
@ -57,7 +107,7 @@ public class PrecAssRecipes extends GenericRecipes<GenericRecipe> {
this.register(new GenericRecipe("precass.beigeprints").setup(5 * min, 50_000L)
.inputItems(new ComparableStack(Items.paper, 24),
new OreDictStack(CINNABAR.gem(), 24),
new ComparableStack(Items.fish, 32, FishType.PUFFERFISH))
new ComparableStack(Items.fish, 8, FishType.PUFFERFISH))
.outputItems(new ChanceOutputMulti(
new ChanceOutput(new ItemStack(ModItems.blueprint_folder, 1, 1), 5),
new ChanceOutput(new ItemStack(Items.paper, 24, 0), 95))

View File

@ -108,7 +108,7 @@ public class SolderingRecipes extends SerializableRecipe {
* COMPUTERS
*/
// a very, very vague guess on what the recipes should be. testing still needed, upgrade requirements are likely to change. maybe inclusion of caesium?
if(!GeneralConfig.enable528) {
recipes.add(new SolderingRecipe(new ItemStack(ModItems.circuit, 1, EnumCircuitType.CONTROLLER.ordinal()), 400, 15_000,
new FluidStack(Fluids.PERFLUOROMETHYL, 1_000),
new AStack[] {
@ -145,6 +145,7 @@ public class SolderingRecipes extends SerializableRecipe {
new AStack[] {
new OreDictStack(PB.wireFine(), 32)}
));
}
/*
* UPGRADES

View File

@ -174,6 +174,10 @@ public class AnvilRecipes extends SerializableRecipe {
public static void registerConstructionRecipes() {
constructionRecipes.add(new AnvilConstructionRecipe(
new AStack[] {new ComparableStack(Blocks.stonebrick, 16), new ComparableStack(ModItems.ingot_firebrick, 16), new OreDictStack(IRON.ingot(), 8), new OreDictStack(CU.ingot(), 8)},
new AnvilOutput(new ItemStack(ModBlocks.machine_annihilator))).setTier(2));
constructionRecipes.add(new AnvilConstructionRecipe(new OreDictStack(AL.ingot(), 1), new AnvilOutput(new ItemStack(ModBlocks.deco_aluminium, 4))).setTier(1).setOverlay(OverlayType.CONSTRUCTION));
constructionRecipes.add(new AnvilConstructionRecipe(new OreDictStack(BE.ingot(), 1), new AnvilOutput(new ItemStack(ModBlocks.deco_beryllium, 4))).setTier(1).setOverlay(OverlayType.CONSTRUCTION));
constructionRecipes.add(new AnvilConstructionRecipe(new OreDictStack(PB.ingot(), 1), new AnvilOutput(new ItemStack(ModBlocks.deco_lead, 4))).setTier(1).setOverlay(OverlayType.CONSTRUCTION));

View File

@ -86,6 +86,7 @@ public abstract class SerializableRecipe {
//AFTER Assembler
recipeHandlers.add(new AnvilRecipes());
recipeHandlers.add(new PedestalRecipes());
recipeHandlers.add(new AnnihilatorRecipes());
//GENERIC
recipeHandlers.add(AssemblyMachineRecipes.INSTANCE);

View File

@ -116,14 +116,17 @@ public class CraftingManager {
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CAPACITOR_TANTALIUM), new Object[] { "I", "N", "W", 'I', ModItems.plate_polymer, 'N', TA.nugget(), 'W', CU.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.PCB), new Object[] { "I", "P", 'I', ModItems.plate_polymer, 'P', CU.plate() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.PCB, 4), new Object[] { "I", "P", 'I', ModItems.plate_polymer, 'P', GOLD.plate() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER_CHASSIS), new Object[] { "PPP", "CBB", "PPP", 'P', ANY_PLASTIC.ingot(), 'C', ModItems.crt_display, 'B', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.PCB) });
if(!GeneralConfig.enable528) {
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP), new Object[] { "I", "S", "W", 'I', ModItems.plate_polymer, 'S', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.SILICON), 'W', CU.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP), new Object[] { "I", "S", "W", 'I', ModItems.plate_polymer, 'S', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.SILICON), 'W', GOLD.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_BISMOID), new Object[] { "III", "SNS", "WWW", 'I', ModItems.plate_polymer, 'S', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.SILICON), 'N', ANY_BISMOID.nugget(), 'W', CU.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_BISMOID), new Object[] { "III", "SNS", "WWW", 'I', ModItems.plate_polymer, 'S', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.SILICON), 'N', ANY_BISMOID.nugget(), 'W', GOLD.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_QUANTUM), new Object[] { "HHH", "SIS", "WWW", 'H', ANY_HARDPLASTIC.ingot(), 'S', BSCCO.wireDense(), 'I', ModItems.pellet_charged, 'W', CU.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP_QUANTUM), new Object[] { "HHH", "SIS", "WWW", 'H', ANY_HARDPLASTIC.ingot(), 'S', BSCCO.wireDense(), 'I', ModItems.pellet_charged, 'W', GOLD.wireFine() });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CONTROLLER_CHASSIS), new Object[] { "PPP", "CBB", "PPP", 'P', ANY_PLASTIC.ingot(), 'C', ModItems.crt_display, 'B', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.PCB) });
addRecipeAuto(DictFrame.fromOne(ModItems.circuit, EnumCircuitType.ATOMIC_CLOCK), new Object[] { "ICI", "CSC", "ICI", 'I', ModItems.plate_polymer, 'C', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.CHIP), 'S', SR.dust() });
}
addRecipeAuto(new ItemStack(ModItems.crt_display, 4), new Object[] { " A ", "SGS", " T ", 'A', AL.dust(), 'S', STEEL.plate(), 'G', KEY_ANYPANE, 'T', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.VACUUM_TUBE) });

View File

@ -7,13 +7,13 @@ import java.util.Map.Entry;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.recipes.AnnihilatorRecipes;
import com.hbm.util.ItemStackUtil;
import com.hbm.interfaces.NotableComments;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagByteArray;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
@ -42,31 +42,12 @@ public class AnnihilatorSavedData extends WorldSavedData {
String poolName = poolCompound.getString("poolname");
AnnihilatorPool pool = new AnnihilatorPool();
pool.deserialize(poolCompound.getTagList("pool", 7));
pool.deserialize(poolCompound.getTagList("pool", 10));
this.pools.put(poolName, pool);
}
}
/*
* woah nelly!
*
* ROOT NBT
* \
* POOLS LIST(COMPOUND) - all pools
* \
* POOL COMPOUND - pool + name association
* \
* POOLNAME STRING
* POOL LIST(LIST) - all item entries in a pool
* \
* PER-ITEM LIST(BYTEARRAY) - all data associated with one item
* \
* KEY ID
* KEY BYTES
* POOL SIZE BYTES
*/
@Override
public void writeToNBT(NBTTagCompound nbt) {
@ -104,25 +85,32 @@ public class AnnihilatorSavedData extends WorldSavedData {
}
/** For fluids */
public void pushToPool(String pool, FluidType type, long amount) {
public ItemStack pushToPool(String pool, FluidType type, long amount, boolean alwaysPayOut) {
AnnihilatorPool poolInstance = grabPool(pool);
poolInstance.increment(type, amount);
ItemStack payout = poolInstance.increment(type, amount, alwaysPayOut);
this.markDirty();
return payout;
}
/** For items (type + meta as well as only type), also handles ore dict */
public void pushToPool(String pool, ItemStack stack) {
public ItemStack pushToPool(String pool, ItemStack stack, boolean alwaysPayOut) {
AnnihilatorPool poolInstance = grabPool(pool);
poolInstance.increment(stack.getItem(), stack.stackSize);
poolInstance.increment(new ComparableStack(stack).makeSingular(), stack.stackSize);
ItemStack itemPayout = poolInstance.increment(stack.getItem(), stack.stackSize, alwaysPayOut);
ItemStack compPayout = poolInstance.increment(new ComparableStack(stack).makeSingular(), stack.stackSize, alwaysPayOut);
ItemStack dictPayout = null;
List<String> oreDict = ItemStackUtil.getOreDictNames(stack);
for(String name : oreDict) if(name != null && !name.isEmpty()) poolInstance.increment(name, stack.stackSize); // because some assholes pollute the ore dict with crap values
for(String name : oreDict) if(name != null && !name.isEmpty()) {
ItemStack payout = poolInstance.increment(name, stack.stackSize, alwaysPayOut); // because some assholes pollute the ore dict with crap values
if(payout != null) dictPayout = payout;
}
// originally a lookup for fluid containers was considered, but no one would use the annihilator like that, and it adds unnecessary overhead
this.markDirty();
return dictPayout != null ? dictPayout : compPayout != null ? compPayout : itemPayout;
}
public static class AnnihilatorPool {
@ -139,32 +127,36 @@ public class AnnihilatorSavedData extends WorldSavedData {
*/
public HashMap<Object, BigInteger> items = new HashMap();
public void increment(Object type, long amount) {
public ItemStack increment(Object type, long amount, boolean alwaysPayOut) {
ItemStack payout = null;
BigInteger counter = items.get(type);
if(counter == null) {
counter = BigInteger.valueOf(amount);
payout = AnnihilatorRecipes.getHighestPayoutFromKey(type, BigInteger.ZERO, counter);
} else {
BigInteger prev = counter;
counter = counter.add(BigInteger.valueOf(amount));
payout = AnnihilatorRecipes.getHighestPayoutFromKey(type, alwaysPayOut ? null : prev, counter);
}
items.put(type, counter);
return payout;
}
public void serialize(NBTTagList nbt) {
for(Entry<Object, BigInteger> entry : items.entrySet()) {
NBTTagList list = new NBTTagList();
serializeKey(list, entry.getKey());
list.appendTag(new NBTTagByteArray(entry.getValue().toByteArray()));
nbt.appendTag(list);
NBTTagCompound compound = new NBTTagCompound();
serializeKey(compound, entry.getKey());
compound.setByteArray("amount", entry.getValue().toByteArray());
nbt.appendTag(compound);
}
}
public void deserialize(NBTTagList nbt) {
try {
for(int i = 0; i < nbt.tagCount(); i++) {
NBTTagList list = (NBTTagList) nbt.tagList.get(i);
Object key = deserializeKey(list);
NBTTagByteArray ntba = (NBTTagByteArray) list.tagList.get(list.tagList.size() - 1);
if(key != null) this.items.put(key, new BigInteger(ntba.func_150292_c()));
NBTTagCompound compound = (NBTTagCompound) nbt.tagList.get(i);
Object key = deserializeKey(compound);
if(key != null) this.items.put(key, new BigInteger(compound.getByteArray("amount")));
}
} catch(Throwable ex) { } // because world data can be dented to all fucking hell and back
}
@ -173,67 +165,47 @@ public class AnnihilatorSavedData extends WorldSavedData {
* So what do? Shrimple, we use NBTTagLists. However, Mojang never expected lists to use different types, even though
* implementing a list like that would be really easy, so we just break down absolutely all information we have into
* byte arrays because the NBTTagList can handle those. God I hate this. */
public void serializeKey(NBTTagList list, Object key) {
public void serializeKey(NBTTagCompound nbt, Object key) {
if(key instanceof Item) { // 0
Item item = (Item) key;
list.appendTag(new NBTTagByteArray(new byte[] {0}));
list.appendTag(new NBTTagByteArray(Item.itemRegistry.getNameForObject(item).getBytes()));
nbt.setByte("key", (byte) 0);
nbt.setString("item", Item.itemRegistry.getNameForObject(item));
}
if(key instanceof ComparableStack) { // 1
ComparableStack item = (ComparableStack) key;
list.appendTag(new NBTTagByteArray(new byte[] {1}));
list.appendTag(new NBTTagByteArray(Item.itemRegistry.getNameForObject(item.item).getBytes()));
short meta = (short) item.meta;
list.appendTag(new NBTTagByteArray(new byte[] {
(byte) ((meta & 0xFF00) << 8),
(byte) (meta & 0x00FF)
})); // HSB and LSB may not be split "fairly" due to sign bit, but we do not care, we just want to store bits
ComparableStack comp = (ComparableStack) key;
nbt.setByte("key", (byte) 1);
nbt.setString("item", Item.itemRegistry.getNameForObject(comp.item));
nbt.setShort("meta", (short) comp.meta);
}
if(key instanceof FluidType) { // 2
FluidType item = (FluidType) key;
list.appendTag(new NBTTagByteArray(new byte[] {2}));
list.appendTag(new NBTTagByteArray(item.getUnlocalizedName().getBytes()));
FluidType type = (FluidType) key;
nbt.setByte("key", (byte) 2);
nbt.setString("fluid", type.getUnlocalizedName());
}
if(key instanceof String) { // 3
String item = (String) key;
list.appendTag(new NBTTagByteArray(new byte[] {3}));
list.appendTag(new NBTTagByteArray(item.getBytes()));
nbt.setByte("key", (byte) 3);
nbt.setString("dict", (String) key);
}
}
public Object deserializeKey(NBTTagList list) {
public Object deserializeKey(NBTTagCompound nbt) {
try {
int size = list.tagCount();
if(size <= 0) return null;
byte key = ((NBTTagByteArray) list.tagList.get(0)).func_150292_c()[0]; // i am pissing myself from all these assumptions
byte key = nbt.getByte("key");
if(key == 0) { // item
byte[] bytes = ((NBTTagByteArray) list.tagList.get(1)).func_150292_c();
Item item = (Item) Item.itemRegistry.getObject(new String(bytes)); // not specifying a charset is probably dangerous for multiple
// reasons but given that i don't really think the charset should change serverside, i *think* this should work
return item;
return Item.itemRegistry.getObject(nbt.getString("item"));
}
if(key == 1) { // comparablestack
byte[] itembytes = ((NBTTagByteArray) list.tagList.get(1)).func_150292_c();
byte[] metabytes = ((NBTTagByteArray) list.tagList.get(2)).func_150292_c();
Item item = (Item) Item.itemRegistry.getObject(new String(itembytes));
//short hsb = (short) (((short) metabytes[0]) << 8);
//short lsb = (short) metabytes[1];
short meta = (short) ((metabytes[0] << 8) | (metabytes[1] & 0xFF));
return new ComparableStack(item, 1, meta);
return new ComparableStack((Item) Item.itemRegistry.getObject(nbt.getString("item")), 1, nbt.getShort("meta"));
}
if(key == 2) { // fluidtype
byte[] bytes = ((NBTTagByteArray) list.tagList.get(1)).func_150292_c();
FluidType type = Fluids.fromName(new String(bytes));
return type;
return Fluids.fromName(nbt.getString("fluid"));
}
if(key == 3) {
byte[] bytes = ((NBTTagByteArray) list.tagList.get(1)).func_150292_c();
String type = new String(bytes);
return type;
return nbt.getString("dict");
}
// i feel filthy

View File

@ -1,22 +1,34 @@
package com.hbm.tileentity.machine;
import java.math.BigInteger;
import com.hbm.inventory.RecipesCommon.ComparableStack;
import com.hbm.inventory.container.ContainerMachineAnnihilator;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.inventory.gui.GUIMachineAnnihilator;
import com.hbm.items.machine.IItemFluidIdentifier;
import com.hbm.saveddata.AnnihilatorSavedData;
import com.hbm.saveddata.AnnihilatorSavedData.AnnihilatorPool;
import com.hbm.tileentity.IGUIProvider;
import com.hbm.tileentity.TileEntityMachineBase;
import com.hbm.util.ParticleUtil;
import com.hbm.util.fauxpointtwelve.DirPos;
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
import api.hbm.fluidmk2.IFluidStandardReceiverMK2;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityMachineAnnihilator extends TileEntityMachineBase implements IFluidStandardReceiverMK2, IGUIProvider {
@ -24,11 +36,12 @@ public class TileEntityMachineAnnihilator extends TileEntityMachineBase implemen
public int timer;
public FluidTank tank;
public BigInteger monitorBigInt = BigInteger.ZERO;
public TileEntityMachineAnnihilator() {
super(11);
this.tank = new FluidTank(Fluids.NONE, 256_000);
this.tank = new FluidTank(Fluids.NONE, 2_500_000);
}
@Override
@ -45,15 +58,57 @@ public class TileEntityMachineAnnihilator extends TileEntityMachineBase implemen
if(this.pool != null && !this.pool.isEmpty()) {
for(DirPos pos : getConPos()) {
if(tank.getTankType() != Fluids.NONE) this.trySubscribe(tank.getTankType(), worldObj, pos);
}
AnnihilatorSavedData data = AnnihilatorSavedData.getData(worldObj);
boolean didSomething = false;
if(slots[0] != null) {
AnnihilatorSavedData.getData(worldObj).pushToPool(pool, slots[0]);
tryAddPayout(data.pushToPool(pool, slots[0], false));
this.slots[0] = null;
this.markChanged();
didSomething = true;
}
if(tank.getFill() > 0) {
AnnihilatorSavedData.getData(worldObj).pushToPool(pool, tank.getTankType(), tank.getFill());
tryAddPayout(data.pushToPool(pool, tank.getTankType(), tank.getFill(), false));
tank.setFill(0);
this.markChanged();
didSomething = true;
}
if(didSomething) {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ParticleUtil.spawnGasFlame(worldObj, this.xCoord + 0.5 - dir.offsetX * 3, this.yCoord + 8.75, this.zCoord + 0.5 - dir.offsetZ * 3, worldObj.rand.nextGaussian() * 0.05, 0.1, worldObj.rand.nextGaussian() * 0.05);
if(worldObj.getTotalWorldTime() % 3 == 0)
this.worldObj.playSoundEffect(this.xCoord + 0.5 - dir.offsetX * 3, this.yCoord + 8.75, this.zCoord + 0.5 - dir.offsetZ * 3, "hbm:weapon.flamethrowerShoot", getVolume(1F), 0.5F + worldObj.rand.nextFloat() * 0.25F);
}
if(slots[8] != null) {
if(slots[8].getItem() instanceof IItemFluidIdentifier) {
IItemFluidIdentifier id = (IItemFluidIdentifier) slots[8].getItem();
FluidType type = id.getType(worldObj, xCoord, yCoord, zCoord, slots[8]);
monitor(data, type);
} else {
monitor(data, new ComparableStack(slots[8]).makeSingular());
}
}
if(slots[9] != null) {
ItemStack single = slots[9].copy();
single.stackSize = 1;
ItemStack payout = data.pushToPool(pool, single, true);
this.decrStackSize(9, 1);
if(payout != null) {
if(slots[10] == null) {
slots[10] = payout;
} else if(slots[10] != null && slots[10].getItem() == payout.getItem() && slots[10].getItemDamage() == payout.getItemDamage() &&
ItemStack.areItemStackTagsEqual(slots[10], payout) && slots[10].getMaxStackSize() >= slots[10].stackSize + payout.stackSize) {
slots[10].stackSize += payout.stackSize;
}
}
}
}
@ -61,33 +116,126 @@ public class TileEntityMachineAnnihilator extends TileEntityMachineBase implemen
}
}
public DirPos[] getConPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new DirPos[] {
new DirPos(xCoord + dir.offsetX * 5, yCoord, zCoord + dir.offsetZ * 5, dir),
new DirPos(xCoord + dir.offsetX * 3 + rot.offsetX * 2, yCoord, zCoord + dir.offsetZ * 3 + rot.offsetZ * 2, rot),
new DirPos(xCoord + dir.offsetX * 3 - rot.offsetX * 2, yCoord, zCoord + dir.offsetZ * 3 - rot.offsetZ * 2, rot.getOpposite())
};
}
public void monitor(AnnihilatorSavedData data, Object type) {
AnnihilatorPool pool = data.pools.get(this.pool);
if(pool != null) {
this.monitorBigInt = pool.items.get(type);
if(this.monitorBigInt == null) this.monitorBigInt = BigInteger.ZERO;
}
}
public void tryAddPayout(ItemStack payout) {
if(payout == null) return;
for(int i = 2; i <= 7; i++) {
if(slots[i] != null && slots[i].getItem() == payout.getItem() && slots[i].getItemDamage() == payout.getItemDamage() &&
ItemStack.areItemStackTagsEqual(slots[i], payout) && slots[i].getMaxStackSize() >= slots[i].stackSize + payout.stackSize) {
slots[i].stackSize += payout.stackSize;
this.markDirty();
return;
}
}
for(int i = 2; i <= 7; i++) {
if(slots[i] == null) {
slots[i] = payout;
this.markDirty();
return;
}
}
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
if(slot == 0) return true; // trash
if(slot == 1 && stack.getItem() instanceof IItemFluidIdentifier) return true;
if(slot == 8) return true; // monitor
if(slot == 9) return true; // payout request
return false;
}
@Override
public boolean canExtractItem(int slot, ItemStack itemStack, int side) {
return slot >= 2 && slot <= 7;
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return new int[] {0};
return new int[] {0, 2, 3, 4, 5, 6, 7};
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
this.tank.readFromNBT(nbt, "t");
this.pool = nbt.getString("pool");
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
this.tank.writeToNBT(nbt, "t");
nbt.setString("pool", pool);
}
@Override
public void serialize(ByteBuf buf) {
super.serialize(buf);
ByteBufUtils.writeUTF8String(buf, this.pool == null ? "" : this.pool);
byte[] array = this.monitorBigInt.toByteArray();
buf.writeInt(array.length);
for(byte b : array) buf.writeByte(b);
}
@Override
public void deserialize(ByteBuf buf) {
super.deserialize(buf);
this.pool = ByteBufUtils.readUTF8String(buf);
byte[] array = new byte[buf.readInt()];
for(int i = 0 ; i < array.length; i++) array[i] = buf.readByte();
this.monitorBigInt = new BigInteger(array);
}
@Override public FluidTank[] getAllTanks() { return new FluidTank[] {tank}; }
@Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {tank}; }
@Override public ConnectionPriority getFluidPriority() { return ConnectionPriority.LOW; }
@Override public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { return new ContainerMachineAnnihilator(player.inventory, this); }
@Override @SideOnly(Side.CLIENT) public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUIMachineAnnihilator(player.inventory, this); }
AxisAlignedBB bb = null;
@Override
public AxisAlignedBB getRenderBoundingBox() {
if(bb == null) {
bb = AxisAlignedBB.getBoundingBox(
xCoord - 5,
yCoord,
zCoord - 5,
xCoord + 6,
yCoord + 8,
zCoord + 6
);
}
return bb;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
}

View File

@ -17,6 +17,7 @@ import com.hbm.tileentity.IFluidCopiable;
import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.util.fauxpointtwelve.DirPos;
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
import api.hbm.fluid.IFluidStandardReceiver;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -125,6 +126,7 @@ public class TileEntityMachineDrain extends TileEntityLoadedBase implements IFlu
@Override public FluidTank[] getAllTanks() { return new FluidTank[] {tank}; }
@Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {tank}; }
@Override public ConnectionPriority getFluidPriority() { return ConnectionPriority.LOW; }
@Override
public boolean canConnect(FluidType type, ForgeDirection dir) {

View File

@ -28,6 +28,7 @@ import com.hbm.util.fauxpointtwelve.DirPos;
import com.hbm.util.i18n.I18nUtil;
import api.hbm.energymk2.IEnergyProviderMK2;
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
import api.hbm.fluid.IFluidStandardReceiver;
import api.hbm.tile.IInfoProviderEC;
import cpw.mods.fml.relauncher.Side;
@ -294,6 +295,11 @@ public class TileEntityMachineGasFlare extends TileEntityMachineBase implements
return new FluidTank[] { tank };
}
@Override
public ConnectionPriority getFluidPriority() {
return ConnectionPriority.LOW;
}
@Override
public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) {
return new ContainerMachineGasFlare(player.inventory, this);

View File

@ -312,9 +312,7 @@ chem.XENON_OXY=Verbessertes Lindeverfahren (Xenon)
chem.YELLOWCAKE=Yellowcakeproduktion
container.ammoBag=Mun-Tasche
container.amsBase=AMS-Basis (Deko)
container.amsEmitter=AMS-Emitter (Deko)
container.amsLimiter=AMS-Stabilisator (Deko)
container.annihilator=Vernichter
container.anvil=Stufe %s Amboss
container.arcFurnace=Lichtbogenofen
container.armorTable=Rüstungsmodifikationstisch
@ -4441,6 +4439,7 @@ tile.leaves_layer.name=Totes Laub
tile.lox_barrel.name=LOX-Fass
tile.machine_amgen.name=Umgebungsstrahlungs-Generator
tile.machine_ammo_press.name=Munitionspresse
tile.machine_annihilator.name=Vernichter
tile.machine_arc_furnace.name=Electrischer Lichtbogenofen
tile.machine_arc_furnace_off.name=Lichtbogenofen
tile.machine_arc_furnace_on.name=Lichtbogenofen

View File

@ -717,9 +717,7 @@ commands.locate.none_found=No structures found nearby!
commands.locate.success.coordinates=Structure %s found at %d, %d
container.ammoBag=Ammo Bag
container.amsBase=AMS Base (Deco)
container.amsEmitter=AMS Emitter (Deco)
container.amsLimiter=AMS Stabilizer (Deco)
container.annihilator=Annihilator
container.anvil=Tier %s Anvil
container.arcFurnace=Arc Furnace
container.armorTable=Armor Modification Table
@ -5703,6 +5701,7 @@ tile.lightstone_bricks_stairs.name=Lightstone Brick Stairs
tile.lox_barrel.name=LOX Barrel
tile.machine_amgen.name=Ambience Radiation Generator
tile.machine_ammo_press.name=Ammo Press
tile.machine_annihilator.name=Annihilator
tile.machine_arc_furnace.name=Electric Arc Furnace
tile.machine_arc_furnace_off.name=Arc Furnace
tile.machine_arc_furnace_on.name=Arc Furnace

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 2.1 KiB