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