mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
also holy shit the whitespace changes, intelliJ wanted to optimize the imports and refactored a ton of whitespace in the process.
181 lines
7.2 KiB
Java
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;
|
|
}
|
|
}
|