From d0e90250c5d02249e60667aab2906a8b8e6c6ba3 Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 19 Mar 2024 21:20:53 +0100 Subject: [PATCH] loot pool config system --- changelog | 1 + .../hbm/commands/CommandReloadRecipes.java | 2 + .../com/hbm/config/ItemPoolConfigJSON.java | 151 ++++++++++++++++++ src/main/java/com/hbm/itempool/ItemPool.java | 53 ++++++ .../com/hbm/itempool/ItemPoolsLegacy.java | 52 ++++++ .../java/com/hbm/lib/HbmChestContents.java | 30 ++-- src/main/java/com/hbm/main/MainRegistry.java | 3 + 7 files changed, 278 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/hbm/config/ItemPoolConfigJSON.java create mode 100644 src/main/java/com/hbm/itempool/ItemPool.java create mode 100644 src/main/java/com/hbm/itempool/ItemPoolsLegacy.java diff --git a/changelog b/changelog index f05221f27..5e7ab9b3a 100644 --- a/changelog +++ b/changelog @@ -32,6 +32,7 @@ * Instead of randomizing directions, schottky diodes will now split particles into "virtual particles" which take mutliple paths at once * The particles will collapse as soon as the first virtual particle with a valid outcome reaches the end * This change allows branching accelerators to be made, where the particle will always take the shortest path necessary to complete the operation. In essence, it allows a single accelerator to do any recipe, without requiring to power the entire accelerator, as only the path of the finishing particle will use up energy. +* The particle accelerator as well as the schottky particle diodes now have presentations explaining how they work ## Fixed * WarTec should now be compatible again diff --git a/src/main/java/com/hbm/commands/CommandReloadRecipes.java b/src/main/java/com/hbm/commands/CommandReloadRecipes.java index ea28801d5..8b2a939eb 100644 --- a/src/main/java/com/hbm/commands/CommandReloadRecipes.java +++ b/src/main/java/com/hbm/commands/CommandReloadRecipes.java @@ -1,5 +1,6 @@ package com.hbm.commands; +import com.hbm.config.ItemPoolConfigJSON; import com.hbm.inventory.recipes.loader.SerializableRecipe; import com.hbm.util.ChatBuilder; @@ -24,6 +25,7 @@ public class CommandReloadRecipes extends CommandBase { public void processCommand(ICommandSender sender, String[] args) { try { SerializableRecipe.initialize(); + ItemPoolConfigJSON.initialize(); sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Reload complete :)")); } catch(Exception ex) { sender.addChatMessage(ChatBuilder.start("----------------------------------").color(EnumChatFormatting.GRAY).flush()); diff --git a/src/main/java/com/hbm/config/ItemPoolConfigJSON.java b/src/main/java/com/hbm/config/ItemPoolConfigJSON.java new file mode 100644 index 000000000..849968062 --- /dev/null +++ b/src/main/java/com/hbm/config/ItemPoolConfigJSON.java @@ -0,0 +1,151 @@ +package com.hbm.config; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map.Entry; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.stream.JsonWriter; +import com.hbm.itempool.ItemPool; +import com.hbm.itempool.ItemPoolsLegacy; +import com.hbm.items.ModItems; +import com.hbm.main.MainRegistry; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.WeightedRandomChestContent; + +public class ItemPoolConfigJSON { + + public static final Gson gson = new Gson(); + public static HashMap pools = new HashMap(); + + public static void initialize() { + File folder = MainRegistry.configHbmDir; + + File config = new File(folder.getAbsolutePath() + File.separatorChar + "hbmItemPools.json"); + File template = new File(folder.getAbsolutePath() + File.separatorChar + "_hbmItemPools.json"); + + if(!config.exists()) { + writeDefault(template); + } else { + readConfig(config); + } + + for(Entry entry : pools.entrySet()) { + System.out.println(entry.getKey()); + + for(WeightedRandomChestContent item : entry.getValue().pool) { + System.out.println(item.theItemId + " " + item.theItemId.stackTagCompound + " " + item.theMinimumChanceToGenerateItem + " " + item.theMaximumChanceToGenerateItem + " " + item.itemWeight); + } + } + } + + private static void writeDefault(File file) { + + try { + JsonWriter writer = new JsonWriter(new FileWriter(file)); + writer.setIndent(" "); + writer.beginObject(); + writer.name("pools").beginObject(); + + for(Entry entry : pools.entrySet()) { + writer.name(entry.getKey()).beginArray(); + + for(WeightedRandomChestContent content : entry.getValue().pool) { + writer.setIndent(" "); + writer.beginArray(); + writer.setIndent(""); + writeItemStack(content.theItemId, writer); + writer.setIndent(""); + writer.value(content.theMinimumChanceToGenerateItem); + writer.value(content.theMaximumChanceToGenerateItem); + writer.value(content.itemWeight); + writer.endArray(); + } + + writer.setIndent(" "); + writer.endArray(); + } + + writer.endObject(); + writer.endObject(); + writer.close(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + private static void readConfig(File file) { + HashMap newPools = new HashMap(); + try { + JsonObject json = gson.fromJson(new FileReader(file), JsonObject.class); + JsonObject pools = json.get("pools").getAsJsonObject(); + + for(Entry entry : pools.entrySet()) { + + String poolName = entry.getKey(); + ItemPool pool = new ItemPool(); + pool.name = poolName; + + for(JsonElement poolEntry : entry.getValue().getAsJsonArray()) { + JsonArray array = poolEntry.getAsJsonArray(); + ItemStack stack = readItemStack(array.get(0).getAsJsonArray()); + int min = array.get(1).getAsInt(); + int max = array.get(2).getAsInt(); + int weight = array.get(3).getAsInt(); + pool.add(stack, min, max, weight); + } + + pool.build(); + newPools.put(poolName, pool); + } + + ItemPoolConfigJSON.pools = newPools; + + } catch(Exception ex) { + ex.printStackTrace(); + } + } + + public static void writeItemStack(ItemStack stack, JsonWriter writer) throws IOException { + writer.beginArray(); + writer.setIndent(""); + writer.value(Item.itemRegistry.getNameForObject(stack.getItem())); + if(stack.stackSize != 1 || stack.getItemDamage() != 0 || stack.hasTagCompound()) writer.value(stack.stackSize); + if(stack.getItemDamage() != 0 || stack.hasTagCompound()) writer.value(stack.getItemDamage()); + if(stack.hasTagCompound()) writer.value(stack.stackTagCompound.toString()); + writer.endArray(); + writer.setIndent(" "); + } + + public static ItemStack readItemStack(JsonArray array) { + try { + Item item = (Item) Item.itemRegistry.getObject(array.get(0).getAsString()); + int stacksize = array.size() > 1 ? array.get(1).getAsInt() : 1; + int meta = array.size() > 2 ? array.get(2).getAsInt() : 0; + if(item != null) { + ItemStack stack = new ItemStack(item, stacksize, meta); + if(array.size() > 3) { + String tag = array.get(3).getAsString(); + NBTBase nbt = JsonToNBT.func_150315_a(tag); + if(nbt instanceof NBTTagCompound) { + stack.stackTagCompound = (NBTTagCompound) nbt; + } + } + return stack; + } + } catch(Exception ex) { } + MainRegistry.logger.error("Error reading stack array " + array.toString() + " - defaulting to NOTHING item!"); + return new ItemStack(ModItems.nothing); + } +} diff --git a/src/main/java/com/hbm/itempool/ItemPool.java b/src/main/java/com/hbm/itempool/ItemPool.java new file mode 100644 index 000000000..7d21ad6dd --- /dev/null +++ b/src/main/java/com/hbm/itempool/ItemPool.java @@ -0,0 +1,53 @@ +package com.hbm.itempool; + +import java.util.ArrayList; +import java.util.List; + +import com.hbm.config.ItemPoolConfigJSON; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.WeightedRandomChestContent; + +public class ItemPool { + + public String name; + public WeightedRandomChestContent[] pool = new WeightedRandomChestContent[0]; + + private List buildingList = new ArrayList(); + + public ItemPool() { } + + public ItemPool(String name) { + this.name = name; + ItemPoolConfigJSON.pools.put(name, this); + } + + public ItemPool add(Item item, int meta, int min, int max, int weight) { buildingList.add(new WeightedRandomChestContent(item, meta, min, max, weight)); return this; } + public ItemPool add(Block block, int meta, int min, int max, int weight) { buildingList.add(new WeightedRandomChestContent(Item.getItemFromBlock(block), meta, min, max, weight)); return this; } + public ItemPool add(ItemStack item, int min, int max, int weight) { buildingList.add(new WeightedRandomChestContent(item, min, max, weight)); return this; } + + public ItemPool build() { + + this.pool = new WeightedRandomChestContent[buildingList.size()]; + + for(int i = 0; i < pool.length; i++) { + this.pool[i] = this.buildingList.get(i); + } + + this.buildingList.clear(); + + return this; + } + + public static void initialize() { + //here we abuse java's lazy loading behavior, referencing the item pools with what is effectively a NOP in order to cause instantiation + //this of course has to happen after the items and blocks are registered but before the item pool config + //will this cause horrific issues if something manages to load the item pools prematurely? absolutely + //however, the advantage here is that i don't need to separate the fields from the instantiation, i can simply slap them together into the class and it works + //is this shitty coding practice? yes! but it's slightly more convenient than the alternative so i will roll with it anyway because go fuck yourself + //who are you to tell me what i can and cannot do + ItemPoolsLegacy.poolGeneric.hashCode(); + } +} diff --git a/src/main/java/com/hbm/itempool/ItemPoolsLegacy.java b/src/main/java/com/hbm/itempool/ItemPoolsLegacy.java new file mode 100644 index 000000000..f27b31bd5 --- /dev/null +++ b/src/main/java/com/hbm/itempool/ItemPoolsLegacy.java @@ -0,0 +1,52 @@ +package com.hbm.itempool; + +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ModItems; +import com.hbm.items.ItemAmmoEnums.Ammo357Magnum; + +import static com.hbm.lib.HbmChestContents.*; + +import net.minecraft.init.Items; +import net.minecraft.util.WeightedRandomChestContent; + +/** + * Item pools for "legacy" structures, i.e. schematic2java ones + * @author hbm + * + */ +public class ItemPoolsLegacy { + + //"generic" set, found commonly in chests in many structures + public static ItemPool poolGeneric = new ItemPool("POOL_GENERIC") {{ + this.pool = new WeightedRandomChestContent[] { + weighted(Items.bread, 0, 1, 5, 8), + weighted(ModItems.twinkie, 0, 1, 3, 6), + weighted(Items.iron_ingot, 0, 2, 6, 10), + weighted(ModItems.ingot_steel, 0, 2, 5, 7), + weighted(ModItems.ingot_beryllium, 0, 1, 2, 4), + weighted(ModItems.ingot_titanium, 0, 1, 1, 3), + weighted(ModItems.circuit_targeting_tier1, 0, 1, 1, 5), + weighted(ModItems.gun_revolver, 0, 1, 1, 3), + weighted(ModItems.ammo_357, Ammo357Magnum.LEAD.ordinal(), 2, 6, 4), + weighted(ModItems.gun_kit_1, 0, 1, 3, 4), + weighted(ModItems.gun_lever_action, 0, 1, 1, 1), + weighted(ModItems.ammo_20gauge, 0, 2, 6, 3), + weighted(ModItems.casing_9, 0, 4, 10, 3), + weighted(ModItems.casing_50, 0, 4, 10, 3), + weighted(ModItems.cordite, 0, 4, 6, 5), + weighted(ModItems.battery_generic, 0, 1, 1, 4), + weighted(ModItems.battery_advanced, 0, 1, 1, 2), + weighted(ModItems.scrap, 0, 1, 3, 10), + weighted(ModItems.dust, 0, 2, 4, 9), + weighted(ModItems.bottle_opener, 0, 1, 1, 2), + weighted(ModItems.bottle_nuka, 0, 1, 3, 4), + weighted(ModItems.bottle_cherry, 0, 1, 1, 2), + weighted(ModItems.stealth_boy, 0, 1, 1, 1), + weighted(ModItems.cap_nuka, 0, 1, 15, 7), + weighted(ModItems.canister_full, Fluids.DIESEL.getID(), 1, 2, 2), + weighted(ModItems.canister_full, Fluids.BIOFUEL.getID(), 1, 2, 3), + weighted(ModItems.gas_mask_m65, 60, 1, 1, 2), + weighted(ModItems.gas_mask_filter, 0, 1, 1, 3) + }; + }}; +} diff --git a/src/main/java/com/hbm/lib/HbmChestContents.java b/src/main/java/com/hbm/lib/HbmChestContents.java index 6131bcb9a..d77fb7647 100644 --- a/src/main/java/com/hbm/lib/HbmChestContents.java +++ b/src/main/java/com/hbm/lib/HbmChestContents.java @@ -13,6 +13,7 @@ import com.hbm.items.machine.ItemZirnoxRod.EnumZirnoxType; import com.hbm.items.special.ItemBookLore; import com.hbm.items.tool.ItemBlowtorch; +import net.minecraft.block.Block; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -85,10 +86,10 @@ public class HbmChestContents { weighted(ModItems.battery_advanced, 0, 1, 1, 3), weighted(ModItems.powder_iodine, 0, 1, 1, 1), weighted(ModItems.powder_bromine, 0, 1, 1, 1), - weighted(Item.getItemFromBlock(ModBlocks.steel_poles), 0, 1, 4, 8), - weighted(Item.getItemFromBlock(ModBlocks.steel_scaffold), 0, 1, 3, 8), - weighted(Item.getItemFromBlock(ModBlocks.pole_top), 0, 1, 1, 4), - weighted(Item.getItemFromBlock(ModBlocks.pole_satellite_receiver), 0, 1, 1, 7), + weighted(ModBlocks.steel_poles, 0, 1, 4, 8), + weighted(ModBlocks.steel_scaffold, 0, 1, 3, 8), + weighted(ModBlocks.pole_top, 0, 1, 1, 4), + weighted(ModBlocks.pole_satellite_receiver, 0, 1, 1, 7), weighted(ModItems.scrap, 0, 1, 3, 10), weighted(ModItems.dust, 0, 2, 4, 9), weighted(ModItems.bottle_opener, 0, 1, 1, 2), @@ -124,7 +125,7 @@ public class HbmChestContents { weighted(ModItems.fusion_core, 0, 1, 1, 4), weighted(ModItems.bottle_nuka, 0, 1, 3, 6), weighted(ModItems.bottle_quantum, 0, 1, 1, 3), - weighted(Item.getItemFromBlock(ModBlocks.red_barrel), 0, 1, 1, 6), + weighted(ModBlocks.red_barrel, 0, 1, 1, 6), weighted(ModItems.canister_full, Fluids.DIESEL.getID(), 1, 2, 2), weighted(ModItems.canister_full, Fluids.BIOFUEL.getID(), 1, 2, 3), weighted(ModItems.gas_mask_m65, 60, 1, 1, 5), @@ -146,7 +147,7 @@ public class HbmChestContents { weighted(ModItems.gas_mask_m65, 60, 1, 1, 5), weighted(ModItems.hazmat_kit, 0, 1, 1, 1), weighted(ModItems.gas_mask_filter, 0, 1, 1, 5), - weighted(Item.getItemFromBlock(ModBlocks.yellow_barrel), 0, 1, 1, 2) }; + weighted(ModBlocks.yellow_barrel, 0, 1, 1, 2) }; public static WeightedRandomChestContent[] nuclearFuel = new WeightedRandomChestContent[] { weighted(ModItems.billet_uranium, 0, 1, 4, 4), @@ -190,7 +191,7 @@ public class HbmChestContents { weighted(ModItems.gas_mask_m65, 60, 1, 1, 5), weighted(ModItems.hazmat_kit, 0, 1, 1, 2), weighted(ModItems.gas_mask_filter, 0, 1, 1, 5), - weighted(Item.getItemFromBlock(ModBlocks.yellow_barrel), 0, 1, 3, 3) }; + weighted(ModBlocks.yellow_barrel, 0, 1, 3, 3) }; public static WeightedRandomChestContent[] vertibird = new WeightedRandomChestContent[] { weighted(ModItems.t45_helmet, 0, 1, 1, 15), @@ -245,12 +246,12 @@ public class HbmChestContents { weighted(ModItems.cell_antimatter, 0, 1, 1, 1), weighted(ModItems.powder_neodymium, 0, 1, 1, 1), weighted(ModItems.powder_niobium, 0, 1, 1, 1), - weighted(Item.getItemFromBlock(ModBlocks.fusion_conductor), 0, 2, 4, 5), - weighted(Item.getItemFromBlock(ModBlocks.fusion_heater), 0, 1, 3, 5), - weighted(Item.getItemFromBlock(ModBlocks.pwr_fuel), 0, 1, 2, 5), - weighted(Item.getItemFromBlock(ModBlocks.block_tungsten), 0, 3, 8, 5), - weighted(Item.getItemFromBlock(ModBlocks.red_wire_coated), 0, 4, 8, 5), - weighted(Item.getItemFromBlock(ModBlocks.red_cable), 0, 8, 16, 5) }; + weighted(ModBlocks.fusion_conductor, 0, 2, 4, 5), + weighted(ModBlocks.fusion_heater, 0, 1, 3, 5), + weighted(ModBlocks.pwr_fuel, 0, 1, 2, 5), + weighted(ModBlocks.block_tungsten, 0, 3, 8, 5), + weighted(ModBlocks.red_wire_coated, 0, 4, 8, 5), + weighted(ModBlocks.red_cable, 0, 8, 16, 5) }; public static WeightedRandomChestContent[] powder = new WeightedRandomChestContent[] { weighted(ModItems.powder_neptunium, 0, 1, 32, 1), @@ -410,8 +411,9 @@ public class HbmChestContents { weighted(Items.book, 0, 1, 5, 10), weighted(Items.experience_bottle, 0, 1, 3, 1), }; - + public static WeightedRandomChestContent weighted(Item item, int meta, int min, int max, int weight) { return new WeightedRandomChestContent(item, meta, min, max, weight); } + public static WeightedRandomChestContent weighted(Block block, int meta, int min, int max, int weight) { return new WeightedRandomChestContent(Item.getItemFromBlock(block), meta, min, max, weight); } public static WeightedRandomChestContent weighted(ItemStack item, int min, int max, int weight) { return new WeightedRandomChestContent(item, min, max, weight); } /** ITEMBOOKLORE SHIT */ diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index 8f815d14e..27763384c 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -29,6 +29,7 @@ import com.hbm.inventory.material.Mats; import com.hbm.inventory.recipes.*; import com.hbm.inventory.recipes.anvil.AnvilRecipes; import com.hbm.inventory.recipes.loader.SerializableRecipe; +import com.hbm.itempool.ItemPool; import com.hbm.items.ItemAmmoEnums.Ammo4Gauge; import com.hbm.items.ItemEnums.EnumAchievementType; import com.hbm.items.ModItems; @@ -861,6 +862,8 @@ public class MainRegistry { RadiolysisRecipes.registerRadiolysis(); FalloutConfigJSON.initialize(); + ItemPool.initialize(); + ItemPoolConfigJSON.initialize(); TileEntityNukeCustom.registerBombItems(); ArmorUtil.register();