diff --git a/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java b/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java new file mode 100644 index 000000000..a849ed3c2 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java @@ -0,0 +1,503 @@ +package ru.dbotthepony.mc.otm; + +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraftforge.event.entity.player.ItemTooltipEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; +import ru.dbotthepony.mc.otm.menu.FormattingHelper; + +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.*; + +public class MatterRegistry { + public static final Map INITIAL_ITEMS = new HashMap<>(); + public static final Map ITEMS = new HashMap<>(); + + public static BigDecimal getMatterValue(Item item) { + return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, BigDecimal.ZERO)); + } + + public static BigDecimal getMatterValue(ItemStack stack) { + Item item = stack.getItem(); + + if (item.isDamageable(stack)) { + return getMatterValue(item).multiply(BigDecimal.ONE.subtract(new BigDecimal(item.getDamage(stack)).divide(new BigDecimal(item.getMaxDamage(stack)), ROUND_RULES))); + } + + return getMatterValue(item); + } + + public static void registerInitialItems() { + // basic things + INITIAL_ITEMS.put(Items.DIRT, new BigDecimal("0.0013")); + INITIAL_ITEMS.put(Items.DIRT_PATH, new BigDecimal("0.0013")); + INITIAL_ITEMS.put(Items.GRASS_BLOCK, new BigDecimal("0.0016")); + + INITIAL_ITEMS.put(Items.POINTED_DRIPSTONE, new BigDecimal("0.0007")); + + INITIAL_ITEMS.put(Items.STONE, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.COBBLESTONE, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.NETHERRACK, new BigDecimal("0.00027")); + INITIAL_ITEMS.put(Items.GRANITE, new BigDecimal("0.0011")); + INITIAL_ITEMS.put(Items.DIORITE, new BigDecimal("0.0013")); + INITIAL_ITEMS.put(Items.ANDESITE, new BigDecimal("0.0012")); + INITIAL_ITEMS.put(Items.BASALT, new BigDecimal("0.0013")); + + INITIAL_ITEMS.put(Items.SOUL_SAND, new BigDecimal("0.00087")); + INITIAL_ITEMS.put(Items.SOUL_SOIL, new BigDecimal("0.00087")); + + INITIAL_ITEMS.put(Items.ICE, new BigDecimal("0.0002")); + + INITIAL_ITEMS.put(Items.GRAVEL, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.FLINT, new BigDecimal("0.001")); + + INITIAL_ITEMS.put(Items.SAND, new BigDecimal("0.0005")); + INITIAL_ITEMS.put(Items.RED_SAND, new BigDecimal("0.0005")); + + INITIAL_ITEMS.put(Items.TUFF, new BigDecimal("0.0007")); + INITIAL_ITEMS.put(Items.DEEPSLATE, new BigDecimal("0.0014")); + INITIAL_ITEMS.put(Items.COBBLED_DEEPSLATE, new BigDecimal("0.0014")); + + INITIAL_ITEMS.put(Items.BLACKSTONE, new BigDecimal("0.0015")); + + INITIAL_ITEMS.put(Items.INFESTED_STONE, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_COBBLESTONE, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new BigDecimal("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new BigDecimal("0.067")); + + // affected by luck enchantment, thus can be duped + // INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new BigDecimal("0.037")); + INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new BigDecimal("0.34")); + + // assuming it is very light since it is floating + INITIAL_ITEMS.put(Items.END_STONE, new BigDecimal("0.0004")); + + INITIAL_ITEMS.put(Items.OBSIDIAN, new BigDecimal("0.038")); + + // metallic / chemical things + INITIAL_ITEMS.put(Items.COAL, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new BigDecimal("0.0042")); + INITIAL_ITEMS.put(Items.REDSTONE, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.CHARCOAL, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.DIAMOND, new BigDecimal("0.5")); + INITIAL_ITEMS.put(Items.EMERALD, new BigDecimal("0.46")); + INITIAL_ITEMS.put(Items.IRON_INGOT, new BigDecimal("0.03")); + INITIAL_ITEMS.put(Items.COPPER_INGOT, new BigDecimal("0.014")); + INITIAL_ITEMS.put(Items.GOLD_INGOT, new BigDecimal("0.32")); + INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new BigDecimal("1.2")); + INITIAL_ITEMS.put(Items.QUARTZ, new BigDecimal("0.008")); + INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new BigDecimal("0.007")); + INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new BigDecimal("0.034")); + + // living things + INITIAL_ITEMS.put(Items.MOSS_BLOCK, new BigDecimal("0.0012")); + + INITIAL_ITEMS.put(Items.OAK_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.SPRUCE_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.BIRCH_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.JUNGLE_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.ACACIA_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.DARK_OAK_LOG, new BigDecimal("0.005")); + + INITIAL_ITEMS.put(Items.BAMBOO, new BigDecimal("0.00085")); + + INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new BigDecimal("0.003")); + INITIAL_ITEMS.put(Items.WARPED_PLANKS, new BigDecimal("0.003")); + + INITIAL_ITEMS.put(Items.STRIPPED_OAK_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_SPRUCE_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_DARK_OAK_LOG, new BigDecimal("0.005")); + + INITIAL_ITEMS.put(Items.CACTUS, new BigDecimal("0.0039")); + INITIAL_ITEMS.put(Items.PUMPKIN, new BigDecimal("0.005")); + INITIAL_ITEMS.put(Items.MELON, new BigDecimal("0.005")); + + // flowers! + final BigDecimal flower_value = new BigDecimal("0.0031"); + INITIAL_ITEMS.put(Items.DANDELION, flower_value); + INITIAL_ITEMS.put(Items.POPPY, flower_value); + INITIAL_ITEMS.put(Items.BLUE_ORCHID, flower_value); + INITIAL_ITEMS.put(Items.ALLIUM, flower_value); + INITIAL_ITEMS.put(Items.AZURE_BLUET, flower_value); + INITIAL_ITEMS.put(Items.RED_TULIP, flower_value); + INITIAL_ITEMS.put(Items.ORANGE_TULIP, flower_value); + INITIAL_ITEMS.put(Items.WHITE_TULIP, flower_value); + INITIAL_ITEMS.put(Items.PINK_TULIP, flower_value); + INITIAL_ITEMS.put(Items.OXEYE_DAISY, flower_value); + INITIAL_ITEMS.put(Items.CORNFLOWER, flower_value); + INITIAL_ITEMS.put(Items.LILY_OF_THE_VALLEY, flower_value); + + final BigDecimal big_flower_value = new BigDecimal("0.0042"); + INITIAL_ITEMS.put(Items.SUNFLOWER, big_flower_value); + INITIAL_ITEMS.put(Items.LILAC, big_flower_value); + INITIAL_ITEMS.put(Items.ROSE_BUSH, big_flower_value); + INITIAL_ITEMS.put(Items.PEONY, big_flower_value); + + INITIAL_ITEMS.put(Items.SPORE_BLOSSOM, new BigDecimal("0.0067")); + INITIAL_ITEMS.put(Items.BROWN_MUSHROOM, new BigDecimal("0.0034")); + INITIAL_ITEMS.put(Items.RED_MUSHROOM, new BigDecimal("0.0034")); + INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new BigDecimal("0.004")); + + // grass + final BigDecimal grass_value = new BigDecimal("0.0024"); + INITIAL_ITEMS.put(Items.CRIMSON_ROOTS, grass_value); + INITIAL_ITEMS.put(Items.WARPED_ROOTS, grass_value); + INITIAL_ITEMS.put(Items.NETHER_SPROUTS, new BigDecimal("0.002")); + INITIAL_ITEMS.put(Items.WEEPING_VINES, grass_value); + INITIAL_ITEMS.put(Items.TWISTING_VINES, grass_value); + INITIAL_ITEMS.put(Items.HANGING_ROOTS, grass_value); + INITIAL_ITEMS.put(Items.TALL_GRASS, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.LARGE_FERN, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.GRASS, grass_value); + INITIAL_ITEMS.put(Items.VINE, grass_value); + INITIAL_ITEMS.put(Items.LILY_PAD, grass_value); + INITIAL_ITEMS.put(Items.BIG_DRIPLEAF, grass_value); + INITIAL_ITEMS.put(Items.SMALL_DRIPLEAF, grass_value); + INITIAL_ITEMS.put(Items.SEA_PICKLE, grass_value); + INITIAL_ITEMS.put(Items.SEAGRASS, grass_value); + INITIAL_ITEMS.put(Items.FERN, grass_value); + INITIAL_ITEMS.put(Items.DEAD_BUSH, new BigDecimal("0.0017")); + INITIAL_ITEMS.put(Items.GLOW_LICHEN, new BigDecimal("0.0026")); + INITIAL_ITEMS.put(Items.AZALEA, new BigDecimal("0.0018")); + INITIAL_ITEMS.put(Items.FLOWERING_AZALEA, grass_value); + + // living plant (not very blocky) things + // saplings + INITIAL_ITEMS.put(Items.OAK_SAPLING, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new BigDecimal("0.0045")); + INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new BigDecimal("0.0048")); + INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new BigDecimal("0.0033")); + INITIAL_ITEMS.put(Items.DARK_OAK_SAPLING, new BigDecimal("0.005")); + + INITIAL_ITEMS.put(Items.WHEAT_SEEDS, new BigDecimal("0.0007")); + INITIAL_ITEMS.put(Items.BEETROOT_SEEDS, new BigDecimal("0.0007")); + // INITIAL_ITEMS.put(Items.MELON_SEEDS, new BigDecimal("0.0013")); + INITIAL_ITEMS.put(Items.WHEAT, new BigDecimal("0.0016")); + INITIAL_ITEMS.put(Items.NETHER_WART, new BigDecimal("0.0017")); + INITIAL_ITEMS.put(Items.CARROT, new BigDecimal("0.0019")); + INITIAL_ITEMS.put(Items.POTATO, new BigDecimal("0.0021")); + INITIAL_ITEMS.put(Items.BEETROOT, new BigDecimal("0.0021")); + INITIAL_ITEMS.put(Items.MELON_SLICE, new BigDecimal("0.0008")); + + INITIAL_ITEMS.put(Items.COCOA_BEANS, new BigDecimal("0.00035")); + INITIAL_ITEMS.put(Items.HONEYCOMB, new BigDecimal("0.0014")); + INITIAL_ITEMS.put(Items.SUGAR_CANE, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.APPLE, new BigDecimal("0.0061")); + INITIAL_ITEMS.put(Items.SWEET_BERRIES, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.GLOW_BERRIES, new BigDecimal("0.0041")); + INITIAL_ITEMS.put(Items.KELP, new BigDecimal("0.0009")); + + // living animal things + INITIAL_ITEMS.put(Items.STRING, new BigDecimal("0.0006")); + INITIAL_ITEMS.put(Items.COBWEB, new BigDecimal("0.0006")); + INITIAL_ITEMS.put(Items.INK_SAC, new BigDecimal("0.0009")); + INITIAL_ITEMS.put(Items.SPIDER_EYE, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.FEATHER, new BigDecimal("0.0007")); + INITIAL_ITEMS.put(Items.GUNPOWDER, new BigDecimal("0.003")); + INITIAL_ITEMS.put(Items.LEATHER, new BigDecimal("0.0065")); + INITIAL_ITEMS.put(Items.BONE, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.ENDER_PEARL, new BigDecimal("0.041")); + INITIAL_ITEMS.put(Items.GHAST_TEAR, new BigDecimal("0.023")); + INITIAL_ITEMS.put(Items.BLAZE_ROD, new BigDecimal("0.02")); + INITIAL_ITEMS.put(Items.SLIME_BALL, new BigDecimal("0.0015")); + INITIAL_ITEMS.put(Items.EGG, new BigDecimal("0.0011")); + + INITIAL_ITEMS.put(Items.PORKCHOP, new BigDecimal("0.0047")); + INITIAL_ITEMS.put(Items.BEEF, new BigDecimal("0.0047")); + INITIAL_ITEMS.put(Items.MUTTON, new BigDecimal("0.004")); + + INITIAL_ITEMS.put(Items.PUFFERFISH, new BigDecimal("0.013")); + INITIAL_ITEMS.put(Items.COD, new BigDecimal("0.013")); + INITIAL_ITEMS.put(Items.SALMON, new BigDecimal("0.013")); + INITIAL_ITEMS.put(Items.TROPICAL_FISH, new BigDecimal("0.013")); + + // building items + INITIAL_ITEMS.put(Items.CLAY_BALL, new BigDecimal("0.0006")); + INITIAL_ITEMS.put(Items.SNOWBALL, new BigDecimal("0.00041")); + + // loot + INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new BigDecimal("1.47")); + INITIAL_ITEMS.put(Items.TRIDENT, new BigDecimal("1.35")); + + /* + INITIAL_ITEMS.put(Items.WHITE_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.ORANGE_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.YELLOW_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.LIME_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.PINK_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.GRAY_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.CYAN_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.PURPLE_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.BLUE_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.BROWN_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.GREEN_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.RED_WOOL, new BigDecimal("0.004")); + INITIAL_ITEMS.put(Items.BLACK_WOOL, new BigDecimal("0.004")); + */ + + // INITIAL_ITEMS.put(Items.CRIMSON_LOG, new BigDecimal("0.005")); + // INITIAL_ITEMS.put(Items.WARPED_LOG, new BigDecimal("0.005")); + } + + private static void registerPostItem(Item item, Item base, BigDecimal multiplier) { + BigDecimal value = getMatterValue(base); + + if (!value.equals(BigDecimal.ZERO)) { + ITEMS.put(item, value.multiply(multiplier)); + } + } + + public static void registerPostItems() { + registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new BigDecimal("0.8")); + registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new BigDecimal("0.5")); + } + + private static final HashMap>> usages = new HashMap<>(); + private static final HashMap>> results = new HashMap<>(); + private static final HashMap seen_items = new HashMap<>(); + private static final HashMap seen_items_child = new HashMap<>(); + + public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.DOWN); + + private static boolean solve_occured = false; + private static Set defered_items = new HashSet<>(); + + private static int stack_index = 0; + private static Item[] scan_stack = new Item[1000]; + + @Nullable + private static BigDecimal determineValue(Item item) { + if (ITEMS.containsKey(item)) { + return ITEMS.get(item); + } + + if (INITIAL_ITEMS.containsKey(item)) { + return INITIAL_ITEMS.get(item); + } + + if (defered_items.contains(item)) { + return null; + } + + for (Item value : scan_stack) { + if (value == null) + break; + + if (value == item) { + // defer, we hit an recursive recipe + defered_items.add(item); + return null; + } + } + + if (seen_items.containsKey(item)) { + // OverdriveThatMatters.LOGGER.debug("Already seen: {}", item); + seen_items.put(item, seen_items.get(item) + 1); + + if (seen_items_child.containsKey(item)) { + for (Item child : seen_items_child.values()) { + seen_items.put(child, seen_items.get(child) + 1); + } + } + + return BigDecimal.ZERO; + } + + seen_items.put(item, 0); + + if (!results.containsKey(item)) { + return BigDecimal.ZERO; + } + + scan_stack[stack_index] = item; + stack_index++; + + boolean defer_occured = false; + + BigDecimal smallest_possible_total = null; + + for (Recipe recipe : results.get(item)) { + ItemStack self = recipe.getResultItem(); + BigDecimal recipe_summ = BigDecimal.ZERO; + + boolean this_defered = false; + + for (Ingredient ingredient : recipe.getIngredients()) { + ItemStack[] items = ingredient.getItems(); + + BigDecimal smallest_possible = null; + + for (ItemStack stack : items) { + if (!stack.isEmpty()) { + BigDecimal determine = determineValue(stack.getItem()); + + // if we hit an recursive recipe, defer it + if (determine != null) { + if (determine.compareTo(BigDecimal.ZERO) == 0) { + // farewell + OverdriveThatMatters.LOGGER.debug("Cannot determine matter value for {} because value of {} is unknown", item, stack.getItem()); + seen_items_child.put(item, stack.getItem()); + scan_stack[stack_index] = null; + return BigDecimal.ZERO; + } + + if (smallest_possible == null || smallest_possible.compareTo(determine) > 0) + smallest_possible = determine; + } else { + OverdriveThatMatters.LOGGER.debug("Matter value for {} happened to be defered in calculations because {} is defered", item, stack.getItem()); + defer_occured = true; + this_defered = true; + smallest_possible = null; + break; + } + } + } + + if (this_defered) + break; + + if (smallest_possible != null) { + recipe_summ = recipe_summ.add(smallest_possible, ROUND_RULES); + } + } + + if (this_defered) + continue; + + recipe_summ = recipe_summ.divide(new BigDecimal(self.getCount()), ROUND_RULES); + + if (smallest_possible_total == null || smallest_possible_total.compareTo(recipe_summ) > 0) + smallest_possible_total = recipe_summ; + } + + if (smallest_possible_total != null) { + // ez + ITEMS.put(item, smallest_possible_total); + scan_stack[stack_index] = null; + solve_occured = true; + return smallest_possible_total; + } + + if (defer_occured) { + defered_items.add(item); + OverdriveThatMatters.LOGGER.debug("Matter value for {} is defered completely until next iteration", item); + return null; + } + + scan_stack[stack_index] = null; + return BigDecimal.ZERO; + } + + private static void flood(List> recipe_type) { + for (Recipe recipe : recipe_type) { + ItemStack result = recipe.getResultItem(); + + if (result.isEmpty()) + continue; + + ArrayList> results_get = results.computeIfAbsent(result.getItem(), k -> new ArrayList<>()); + + if (results_get.contains(recipe)) + return; + + results_get.add(recipe); + + for (Ingredient ingredient : recipe.getIngredients()) { + ItemStack[] items = ingredient.getItems(); + + for (ItemStack stack : items) { + if (!stack.isEmpty()) { + ArrayList> usages_get = usages.computeIfAbsent(stack.getItem(), k -> new ArrayList<>()); + + if (!usages_get.contains(recipe)) { + usages_get.add(recipe); + } + } + } + } + } + } + + @SubscribeEvent + public static void serverStarted(FMLServerStartedEvent event) { + ITEMS.clear(); + usages.clear(); + results.clear(); + + // scan for recipes and build linked tables + flood(event.getServer().getRecipeManager().getAllRecipesFor(RecipeType.CRAFTING)); + flood(event.getServer().getRecipeManager().getAllRecipesFor(RecipeType.SMELTING)); + flood(event.getServer().getRecipeManager().getAllRecipesFor(RecipeType.STONECUTTING)); + flood(event.getServer().getRecipeManager().getAllRecipesFor(RecipeType.SMITHING)); + + // expand the recipe tree and find references + // just scan entire known tree + solve_occured = true; + + for (int i = 0; i < 100 && solve_occured; i++) + for (Item item : results.keySet()) { + seen_items.clear(); + seen_items_child.clear(); + defered_items.clear(); + determineValue(item); + } + + // clean up garbage + usages.clear(); + results.clear(); + + ArrayList> required_resolve = new ArrayList<>(seen_items.entrySet()); + required_resolve.sort((a, b) -> Integer.compare(0, a.getValue().compareTo(b.getValue()))); + + for (Map.Entry entry : required_resolve) { + if (entry.getValue() > 0) { + OverdriveThatMatters.LOGGER.debug("Resolving matter value of {} will unlock {} subcalls (reason: {})", entry.getKey(), entry.getValue(), seen_items_child.getOrDefault(entry.getKey(), Items.AIR)); + } + } + + seen_items.clear(); + seen_items_child.clear(); + + /* + for (Map.Entry entry : ITEMS.entrySet()) { + OverdriveThatMatters.LOGGER.debug("{} -> {}", entry.getKey(), entry.getValue()); + } + */ + + registerPostItems(); + } + + @SubscribeEvent + public static void attachItemStackTextEvent(ItemTooltipEvent event) { + if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344)) { + BigDecimal matter_value = getMatterValue(event.getItemStack()); + + if (!matter_value.equals(BigDecimal.ZERO)) { + event.getToolTip().add(FormattingHelper.formatMatterValue(matter_value).withStyle(ChatFormatting.AQUA)); + } + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 6a952c412..d88a5f5cc 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -4,7 +4,6 @@ import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -14,7 +13,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; -import net.minecraftforge.fml.loading.FMLEnvironment; +import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; import net.minecraftforge.fmlserverevents.FMLServerStartingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; @@ -23,10 +22,8 @@ import ru.dbotthepony.mc.otm.capability.AndroidCapability; import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.client.AndroidGui; -import ru.dbotthepony.mc.otm.menu.FormattingHelper; -import ru.dbotthepony.mc.otm.network.MatteryNetwork; +import ru.dbotthepony.mc.otm.network.MatteryNetworking; -import java.math.BigDecimal; import java.util.stream.Collectors; // The value here should match an entry in the META-INF/mods.toml file @@ -59,13 +56,16 @@ public class OverdriveThatMatters { // some preinit code MatteryCapability.register(); // LOGGER.info("Registered capabilities"); - MatteryNetwork.register(); + MatteryNetworking.register(); // LOGGER.info("Registered network"); + + MatterRegistry.registerInitialItems(); } private void setupClient(final FMLClientSetupEvent event) { ANDROID_GUI = new AndroidGui(); MinecraftForge.EVENT_BUS.register(ANDROID_GUI); + MinecraftForge.EVENT_BUS.register(MatterRegistry.class); Registry.Menus.registerScreens(event); } @@ -84,7 +84,7 @@ public class OverdriveThatMatters { // You can use SubscribeEvent and let the Event Bus discover methods to call @SubscribeEvent - public void onServerStarting(FMLServerStartingEvent event) { + public void onServerStarting(FMLServerStartedEvent event) { // do something when the server starts } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java index e03b96f91..eea1b5c9f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java @@ -10,10 +10,9 @@ import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fmllegacy.network.PacketDistributor; -import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.network.AndroidCapabilityChangePacket; -import ru.dbotthepony.mc.otm.network.MatteryNetwork; +import ru.dbotthepony.mc.otm.network.MatteryNetworking; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -145,7 +144,7 @@ public class AndroidCapabilityPlayer extends AndroidCapability { AndroidCapabilityChangePacket packet = writeChanges(); if (packet != null) - MatteryNetwork.ANDROID_PLAYER.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) ent), packet); + MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) ent), packet); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java index db5e6bc15..ebc23139f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java @@ -34,6 +34,8 @@ public class FormattingHelper { }; public static final String[] SUFFIX_COMPONENTS_BELOW_ONE = new String[] { + "otm.suffix.deci", + "otm.suffix.centi", "otm.suffix.milli", "otm.suffix.micro", "otm.suffix.nano", @@ -45,6 +47,8 @@ public class FormattingHelper { }; public static final BigDecimal[] SUFFIX_BELOW_ONE = new BigDecimal[] { + BigDecimal.ONE.divide(new BigDecimal("10")), // "otm.suffix.milli": "d%s", + BigDecimal.ONE.divide(new BigDecimal("100")), // "otm.suffix.milli": "c%s", BigDecimal.ONE.divide(new BigDecimal("1000")), // "otm.suffix.milli": "m%s", BigDecimal.ONE.divide(new BigDecimal("1000000")), // "otm.suffix.micro": "μ%s", BigDecimal.ONE.divide(new BigDecimal("1000000000")), // "otm.suffix.nano": "n%s", @@ -60,11 +64,16 @@ public class FormattingHelper { } public static final TranslatableComponent POWER_NAME = new TranslatableComponent("otm.gui.power.name"); + public static final TranslatableComponent MATTER_NAME = new TranslatableComponent("otm.gui.matter.name"); public static Component formatPowerLevel(BigDecimal power, BigDecimal max_power) { return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME)); } + public static TranslatableComponent formatMatterValue(BigDecimal matter) { + return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); + } + public static Component formatPower(BigDecimal power) { return formatSI(power, POWER_NAME); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetwork.java b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java similarity index 79% rename from src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetwork.java rename to src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java index f00856452..d0ff337a5 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetwork.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java @@ -8,20 +8,20 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters; import java.util.Optional; -public class MatteryNetwork { +public class MatteryNetworking { private static final String PROTOCOL_VERSION = "1"; private static int next_network_id = 0; - public static final SimpleChannel ANDROID_PLAYER = NetworkRegistry.newSimpleChannel( - new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_player"), + public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( + new ResourceLocation(OverdriveThatMatters.MOD_ID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void register() { - ANDROID_PLAYER.registerMessage( + CHANNEL.registerMessage( next_network_id++, AndroidCapabilityChangePacket.class, AndroidCapabilityChangePacket::encodeNetwork, diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index f9f80b21c..2c35e5649 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -6,6 +6,9 @@ "otm.gui.level": "%s / %s", "otm.gui.power.name": "MtE", + "otm.gui.matter.format": "Matter: %s", + "otm.gui.matter.name": "MtU", + "otm.item.power.infinite.storage": "Stored energy: Infinity / Infinity", "otm.item.power.infinite.throughput": "Max I/O Infinite / Infinite", @@ -23,6 +26,8 @@ "otm.suffix.zetta": "%s Z%s", "otm.suffix.yotta": "%s Y%s", + "otm.suffix.deci": "%s d%s", + "otm.suffix.centi": "%s c%s", "otm.suffix.milli": "%s m%s", "otm.suffix.micro": "%s μ%s", "otm.suffix.nano": "%s n%s",