    001    package net.minecraft.stats;
    002
    003    import cpw.mods.fml.relauncher.Side;
    004    import cpw.mods.fml.relauncher.SideOnly;
    005    import java.util.ArrayList;
    006    import java.util.HashMap;
    007    import java.util.HashSet;
    008    import java.util.Iterator;
    009    import java.util.List;
    010    import java.util.Map;
    011    import net.minecraft.block.Block;
    012    import net.minecraft.item.Item;
    013    import net.minecraft.item.ItemStack;
    014    import net.minecraft.item.crafting.CraftingManager;
    015    import net.minecraft.item.crafting.FurnaceRecipes;
    016    import net.minecraft.item.crafting.IRecipe;
    017    import net.minecraft.util.StatCollector;
    018
    019    public class StatList
    020    {
    021        /** Tracks one-off stats. */
    022        protected static Map oneShotStats = new HashMap();
    023        public static List allStats = new ArrayList();
    024        public static List generalStats = new ArrayList();
    025        public static List itemStats = new ArrayList();
    026
    027        /** Tracks the number of times a given block or item has been mined. */
    028        public static List objectMineStats = new ArrayList();
    029
    030        /** times the game has been started */
    031        public static StatBase startGameStat = (new StatBasic(1000, "stat.startGame")).initIndependentStat().registerStat();
    032
    033        /** times a world has been created */
    034        public static StatBase createWorldStat = (new StatBasic(1001, "stat.createWorld")).initIndependentStat().registerStat();
    035
    036        /** the number of times you have loaded a world */
    037        public static StatBase loadWorldStat = (new StatBasic(1002, "stat.loadWorld")).initIndependentStat().registerStat();
    038
    039        /** number of times you've joined a multiplayer world */
    040        public static StatBase joinMultiplayerStat = (new StatBasic(1003, "stat.joinMultiplayer")).initIndependentStat().registerStat();
    041
    042        /** number of times you've left a game */
    043        public static StatBase leaveGameStat = (new StatBasic(1004, "stat.leaveGame")).initIndependentStat().registerStat();
    044
    045        /** number of minutes you have played */
    046        public static StatBase minutesPlayedStat = (new StatBasic(1100, "stat.playOneMinute", StatBase.timeStatType)).initIndependentStat().registerStat();
    047
    048        /** distance you've walked */
    049        public static StatBase distanceWalkedStat = (new StatBasic(2000, "stat.walkOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    050
    051        /** distance you have swam */
    052        public static StatBase distanceSwumStat = (new StatBasic(2001, "stat.swimOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    053
    054        /** the distance you have fallen */
    055        public static StatBase distanceFallenStat = (new StatBasic(2002, "stat.fallOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    056
    057        /** the distance you've climbed */
    058        public static StatBase distanceClimbedStat = (new StatBasic(2003, "stat.climbOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    059
    060        /** the distance you've flown */
    061        public static StatBase distanceFlownStat = (new StatBasic(2004, "stat.flyOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    062
    063        /** the distance you've dived */
    064        public static StatBase distanceDoveStat = (new StatBasic(2005, "stat.diveOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    065
    066        /** the distance you've traveled by minecart */
    067        public static StatBase distanceByMinecartStat = (new StatBasic(2006, "stat.minecartOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    068
    069        /** the distance you've traveled by boat */
    070        public static StatBase distanceByBoatStat = (new StatBasic(2007, "stat.boatOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    071
    072        /** the distance you've traveled by pig */
    073        public static StatBase distanceByPigStat = (new StatBasic(2008, "stat.pigOneCm", StatBase.distanceStatType)).initIndependentStat().registerStat();
    074
    075        /** the times you've jumped */
    076        public static StatBase jumpStat = (new StatBasic(2010, "stat.jump")).initIndependentStat().registerStat();
    077
    078        /** the distance you've dropped (or times you've fallen?) */
    079        public static StatBase dropStat = (new StatBasic(2011, "stat.drop")).initIndependentStat().registerStat();
    080
    081        /** the amount of damage you've dealt */
    082        public static StatBase damageDealtStat = (new StatBasic(2020, "stat.damageDealt")).registerStat();
    083
    084        /** the amount of damage you have taken */
    085        public static StatBase damageTakenStat = (new StatBasic(2021, "stat.damageTaken")).registerStat();
    086
    087        /** the number of times you have died */
    088        public static StatBase deathsStat = (new StatBasic(2022, "stat.deaths")).registerStat();
    089
    090        /** the number of mobs you have killed */
    091        public static StatBase mobKillsStat = (new StatBasic(2023, "stat.mobKills")).registerStat();
    092
    093        /** counts the number of times you've killed a player */
    094        public static StatBase playerKillsStat = (new StatBasic(2024, "stat.playerKills")).registerStat();
    095        public static StatBase fishCaughtStat = (new StatBasic(2025, "stat.fishCaught")).registerStat();
    096        public static StatBase[] mineBlockStatArray = initMinableStats("stat.mineBlock", 16777216);
    097
    098        /** Tracks the number of items a given block or item has been crafted. */
    099        public static StatBase[] objectCraftStats;
    100
    101        /** Tracks the number of times a given block or item has been used. */
    102        public static StatBase[] objectUseStats;
    103
    104        /** Tracks the number of times a given block or item has been broken. */
    105        public static StatBase[] objectBreakStats;
    106        private static boolean blockStatsInitialized;
    107        private static boolean itemStatsInitialized;
    108
    109        /**
    110         * This method simply NOPs. It is presumably used to call the static constructors on server start.
    111         */
    112        public static void nopInit() {}
    113
    114        /**
    115         * Initializes statistic fields related to breakable items and blocks.
    116         */
    117        public static void initBreakableStats()
    118        {
    119            objectUseStats = initUsableStats(objectUseStats, "stat.useItem", 16908288, 0, 256);
    120            objectBreakStats = initBreakStats(objectBreakStats, "stat.breakItem", 16973824, 0, 256);
    121            blockStatsInitialized = true;
    122            initCraftableStats();
    123        }
    124
    125        public static void initStats()
    126        {
    127            objectUseStats = initUsableStats(objectUseStats, "stat.useItem", 16908288, 256, 32000);
    128            objectBreakStats = initBreakStats(objectBreakStats, "stat.breakItem", 16973824, 256, 32000);
    129            itemStatsInitialized = true;
    130            initCraftableStats();
    131        }
    132
    133        /**
    134         * Initializes statistics related to craftable items. Is only called after both block and item stats have been
    135         * initialized.
    136         */
    137        public static void initCraftableStats()
    138        {
    139            if (blockStatsInitialized && itemStatsInitialized)
    140            {
    141                HashSet var0 = new HashSet();
    142                Iterator var1 = CraftingManager.getInstance().getRecipeList().iterator();
    143
    144                while (var1.hasNext())
    145                {
    146                    IRecipe var2 = (IRecipe)var1.next();
    147
    148                    if (var2.getRecipeOutput() != null)
    149                    {
    150                        var0.add(Integer.valueOf(var2.getRecipeOutput().itemID));
    151                    }
    152                }
    153
    154                var1 = FurnaceRecipes.smelting().getSmeltingList().values().iterator();
    155
    156                while (var1.hasNext())
    157                {
    158                    ItemStack var4 = (ItemStack)var1.next();
    159                    var0.add(Integer.valueOf(var4.itemID));
    160                }
    161
    162                objectCraftStats = new StatBase[32000];
    163                var1 = var0.iterator();
    164
    165                while (var1.hasNext())
    166                {
    167                    Integer var5 = (Integer)var1.next();
    168
    169                    if (Item.itemsList[var5.intValue()] != null)
    170                    {
    171                        String var3 = StatCollector.translateToLocalFormatted("stat.craftItem", new Object[] {Item.itemsList[var5.intValue()].getStatName()});
    172                        objectCraftStats[var5.intValue()] = (new StatCrafting(16842752 + var5.intValue(), var3, var5.intValue())).registerStat();
    173                    }
    174                }
    175
    176                replaceAllSimilarBlocks(objectCraftStats);
    177            }
    178        }
    179
    180        /**
    181         * Initializes statistic fields related to minable items and blocks.
    182         */
    183        private static StatBase[] initMinableStats(String par0Str, int par1)
    184        {
    185            StatBase[] var2 = new StatBase[Block.blocksList.length];
    186
    187            for (int var3 = 0; var3 < Block.blocksList.length; ++var3)
    188            {
    189                if (Block.blocksList[var3] != null && Block.blocksList[var3].getEnableStats())
    190                {
    191                    String var4 = StatCollector.translateToLocalFormatted(par0Str, new Object[] {Block.blocksList[var3].translateBlockName()});
    192                    var2[var3] = (new StatCrafting(par1 + var3, var4, var3)).registerStat();
    193                    objectMineStats.add((StatCrafting)var2[var3]);
    194                }
    195            }
    196
    197            replaceAllSimilarBlocks(var2);
    198            return var2;
    199        }
    200
    201        /**
    202         * Initializes statistic fields related to usable items and blocks.
    203         */
    204        private static StatBase[] initUsableStats(StatBase[] par0ArrayOfStatBase, String par1Str, int par2, int par3, int par4)
    205        {
    206            if (par0ArrayOfStatBase == null)
    207            {
    208                par0ArrayOfStatBase = new StatBase[32000];
    209            }
    210
    211            for (int var5 = par3; var5 < par4; ++var5)
    212            {
    213                if (Item.itemsList[var5] != null)
    214                {
    215                    String var6 = StatCollector.translateToLocalFormatted(par1Str, new Object[] {Item.itemsList[var5].getStatName()});
    216                    par0ArrayOfStatBase[var5] = (new StatCrafting(par2 + var5, var6, var5)).registerStat();
    217
    218                    if (var5 >= 256)
    219                    {
    220                        itemStats.add((StatCrafting)par0ArrayOfStatBase[var5]);
    221                    }
    222                }
    223            }
    224
    225            replaceAllSimilarBlocks(par0ArrayOfStatBase);
    226            return par0ArrayOfStatBase;
    227        }
    228
    229        private static StatBase[] initBreakStats(StatBase[] par0ArrayOfStatBase, String par1Str, int par2, int par3, int par4)
    230        {
    231            if (par0ArrayOfStatBase == null)
    232            {
    233                par0ArrayOfStatBase = new StatBase[32000];
    234            }
    235
    236            for (int var5 = par3; var5 < par4; ++var5)
    237            {
    238                if (Item.itemsList[var5] != null && Item.itemsList[var5].isDamageable())
    239                {
    240                    String var6 = StatCollector.translateToLocalFormatted(par1Str, new Object[] {Item.itemsList[var5].getStatName()});
    241                    par0ArrayOfStatBase[var5] = (new StatCrafting(par2 + var5, var6, var5)).registerStat();
    242                }
    243            }
    244
    245            replaceAllSimilarBlocks(par0ArrayOfStatBase);
    246            return par0ArrayOfStatBase;
    247        }
    248
    249        /**
    250         * Forces all dual blocks to count for each other on the stats list
    251         */
    252        private static void replaceAllSimilarBlocks(StatBase[] par0ArrayOfStatBase)
    253        {
    254            replaceSimilarBlocks(par0ArrayOfStatBase, Block.waterStill.blockID, Block.waterMoving.blockID);
    255            replaceSimilarBlocks(par0ArrayOfStatBase, Block.lavaStill.blockID, Block.lavaStill.blockID);
    256            replaceSimilarBlocks(par0ArrayOfStatBase, Block.pumpkinLantern.blockID, Block.pumpkin.blockID);
    257            replaceSimilarBlocks(par0ArrayOfStatBase, Block.stoneOvenActive.blockID, Block.stoneOvenIdle.blockID);
    258            replaceSimilarBlocks(par0ArrayOfStatBase, Block.oreRedstoneGlowing.blockID, Block.oreRedstone.blockID);
    259            replaceSimilarBlocks(par0ArrayOfStatBase, Block.redstoneRepeaterActive.blockID, Block.redstoneRepeaterIdle.blockID);
    260            replaceSimilarBlocks(par0ArrayOfStatBase, Block.torchRedstoneActive.blockID, Block.torchRedstoneIdle.blockID);
    261            replaceSimilarBlocks(par0ArrayOfStatBase, Block.mushroomRed.blockID, Block.mushroomBrown.blockID);
    262            replaceSimilarBlocks(par0ArrayOfStatBase, Block.stoneDoubleSlab.blockID, Block.stoneSingleSlab.blockID);
    263            replaceSimilarBlocks(par0ArrayOfStatBase, Block.woodDoubleSlab.blockID, Block.woodSingleSlab.blockID);
    264            replaceSimilarBlocks(par0ArrayOfStatBase, Block.grass.blockID, Block.dirt.blockID);
    265            replaceSimilarBlocks(par0ArrayOfStatBase, Block.tilledField.blockID, Block.dirt.blockID);
    266        }
    267
    268        /**
    269         * Forces stats for one block to add to another block, such as idle and active furnaces
    270         */
    271        private static void replaceSimilarBlocks(StatBase[] par0ArrayOfStatBase, int par1, int par2)
    272        {
    273            if (par0ArrayOfStatBase[par1] != null && par0ArrayOfStatBase[par2] == null)
    274            {
    275                par0ArrayOfStatBase[par2] = par0ArrayOfStatBase[par1];
    276            }
    277            else
    278            {
    279                allStats.remove(par0ArrayOfStatBase[par1]);
    280                objectMineStats.remove(par0ArrayOfStatBase[par1]);
    281                generalStats.remove(par0ArrayOfStatBase[par1]);
    282                par0ArrayOfStatBase[par1] = par0ArrayOfStatBase[par2];
    283            }
    284        }
    285
    286        @SideOnly(Side.CLIENT)
    287        public static StatBase getOneShotStat(int par0)
    288        {
    289            return (StatBase)oneShotStats.get(Integer.valueOf(par0));
    290        }
    291
    292        static
    293        {
    294            AchievementList.init();
    295            blockStatsInitialized = false;
    296            itemStatsInitialized = false;
    297        }
    298    }