BallOfEnergy 4bd6f0df53 More shit, also precompiled packets.
also holy shit the whitespace changes, intelliJ wanted to optimize the imports and refactored a ton of whitespace in the process.
2024-11-09 17:04:19 -06:00

181 lines
7.2 KiB
Java

package com.hbm.util;
import com.hbm.interfaces.NotableComments;
import cpw.mods.fml.relauncher.ReflectionHelper;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatBase;
import net.minecraft.stats.StatCrafting;
import net.minecraft.stats.StatList;
import net.minecraft.util.ChatComponentTranslation;
import java.util.Iterator;
import java.util.Map;
@NotableComments
public class StatHelper {
/*
* God is dead and we are pissing on his grave
*/
public static Map publicReferenceToOneshotStatListPleaseAllPointAndLaugh;
/**
* This is probably the worst fucking way of doing this, but it's the only one I could think of that works.
* In short: stats are hilariously broken.
* Minecraft registers them at the earliest point during startup right after blocks and items are registered.
* The problem in that? Item remapping. Modded items probably don't even exist at that point and even if they did,
* the system would break because modded items have dynamic IDs and the stats register fixed IDs instead of item instances.
* What did forge do to solve this issue? Well nothing, of course! The injected bits comment on that in vanilla's stat
* registering code, but instead of fixing anything it just slaps a fat "TODO" onto it. Wow! Really helpful!
*
* So what do we do? Every time the world starts and we know the IDs are now correct, we smack that fucker up nice and good.
* All ID-bound stats get deep-cleaned out of this mess and registered 1:1 again. Is this terrible and prone to breaking with
* mods that do their own stat handling? Hard to say, but the possibility is there.
*/
public static void resetStatShitFuck() {
publicReferenceToOneshotStatListPleaseAllPointAndLaugh = ReflectionHelper.getPrivateValue(StatList.class, null, "field_75942_a", "oneShotStats");
for(int i = 0; i < StatList.objectCraftStats.length; i++) StatList.objectCraftStats[i] = null;
for(int i = 0; i < StatList.mineBlockStatArray.length; i++) StatList.mineBlockStatArray[i] = null;
for(int i = 0; i < StatList.objectUseStats.length; i++) StatList.objectUseStats[i] = null;
for(int i = 0; i < StatList.objectBreakStats.length; i++) StatList.objectBreakStats[i] = null;
StatList.objectMineStats.clear();
StatList.itemStats.clear();
try {
initCraftItemStats();
initBlockMineStats();
initItemUseStats();
initItemBreakStats();
} catch(Throwable ex) { } // just to be sure
}
/**
* For reasons beyond human comprehension, this bit originally only registered items that are the result
* of an IRecipe instead of just all items outright like the item usage stats. The logical consequence of this is:
* 1) The code has to iterate over thousands of recipes to get recipe results which is no more performant than just going over
* 32k potential items, most of which are going to be null anyway
* 2) The system just will never work with items that don't have crafting table recipes
*/
private static void initCraftItemStats() {
Iterator iterator = Item.itemRegistry.iterator();
while(iterator.hasNext()) {
Item item = (Item) iterator.next();
if(item != null) {
int i = Item.getIdFromItem(item);
try {
StatList.objectCraftStats[i] = registerStat(new StatCrafting("stat.craftItem." + i, new ChatComponentTranslation("stat.craftItem", new Object[] { (new ItemStack(item)).func_151000_E() }), item));
} catch(Throwable ex) { }
}
}
replaceAllSimilarBlocks(StatList.objectCraftStats);
}
private static void initBlockMineStats() {
Iterator iterator = Block.blockRegistry.iterator();
while(iterator.hasNext()) {
Block block = (Block) iterator.next();
if(Item.getItemFromBlock(block) != null) {
int i = Block.getIdFromBlock(block);
try {
if(block.getEnableStats()) {
StatList.mineBlockStatArray[i] = registerStat(new StatCrafting("stat.mineBlock." + i, new ChatComponentTranslation("stat.mineBlock", new Object[] { (new ItemStack(block)).func_151000_E() }), Item.getItemFromBlock(block)));
StatList.objectMineStats.add((StatCrafting) StatList.mineBlockStatArray[i]);
}
} catch(Throwable ex) { }
}
}
replaceAllSimilarBlocks(StatList.mineBlockStatArray);
}
private static void initItemUseStats() {
Iterator iterator = Item.itemRegistry.iterator();
while(iterator.hasNext()) {
Item item = (Item) iterator.next();
if(item != null) {
int i = Item.getIdFromItem(item);
try {
StatList.objectUseStats[i] = registerStat(new StatCrafting("stat.useItem." + i, new ChatComponentTranslation("stat.useItem", new Object[] { (new ItemStack(item)).func_151000_E() }), item));
if(!(item instanceof ItemBlock)) {
StatList.itemStats.add((StatCrafting) StatList.objectUseStats[i]);
}
} catch(Throwable ex) { }
}
}
replaceAllSimilarBlocks(StatList.objectUseStats);
}
private static void initItemBreakStats() {
Iterator iterator = Item.itemRegistry.iterator();
while(iterator.hasNext()) {
Item item = (Item) iterator.next();
if(item != null) {
int i = Item.getIdFromItem(item);
try {
if(item.isDamageable()) {
StatList.objectBreakStats[i] = registerStat(new StatCrafting("stat.breakItem." + i, new ChatComponentTranslation("stat.breakItem", new Object[] { (new ItemStack(item)).func_151000_E() }), item));
}
} catch(Throwable ex) { }
}
}
replaceAllSimilarBlocks(StatList.objectBreakStats);
}
private static void replaceAllSimilarBlocks(StatBase[] stats) {
func_151180_a(stats, Blocks.water, Blocks.flowing_water);
func_151180_a(stats, Blocks.lava, Blocks.flowing_lava);
func_151180_a(stats, Blocks.lit_pumpkin, Blocks.pumpkin);
func_151180_a(stats, Blocks.lit_furnace, Blocks.furnace);
func_151180_a(stats, Blocks.lit_redstone_ore, Blocks.redstone_ore);
func_151180_a(stats, Blocks.powered_repeater, Blocks.unpowered_repeater);
func_151180_a(stats, Blocks.powered_comparator, Blocks.unpowered_comparator);
func_151180_a(stats, Blocks.redstone_torch, Blocks.unlit_redstone_torch);
func_151180_a(stats, Blocks.lit_redstone_lamp, Blocks.redstone_lamp);
func_151180_a(stats, Blocks.red_mushroom, Blocks.brown_mushroom);
func_151180_a(stats, Blocks.double_stone_slab, Blocks.stone_slab);
func_151180_a(stats, Blocks.double_wooden_slab, Blocks.wooden_slab);
func_151180_a(stats, Blocks.grass, Blocks.dirt);
func_151180_a(stats, Blocks.farmland, Blocks.dirt);
}
private static void func_151180_a(StatBase[] stats, Block block, Block similarBlock) {
int i = Block.getIdFromBlock(block);
int j = Block.getIdFromBlock(similarBlock);
if(stats[i] != null && stats[j] == null) {
stats[j] = stats[i];
} else {
StatList.allStats.remove(stats[i]);
StatList.objectMineStats.remove(stats[i]);
StatList.generalStats.remove(stats[i]);
stats[i] = stats[j];
}
}
private static StatBase registerStat(StatBase stat) {
if(publicReferenceToOneshotStatListPleaseAllPointAndLaugh.containsKey(stat.statId)) {
publicReferenceToOneshotStatListPleaseAllPointAndLaugh.remove(stat.statId);
}
StatList.allStats.add(stat);
publicReferenceToOneshotStatListPleaseAllPointAndLaugh.put(stat.statId, stat);
return stat;
}
}