Code Snippets/Classes

Discussion in 'Mod Development' started by Strikingwolf, Sep 19, 2014.

  1. CoolSquid

    CoolSquid New Member

    This one checks if you are running in a de obfuscated environment:
    Code:
    public static final boolean developmentEnvironment = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
    Borrowed from one of the only tutorials I've ever read.

    This one checks if you are running Bukkit:
    Code:
    public static final boolean isBukkit() {
    	try {
    		return Class.forName("org.bukkit.Bukkit") != null;
    	} catch (ClassNotFoundException e) {
    		return false;
    	}
    }
    This one checks if you are playing on a client:
    Code:
    public static final boolean isClient() {
    	return FMLCommonHandler.instance().getSide().equals(Side.CLIENT);
    }
    
     
    chbachman likes this.
  2. ratchet freak

    ratchet freak Well-Known Member

    it's faster to cache the Field object between calls and it may cause glitches when the field is statically initialized due to inlining

    that time is the system time not the ingame time

    copyright text should be static as it shows when the version was released
     
  3. ratchet freak

    ratchet freak Well-Known Member

    I kinda wanted to make that clear, some people will complain if you don't
     
  4. CoolSquid

    CoolSquid New Member

    True.
     
  5. ljfa

    ljfa New Member

    Since 1.7 config GUIs exist. It is possible to edit configurations ingame in a GUI without necessarily needing to restarting Minecraft.
    For anyone who doesn't know where to find these: If you click on the "Mods" button on the main title screen you get a list of loaded mods. When clicking on a mod you will see a "Config" button on the bottom left if the mod supports config GUIs.

    @Minalien has a tutorial on how to make your mod compatible with config GUIs. But she only covers the case of one single category. What if you want to use more than one category, displaying each category in a separate page?
    You can do this by adapting your main ConfigGui class like this:
    Code:
    public class MyModConfigGui extends GuiConfig {
        public MyModConfigGui(GuiScreen parent) {
            super(parent, getConfigElements(), Reference.MODID, false, false, "My mod's configuration");
        }
      
        /** Compiles a list of config elements */
        private static List<IConfigElement> getConfigElements() {
            List<IConfigElement> list = new ArrayList<IConfigElement>();
          
            //Add categories to config GUI
            list.add(categoryElement(Config.CATEGORY_GENERAL, "General", "mymod.configgui.ctgy.general"));
            list.add(categoryElement(Config.CATEGORY_FOO, "Foo", "mymod.configgui.ctgy.foo"));
            list.add(categoryElement(Config.CATEGORY_BAR, "Bar", "mymod.configgui.ctgy.bar"));
          
            return list;
        }
      
        /** Creates a button linking to another screen where all options of the category are available */
        private static IConfigElement categoryElement(String category, String name, String tooltip_key) {
            return new DummyConfigElement.DummyCategoryElement(name, tooltip_key,
                    new ConfigElement(Config.conf.getCategory(category)).getChildElements());
        }
    }
    

    Instead of displaying only the main category on the main screen, the call to getConfigElements() will instead make a list of buttons which lead to sub-screens, one sub-screen for each category.

    The other part needed for the config GUI to work is the GUI factory, which Minalien also covers:
    Code:
    public class MyModGuiFactory implements IModGuiFactory {
        @Override
        public void initialize(Minecraft minecraftInstance) {}
    
        @Override
        public Class<? extends GuiScreen> mainConfigGuiClass() {
            return MyModConfigGui.class;
        }
    
        @Override
        public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
            return null;
        }
    
        @Override
        public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
            return null;
        }
    }
    
    To make your config GUI actually work you need to put the GUI factory's class name into the @Mod annotation like this:
    Code:
    @Mod([...], guiFactory = "fully.qualified.name.of.MyModGuiFactory")
    which of course you can also put into a Reference class.
    Refer to Minalien's tutorial for details.
     
    Last edited: Jan 13, 2015
    Minalien and CoolSquid like this.
  6. Strikingwolf

    Strikingwolf New Member

    I need to update this...
     
  7. ljfa

    ljfa New Member

    Yea probably if the post doesn't get too long :p
     
  8. CoolSquid

    CoolSquid New Member

    All the spoilers are broken at Tapatalk...
     
  9. ljfa

    ljfa New Member

    I just noticed that config GUIs are already listed, but without much detail on how to use them (and without the stuff I added).
     
  10. InfinityRaider

    InfinityRaider New Member

    Wouldnt a github repo be easyer? organise the code in some packages and people who want to submit could just do a pull request. That would take a lot of work of your back.
     
  11. Strikingwolf

    Strikingwolf New Member

    You are very smart...I will convert this to github tomorrow
     
    InfinityRaider and CoolSquid like this.
  12. silentrob

    silentrob New Member

    Tapatalk doesn't like "named" spoilers.
     
  13. Minalien

    Minalien New Member

    Just a note, the link has changed as I plan to repurpose my website. https://github.com/Minalien/BlogArchive/blob/master/ForgeTutorials/Spotlight__Config_GUIs.md :)

    There were plans to expand it, but life kind of got in the way of a lot of things. It's definitely nice to see in-game config GUIs getting more attention, and I'd be happy to add a link to your snippet (which is probably much more up-to-date in general as well) to the archived tutorial as well. :)
     
  14. ljfa

    ljfa New Member

    Oh that's why the link is dead.
    I changed the link in my post.

    Go ahead :)
     
  15. Strikingwolf

    Strikingwolf New Member

    Didn't get a chance to switch it. Will do so friday
     
  16. ljfa

    ljfa New Member

    Until then, I have two small functions for generating triangular distributed random numbers:
    Code:
    /** Generates a symmetrically triangular distributed integer between min and max (inclusive).
     * The expected value is (min+max)/2.
     */
    public static int triangularInt(Random rand, int min, int max) {
        int span = max-min;
        return min + rand.nextInt(span/2 + 1) + rand.nextInt((span+1)/2 + 1);
    }
    
    /** Generates a symmetrically triangular distributed double in ]min, max[.
     * The modus and expected value is (min+max)/2.
     */
    public static double triangularDouble(Random rand, double min, double max) {
        return min + 0.5*(max-min)*(rand.nextDouble() - rand.nextDouble() + 1.0);
    }
    
    Use these if you want numbers near the mean to appear more often.
     

Share This Page