001    package net.minecraft.src;
002    
003    import cpw.mods.fml.client.FMLClientHandler;
004    import cpw.mods.fml.common.Side;
005    import cpw.mods.fml.common.asm.SideOnly;
006    import java.io.BufferedReader;
007    import java.io.File;
008    import java.io.FileReader;
009    import java.io.FileWriter;
010    import java.io.PrintWriter;
011    import net.minecraft.client.Minecraft;
012    import org.lwjgl.input.Keyboard;
013    import org.lwjgl.opengl.Display;
014    
015    @SideOnly(Side.CLIENT)
016    public class GameSettings
017    {
018        private static final String[] RENDER_DISTANCES = new String[] {"options.renderDistance.far", "options.renderDistance.normal", "options.renderDistance.short", "options.renderDistance.tiny"};
019        private static final String[] DIFFICULTIES = new String[] {"options.difficulty.peaceful", "options.difficulty.easy", "options.difficulty.normal", "options.difficulty.hard"};
020    
021        /** GUI scale values */
022        private static final String[] GUISCALES = new String[] {"options.guiScale.auto", "options.guiScale.small", "options.guiScale.normal", "options.guiScale.large"};
023        private static final String[] field_74369_af = new String[] {"options.chat.visibility.full", "options.chat.visibility.system", "options.chat.visibility.hidden"};
024        private static final String[] PARTICLES = new String[] {"options.particles.all", "options.particles.decreased", "options.particles.minimal"};
025    
026        /** Limit framerate labels */
027        private static final String[] LIMIT_FRAMERATES = new String[] {"performance.max", "performance.balanced", "performance.powersaver"};
028        public float musicVolume = 1.0F;
029        public float soundVolume = 1.0F;
030        public float mouseSensitivity = 0.5F;
031        public boolean invertMouse = false;
032        public int renderDistance = 0;
033        public boolean viewBobbing = true;
034        public boolean anaglyph = false;
035    
036        /** Advanced OpenGL */
037        public boolean advancedOpengl = false;
038        public int limitFramerate = 1;
039        public boolean fancyGraphics = true;
040    
041        /** Smooth Lighting */
042        public boolean ambientOcclusion = true;
043    
044        /** Clouds flag */
045        public boolean clouds = true;
046    
047        /** The name of the selected texture pack. */
048        public String skin = "Default";
049        public int chatVisibility = 0;
050        public boolean chatColours = true;
051        public boolean chatLinks = true;
052        public boolean chatLinksPrompt = true;
053        public float chatOpacity = 1.0F;
054        public boolean serverTextures = true;
055        public boolean snooperEnabled = true;
056        public boolean fullScreen = false;
057        public boolean enableVsync = false;
058        public boolean field_80005_w = false;
059        public KeyBinding keyBindForward = new KeyBinding("key.forward", 17);
060        public KeyBinding keyBindLeft = new KeyBinding("key.left", 30);
061        public KeyBinding keyBindBack = new KeyBinding("key.back", 31);
062        public KeyBinding keyBindRight = new KeyBinding("key.right", 32);
063        public KeyBinding keyBindJump = new KeyBinding("key.jump", 57);
064        public KeyBinding keyBindInventory = new KeyBinding("key.inventory", 18);
065        public KeyBinding keyBindDrop = new KeyBinding("key.drop", 16);
066        public KeyBinding keyBindChat = new KeyBinding("key.chat", 20);
067        public KeyBinding keyBindSneak = new KeyBinding("key.sneak", 42);
068        public KeyBinding keyBindAttack = new KeyBinding("key.attack", -100);
069        public KeyBinding keyBindUseItem = new KeyBinding("key.use", -99);
070        public KeyBinding keyBindPlayerList = new KeyBinding("key.playerlist", 15);
071        public KeyBinding keyBindPickBlock = new KeyBinding("key.pickItem", -98);
072        public KeyBinding field_74323_J = new KeyBinding("key.command", 53);
073        public KeyBinding[] keyBindings;
074        protected Minecraft mc;
075        private File optionsFile;
076        public int difficulty;
077        public boolean hideGUI;
078        public int thirdPersonView;
079    
080        /** true if debug info should be displayed instead of version */
081        public boolean showDebugInfo;
082        public boolean field_74329_Q;
083    
084        /** The lastServer string. */
085        public String lastServer;
086    
087        /** No clipping for singleplayer */
088        public boolean noclip;
089    
090        /** Smooth Camera Toggle */
091        public boolean smoothCamera;
092        public boolean debugCamEnable;
093    
094        /** No clipping movement rate */
095        public float noclipRate;
096    
097        /** Change rate for debug camera */
098        public float debugCamRate;
099        public float fovSetting;
100        public float gammaSetting;
101    
102        /** GUI scale */
103        public int guiScale;
104    
105        /** Determines amount of particles. 0 = All, 1 = Decreased, 2 = Minimal */
106        public int particleSetting;
107    
108        /** Game settings language */
109        public String language;
110    
111        public GameSettings(Minecraft par1Minecraft, File par2File)
112        {
113            this.keyBindings = new KeyBinding[] {this.keyBindAttack, this.keyBindUseItem, this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump, this.keyBindSneak, this.keyBindDrop, this.keyBindInventory, this.keyBindChat, this.keyBindPlayerList, this.keyBindPickBlock, this.field_74323_J};
114            this.difficulty = 2;
115            this.hideGUI = false;
116            this.thirdPersonView = 0;
117            this.showDebugInfo = false;
118            this.field_74329_Q = false;
119            this.lastServer = "";
120            this.noclip = false;
121            this.smoothCamera = false;
122            this.debugCamEnable = false;
123            this.noclipRate = 1.0F;
124            this.debugCamRate = 1.0F;
125            this.fovSetting = 0.0F;
126            this.gammaSetting = 0.0F;
127            this.guiScale = 0;
128            this.particleSetting = 0;
129            this.language = "en_US";
130            this.mc = par1Minecraft;
131            this.optionsFile = new File(par2File, "options.txt");
132            this.loadOptions();
133        }
134    
135        public GameSettings()
136        {
137            this.keyBindings = new KeyBinding[] {this.keyBindAttack, this.keyBindUseItem, this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump, this.keyBindSneak, this.keyBindDrop, this.keyBindInventory, this.keyBindChat, this.keyBindPlayerList, this.keyBindPickBlock, this.field_74323_J};
138            this.difficulty = 2;
139            this.hideGUI = false;
140            this.thirdPersonView = 0;
141            this.showDebugInfo = false;
142            this.field_74329_Q = false;
143            this.lastServer = "";
144            this.noclip = false;
145            this.smoothCamera = false;
146            this.debugCamEnable = false;
147            this.noclipRate = 1.0F;
148            this.debugCamRate = 1.0F;
149            this.fovSetting = 0.0F;
150            this.gammaSetting = 0.0F;
151            this.guiScale = 0;
152            this.particleSetting = 0;
153            this.language = "en_US";
154        }
155    
156        public String getKeyBindingDescription(int par1)
157        {
158            StringTranslate var2 = StringTranslate.getInstance();
159            return var2.translateKey(this.keyBindings[par1].keyDescription);
160        }
161    
162        /**
163         * The string that appears inside the button/slider in the options menu.
164         */
165        public String getOptionDisplayString(int par1)
166        {
167            int var2 = this.keyBindings[par1].keyCode;
168            return getKeyDisplayString(var2);
169        }
170    
171        /**
172         * Represents a key or mouse button as a string. Args: key
173         */
174        public static String getKeyDisplayString(int par0)
175        {
176            return par0 < 0 ? StatCollector.translateToLocalFormatted("key.mouseButton", new Object[] {Integer.valueOf(par0 + 101)}): Keyboard.getKeyName(par0);
177        }
178    
179        /**
180         * Sets a key binding.
181         */
182        public void setKeyBinding(int par1, int par2)
183        {
184            this.keyBindings[par1].keyCode = par2;
185            this.saveOptions();
186        }
187    
188        /**
189         * If the specified option is controlled by a slider (float value), this will set the float value.
190         */
191        public void setOptionFloatValue(EnumOptions par1EnumOptions, float par2)
192        {
193            if (par1EnumOptions == EnumOptions.MUSIC)
194            {
195                this.musicVolume = par2;
196                this.mc.sndManager.onSoundOptionsChanged();
197            }
198    
199            if (par1EnumOptions == EnumOptions.SOUND)
200            {
201                this.soundVolume = par2;
202                this.mc.sndManager.onSoundOptionsChanged();
203            }
204    
205            if (par1EnumOptions == EnumOptions.SENSITIVITY)
206            {
207                this.mouseSensitivity = par2;
208            }
209    
210            if (par1EnumOptions == EnumOptions.FOV)
211            {
212                this.fovSetting = par2;
213            }
214    
215            if (par1EnumOptions == EnumOptions.GAMMA)
216            {
217                this.gammaSetting = par2;
218            }
219    
220            if (par1EnumOptions == EnumOptions.CHAT_OPACITY)
221            {
222                this.chatOpacity = par2;
223            }
224        }
225    
226        /**
227         * For non-float options. Toggles the option on/off, or cycles through the list i.e. render distances.
228         */
229        public void setOptionValue(EnumOptions par1EnumOptions, int par2)
230        {
231            if (par1EnumOptions == EnumOptions.INVERT_MOUSE)
232            {
233                this.invertMouse = !this.invertMouse;
234            }
235    
236            if (par1EnumOptions == EnumOptions.RENDER_DISTANCE)
237            {
238                this.renderDistance = this.renderDistance + par2 & 3;
239            }
240    
241            if (par1EnumOptions == EnumOptions.GUI_SCALE)
242            {
243                this.guiScale = this.guiScale + par2 & 3;
244            }
245    
246            if (par1EnumOptions == EnumOptions.PARTICLES)
247            {
248                this.particleSetting = (this.particleSetting + par2) % 3;
249            }
250    
251            if (par1EnumOptions == EnumOptions.VIEW_BOBBING)
252            {
253                this.viewBobbing = !this.viewBobbing;
254            }
255    
256            if (par1EnumOptions == EnumOptions.RENDER_CLOUDS)
257            {
258                this.clouds = !this.clouds;
259            }
260    
261            if (par1EnumOptions == EnumOptions.ADVANCED_OPENGL)
262            {
263                this.advancedOpengl = !this.advancedOpengl;
264                this.mc.renderGlobal.loadRenderers();
265            }
266    
267            if (par1EnumOptions == EnumOptions.ANAGLYPH)
268            {
269                this.anaglyph = !this.anaglyph;
270                this.mc.renderEngine.refreshTextures();
271            }
272    
273            if (par1EnumOptions == EnumOptions.FRAMERATE_LIMIT)
274            {
275                this.limitFramerate = (this.limitFramerate + par2 + 3) % 3;
276            }
277    
278            if (par1EnumOptions == EnumOptions.DIFFICULTY)
279            {
280                this.difficulty = this.difficulty + par2 & 3;
281            }
282    
283            if (par1EnumOptions == EnumOptions.GRAPHICS)
284            {
285                this.fancyGraphics = !this.fancyGraphics;
286                this.mc.renderGlobal.loadRenderers();
287            }
288    
289            if (par1EnumOptions == EnumOptions.AMBIENT_OCCLUSION)
290            {
291                this.ambientOcclusion = !this.ambientOcclusion;
292                this.mc.renderGlobal.loadRenderers();
293            }
294    
295            if (par1EnumOptions == EnumOptions.CHAT_VISIBILITY)
296            {
297                this.chatVisibility = (this.chatVisibility + par2) % 3;
298            }
299    
300            if (par1EnumOptions == EnumOptions.CHAT_COLOR)
301            {
302                this.chatColours = !this.chatColours;
303            }
304    
305            if (par1EnumOptions == EnumOptions.CHAT_LINKS)
306            {
307                this.chatLinks = !this.chatLinks;
308            }
309    
310            if (par1EnumOptions == EnumOptions.CHAT_LINKS_PROMPT)
311            {
312                this.chatLinksPrompt = !this.chatLinksPrompt;
313            }
314    
315            if (par1EnumOptions == EnumOptions.USE_SERVER_TEXTURES)
316            {
317                this.serverTextures = !this.serverTextures;
318            }
319    
320            if (par1EnumOptions == EnumOptions.SNOOPER_ENABLED)
321            {
322                this.snooperEnabled = !this.snooperEnabled;
323            }
324    
325            if (par1EnumOptions == EnumOptions.USE_FULLSCREEN)
326            {
327                this.fullScreen = !this.fullScreen;
328    
329                if (this.mc.isFullScreen() != this.fullScreen)
330                {
331                    this.mc.toggleFullscreen();
332                }
333            }
334    
335            if (par1EnumOptions == EnumOptions.ENABLE_VSYNC)
336            {
337                this.enableVsync = !this.enableVsync;
338                Display.setVSyncEnabled(this.enableVsync);
339            }
340    
341            this.saveOptions();
342        }
343    
344        public float getOptionFloatValue(EnumOptions par1EnumOptions)
345        {
346            return par1EnumOptions == EnumOptions.FOV ? this.fovSetting : (par1EnumOptions == EnumOptions.GAMMA ? this.gammaSetting : (par1EnumOptions == EnumOptions.MUSIC ? this.musicVolume : (par1EnumOptions == EnumOptions.SOUND ? this.soundVolume : (par1EnumOptions == EnumOptions.SENSITIVITY ? this.mouseSensitivity : (par1EnumOptions == EnumOptions.CHAT_OPACITY ? this.chatOpacity : 0.0F)))));
347        }
348    
349        public boolean getOptionOrdinalValue(EnumOptions par1EnumOptions)
350        {
351            switch (EnumOptionsHelper.enumOptionsMappingHelperArray[par1EnumOptions.ordinal()])
352            {
353                case 1:
354                    return this.invertMouse;
355                case 2:
356                    return this.viewBobbing;
357                case 3:
358                    return this.anaglyph;
359                case 4:
360                    return this.advancedOpengl;
361                case 5:
362                    return this.ambientOcclusion;
363                case 6:
364                    return this.clouds;
365                case 7:
366                    return this.chatColours;
367                case 8:
368                    return this.chatLinks;
369                case 9:
370                    return this.chatLinksPrompt;
371                case 10:
372                    return this.serverTextures;
373                case 11:
374                    return this.snooperEnabled;
375                case 12:
376                    return this.fullScreen;
377                case 13:
378                    return this.enableVsync;
379                default:
380                    return false;
381            }
382        }
383    
384        private static String func_74299_a(String[] par0ArrayOfStr, int par1)
385        {
386            if (par1 < 0 || par1 >= par0ArrayOfStr.length)
387            {
388                par1 = 0;
389            }
390    
391            StringTranslate var2 = StringTranslate.getInstance();
392            return var2.translateKey(par0ArrayOfStr[par1]);
393        }
394    
395        /**
396         * Gets a key binding.
397         */
398        public String getKeyBinding(EnumOptions par1EnumOptions)
399        {
400            StringTranslate var2 = StringTranslate.getInstance();
401            String var3 = var2.translateKey(par1EnumOptions.getEnumString()) + ": ";
402    
403            if (par1EnumOptions.getEnumFloat())
404            {
405                float var5 = this.getOptionFloatValue(par1EnumOptions);
406                return par1EnumOptions == EnumOptions.SENSITIVITY ? (var5 == 0.0F ? var3 + var2.translateKey("options.sensitivity.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.sensitivity.max") : var3 + (int)(var5 * 200.0F) + "%")) : (par1EnumOptions == EnumOptions.FOV ? (var5 == 0.0F ? var3 + var2.translateKey("options.fov.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.fov.max") : var3 + (int)(70.0F + var5 * 40.0F))) : (par1EnumOptions == EnumOptions.GAMMA ? (var5 == 0.0F ? var3 + var2.translateKey("options.gamma.min") : (var5 == 1.0F ? var3 + var2.translateKey("options.gamma.max") : var3 + "+" + (int)(var5 * 100.0F) + "%")) : (par1EnumOptions == EnumOptions.CHAT_OPACITY ? var3 + (int)(var5 * 90.0F + 10.0F) + "%" : (var5 == 0.0F ? var3 + var2.translateKey("options.off") : var3 + (int)(var5 * 100.0F) + "%"))));
407            }
408            else if (par1EnumOptions.getEnumBoolean())
409            {
410                boolean var4 = this.getOptionOrdinalValue(par1EnumOptions);
411                return var4 ? var3 + var2.translateKey("options.on") : var3 + var2.translateKey("options.off");
412            }
413            else
414            {
415                return par1EnumOptions == EnumOptions.RENDER_DISTANCE ? var3 + func_74299_a(RENDER_DISTANCES, this.renderDistance) : (par1EnumOptions == EnumOptions.DIFFICULTY ? var3 + func_74299_a(DIFFICULTIES, this.difficulty) : (par1EnumOptions == EnumOptions.GUI_SCALE ? var3 + func_74299_a(GUISCALES, this.guiScale) : (par1EnumOptions == EnumOptions.CHAT_VISIBILITY ? var3 + func_74299_a(field_74369_af, this.chatVisibility) : (par1EnumOptions == EnumOptions.PARTICLES ? var3 + func_74299_a(PARTICLES, this.particleSetting) : (par1EnumOptions == EnumOptions.FRAMERATE_LIMIT ? var3 + func_74299_a(LIMIT_FRAMERATES, this.limitFramerate) : (par1EnumOptions == EnumOptions.GRAPHICS ? (this.fancyGraphics ? var3 + var2.translateKey("options.graphics.fancy") : var3 + var2.translateKey("options.graphics.fast")) : var3))))));
416            }
417        }
418    
419        /**
420         * Loads the options from the options file. It appears that this has replaced the previous 'loadOptions'
421         */
422        public void loadOptions()
423        {
424            try
425            {
426                if (!this.optionsFile.exists())
427                {
428                    return;
429                }
430    
431                BufferedReader var1 = new BufferedReader(new FileReader(this.optionsFile));
432                String var2 = "";
433    
434                while ((var2 = var1.readLine()) != null)
435                {
436                    try
437                    {
438                        String[] var3 = var2.split(":");
439    
440                        if (var3[0].equals("music"))
441                        {
442                            this.musicVolume = this.parseFloat(var3[1]);
443                        }
444    
445                        if (var3[0].equals("sound"))
446                        {
447                            this.soundVolume = this.parseFloat(var3[1]);
448                        }
449    
450                        if (var3[0].equals("mouseSensitivity"))
451                        {
452                            this.mouseSensitivity = this.parseFloat(var3[1]);
453                        }
454    
455                        if (var3[0].equals("fov"))
456                        {
457                            this.fovSetting = this.parseFloat(var3[1]);
458                        }
459    
460                        if (var3[0].equals("gamma"))
461                        {
462                            this.gammaSetting = this.parseFloat(var3[1]);
463                        }
464    
465                        if (var3[0].equals("invertYMouse"))
466                        {
467                            this.invertMouse = var3[1].equals("true");
468                        }
469    
470                        if (var3[0].equals("viewDistance"))
471                        {
472                            this.renderDistance = Integer.parseInt(var3[1]);
473                        }
474    
475                        if (var3[0].equals("guiScale"))
476                        {
477                            this.guiScale = Integer.parseInt(var3[1]);
478                        }
479    
480                        if (var3[0].equals("particles"))
481                        {
482                            this.particleSetting = Integer.parseInt(var3[1]);
483                        }
484    
485                        if (var3[0].equals("bobView"))
486                        {
487                            this.viewBobbing = var3[1].equals("true");
488                        }
489    
490                        if (var3[0].equals("anaglyph3d"))
491                        {
492                            this.anaglyph = var3[1].equals("true");
493                        }
494    
495                        if (var3[0].equals("advancedOpengl"))
496                        {
497                            this.advancedOpengl = var3[1].equals("true");
498                        }
499    
500                        if (var3[0].equals("fpsLimit"))
501                        {
502                            this.limitFramerate = Integer.parseInt(var3[1]);
503                        }
504    
505                        if (var3[0].equals("difficulty"))
506                        {
507                            this.difficulty = Integer.parseInt(var3[1]);
508                        }
509    
510                        if (var3[0].equals("fancyGraphics"))
511                        {
512                            this.fancyGraphics = var3[1].equals("true");
513                        }
514    
515                        if (var3[0].equals("ao"))
516                        {
517                            this.ambientOcclusion = var3[1].equals("true");
518                        }
519    
520                        if (var3[0].equals("clouds"))
521                        {
522                            this.clouds = var3[1].equals("true");
523                        }
524    
525                        if (var3[0].equals("skin"))
526                        {
527                            this.skin = var3[1];
528                        }
529    
530                        if (var3[0].equals("lastServer") && var3.length >= 2)
531                        {
532                            this.lastServer = var3[1];
533                        }
534    
535                        if (var3[0].equals("lang") && var3.length >= 2)
536                        {
537                            this.language = var3[1];
538                        }
539    
540                        if (var3[0].equals("chatVisibility"))
541                        {
542                            this.chatVisibility = Integer.parseInt(var3[1]);
543                        }
544    
545                        if (var3[0].equals("chatColors"))
546                        {
547                            this.chatColours = var3[1].equals("true");
548                        }
549    
550                        if (var3[0].equals("chatLinks"))
551                        {
552                            this.chatLinks = var3[1].equals("true");
553                        }
554    
555                        if (var3[0].equals("chatLinksPrompt"))
556                        {
557                            this.chatLinksPrompt = var3[1].equals("true");
558                        }
559    
560                        if (var3[0].equals("chatOpacity"))
561                        {
562                            this.chatOpacity = this.parseFloat(var3[1]);
563                        }
564    
565                        if (var3[0].equals("serverTextures"))
566                        {
567                            this.serverTextures = var3[1].equals("true");
568                        }
569    
570                        if (var3[0].equals("snooperEnabled"))
571                        {
572                            this.snooperEnabled = var3[1].equals("true");
573                        }
574    
575                        if (var3[0].equals("fullscreen"))
576                        {
577                            this.fullScreen = var3[1].equals("true");
578                        }
579    
580                        if (var3[0].equals("enableVsync"))
581                        {
582                            this.enableVsync = var3[1].equals("true");
583                        }
584    
585                        if (var3[0].equals("hideServerAddress"))
586                        {
587                            this.field_80005_w = var3[1].equals("true");
588                        }
589    
590                        KeyBinding[] var4 = this.keyBindings;
591                        int var5 = var4.length;
592    
593                        for (int var6 = 0; var6 < var5; ++var6)
594                        {
595                            KeyBinding var7 = var4[var6];
596    
597                            if (var3[0].equals("key_" + var7.keyDescription))
598                            {
599                                var7.keyCode = Integer.parseInt(var3[1]);
600                            }
601                        }
602                    }
603                    catch (Exception var8)
604                    {
605                        System.out.println("Skipping bad option: " + var2);
606                    }
607                }
608    
609                KeyBinding.resetKeyBindingArrayAndHash();
610                var1.close();
611            }
612            catch (Exception var9)
613            {
614                System.out.println("Failed to load options");
615                var9.printStackTrace();
616            }
617        }
618    
619        /**
620         * Parses a string into a float.
621         */
622        private float parseFloat(String par1Str)
623        {
624            return par1Str.equals("true") ? 1.0F : (par1Str.equals("false") ? 0.0F : Float.parseFloat(par1Str));
625        }
626    
627        /**
628         * Saves the options to the options file.
629         */
630        public void saveOptions()
631        {
632            if (FMLClientHandler.instance().isLoading()) return;
633            try
634            {
635                PrintWriter var1 = new PrintWriter(new FileWriter(this.optionsFile));
636                var1.println("music:" + this.musicVolume);
637                var1.println("sound:" + this.soundVolume);
638                var1.println("invertYMouse:" + this.invertMouse);
639                var1.println("mouseSensitivity:" + this.mouseSensitivity);
640                var1.println("fov:" + this.fovSetting);
641                var1.println("gamma:" + this.gammaSetting);
642                var1.println("viewDistance:" + this.renderDistance);
643                var1.println("guiScale:" + this.guiScale);
644                var1.println("particles:" + this.particleSetting);
645                var1.println("bobView:" + this.viewBobbing);
646                var1.println("anaglyph3d:" + this.anaglyph);
647                var1.println("advancedOpengl:" + this.advancedOpengl);
648                var1.println("fpsLimit:" + this.limitFramerate);
649                var1.println("difficulty:" + this.difficulty);
650                var1.println("fancyGraphics:" + this.fancyGraphics);
651                var1.println("ao:" + this.ambientOcclusion);
652                var1.println("clouds:" + this.clouds);
653                var1.println("skin:" + this.skin);
654                var1.println("lastServer:" + this.lastServer);
655                var1.println("lang:" + this.language);
656                var1.println("chatVisibility:" + this.chatVisibility);
657                var1.println("chatColors:" + this.chatColours);
658                var1.println("chatLinks:" + this.chatLinks);
659                var1.println("chatLinksPrompt:" + this.chatLinksPrompt);
660                var1.println("chatOpacity:" + this.chatOpacity);
661                var1.println("serverTextures:" + this.serverTextures);
662                var1.println("snooperEnabled:" + this.snooperEnabled);
663                var1.println("fullscreen:" + this.fullScreen);
664                var1.println("enableVsync:" + this.enableVsync);
665                var1.println("hideServerAddress:" + this.field_80005_w);
666                KeyBinding[] var2 = this.keyBindings;
667                int var3 = var2.length;
668    
669                for (int var4 = 0; var4 < var3; ++var4)
670                {
671                    KeyBinding var5 = var2[var4];
672                    var1.println("key_" + var5.keyDescription + ":" + var5.keyCode);
673                }
674    
675                var1.close();
676            }
677            catch (Exception var6)
678            {
679                System.out.println("Failed to save options");
680                var6.printStackTrace();
681            }
682    
683            if (this.mc.thePlayer != null)
684            {
685                this.mc.thePlayer.sendQueue.addToSendQueue(new Packet204ClientInfo(this.language, this.renderDistance, this.chatVisibility, this.chatColours, this.difficulty));
686            }
687        }
688    
689        /**
690         * Should render clouds
691         */
692        public boolean shouldRenderClouds()
693        {
694            return this.renderDistance < 2 && this.clouds;
695        }
696    }