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