Code Snippets/Classes

Democretes

New Member
Jul 29, 2019
1,134
0
1
So I take it you also have a DirectionHelper where you define public static final int DOWN = 0 instead of using ForgeDirection.DOWN? EnumChatFormatting is exactly what Enum's are for.
Generally when I use ForgeDirections, I'm comparing them, iterating through the list of directions, getting the opposite direction. When I use colors, I make them into strings using specific ones. I've never used them to compare colors or remove them. There's just very little use for it. I don't need an enum of colors to iterate through. I just need pre-defined colors as Strings. We're just going to have to agree to disagree here.
 

squeek502

New Member
Jul 29, 2019
146
0
0
We're just going to have to agree to disagree here.
Ok. Just to clarify my stance, I agree that there is a use case for some sort of FormattingHelper-type class that makes applying formatting codes easier. I'm not sure String constants are the best solution to that (though I recognize that they help a bit), but as long as EnumChatFormatting is used to define the String constants, I'm happy.
 

Alexiy

Well-Known Member
Mar 3, 2014
229
128
68
Riga, Latvia
I've got a whole library but I don't think it is useful to put something here as the post is very big already. It might be interesting to have a modding wiki, though.
 

Strikingwolf

New Member
Jul 29, 2019
3,709
-26
1
I've got a whole library but I don't think it is useful to put something here as the post is very big already. It might be interesting to have a modding wiki, though.
Yeah we do need a better way of handling this :p. However I think a community-driven wiki would be better than the minecraft-forge one. How about this, could you make a post in this section with your library in it and I will make a libraries section with links ;)
 

Strikingwolf

New Member
Jul 29, 2019
3,709
-26
1
BTW can I have blanket permission to everything here? I was thinking of making say a core mod ;) And yes this may or may not have been a way to collect things people use for said core mod :p
 
C

chbachman

Guest
BTW can I have blanket permission to everything here? I was thinking of making say a core mod ;) And yes this may or may not have been a way to collect things people use for said core mod :p
You mean a library? Core mods change vanilla minecraft's code.
 
  • Like
Reactions: SatanicSanta

SoraZodia

Forum Ghost
Third Party Pack Team
Mod Developer
Mar 11, 2014
3,924
1,289
253
BTW can I have blanket permission to everything here? I was thinking of making say a core mod ;) And yes this may or may not have been a way to collect things people use for said core mod :p
For my code, sure
 

Strikingwolf

New Member
Jul 29, 2019
3,709
-26
1
At least you know the difference between int and String
Amen.[DOUBLEPOST=1413408449,1412913407][/DOUBLEPOST]Quoting for pings
This is intended to be a place where you post general code snippets to do crap :p

Basic Classes
How about I start us off with the most basic classes of all, the base mod class, my counterpart for it the Reference class, and the proxy classes

Base Mod class for you (Requires Reference and Proxy classes)
Code:
@Mod(modid = Reference.MOD_ID, name = Reference.MOD_NAME, version = Reference.VERSION)
public class ModName
{
    @Mod.Instance(Reference.MOD_ID)
    public static ModName instance;

    @SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS)
    public static CommonProxy proxy;

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
        //Optional if you have ConfigurationHandler setup
        //ConfigurationHandler.init(event.getSuggestedConfigurationFile());
        //FMLCommonHandler.instance().bus().register(new ConfigurationHandler());

        //Optional if you use the LogHelper
        //LogHelper.info("Pre Initialization Complete");
    }

    @Mod.EventHandler
    public void Init(FMLInitializationEvent event)
    {
        //Optional if you use the LogHelper
        //LogHelper.info("Initialization Complete");
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event)
    {
        //Optional if you use the LogHelper
        //LogHelper.info("Post Initialization Complete");
    }
}
For all your referencing needs
Code:
public class Reference
{
    public static final String MOD_ID = "ModID";
    public static final String MOD_NAME = "ModName";
    public static final String VERSION = "VERSION";

    public static final String CLIENT_PROXY_CLASS = "mods.modname.proxy.ClientProxy";
    public static final String SERVER_PROXY_CLASS = "mods.modname.proxy.ServerProxy";
}
For all your proxy needs
Code:
public interface IProxy
{
    public abstract void registerKeyBindings();
}
Code:
public abstract class CommonProxy implements IProxy {

    public void initSounds()
    {

    }

    public void initRenderers()
    {

    }
}
Code:
public class ServerProxy extends CommonProxy {


    @Override
    public void registerKeyBindings() {
        //NOOP
    }
}
Code:
public class ClientProxy extends CommonProxy {

    @Override
    public void initSounds()
    {

    }

    @Override
    public void initRenderers()
    {

    }

    @Override
    public void registerKeyBindings()
    {

    }
}

Utility

Also the LogHelper class is very helpful when doing anything logging related (requires Reference Class)
Code:
public class LogHelper {
    public static void log(Level logLevel, Object object)
    {
        FMLLog.log(Reference.MOD_NAME, logLevel, String.valueOf(object));
    }

    public static void all(Object object)
    {
        log(Level.ALL, object);
    }

    public static void debug(Object object)
    {
        log(Level.DEBUG, object);
    }

    public static void error(Object object)
    {
        log(Level.ERROR, object);
    }

    public static void fatal(Object object)
    {
        log(Level.FATAL, object);
    }

    public static void info(Object object)
    {
        log(Level.INFO, object);
    }

    public static void off(Object object)
    {
        log(Level.OFF, object);
    }

    public static void trace(Object object)
    {
        log(Level.TRACE, object);
    }

    public static void warn(Object object)
    {
        log(Level.WARN, object);
    }
}

KeyHelper; detects shift/control with proper Mac support contributed by @squeek502
Code:
public class KeyHelper
{
   public static boolean isCtrlKeyDown()
   {
     // prioritize CONTROL, but allow OPTION as well on Mac (note: GuiScreen's isCtrlKeyDown only checks for the OPTION key on Mac)
     boolean isCtrlKeyDown = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
     if (!isCtrlKeyDown && Minecraft.isRunningOnMac)
       isCtrlKeyDown = Keyboard.isKeyDown(Keyboard.KEY_LMETA) || Keyboard.isKeyDown(Keyboard.KEY_RMETA);

     return isCtrlKeyDown;
   }

   public static boolean isShiftKeyDown()
   {
     return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
   }
}

ColorHelper; converts between the common color types used within Minecraft code (hexadecimal color using an int, rgba using ints from 0-255, and rgba using floats from 0.0-1.0) contributed by @squeek502
Code:
public class ColorHelper
{
   public static float[] toNormalizedRGB(int color)
   {
     return toNormalizedRGBA(color | 255 << 24);
   }

   public static float[] toNormalizedRGBA(int color)
   {
     int[] rgba = toRGBA(color);

     return new float[]{rgba[0] / 255f, rgba[1] / 255f, rgba[2] / 255f, rgba[3] / 255f};
   }

   public static int[] toRGBA(int color)
   {
     int alpha = color >> 24 & 255;
     int red = color >> 16 & 255;
     int green = color >> 8 & 255;
     int blue = color & 255;

     return new int[]{red, green, blue, alpha};
   }

   public static int fromRGBA(int r, int g, int b, int a)
   {
     return (a & 255) << 24 | (r & 255) << 16 | (g & 255) << 8 | b & 255;
   }

   public static int fromRGB(int r, int g, int b)
   {
     return fromRGBA(r, g, b, 255);
   }

   public static int fromNormalizedRGBA(float r, float g, float b, float a)
   {
     return fromRGBA((int) r * 255, (int) g * 255, (int) b * 255, (int) a * 255);
   }

   public static int fromNormalizedRGB(float r, float g, float b)
   {
     return fromNormalizedRGBA(r, g, b, 1f);
   }
}

If you are working with Configs you may want a basic ConfigurationHandler class (Requires Reference Class)
Code:
public class ConfigurationHandler {

    public static Configuration configuration;

    public static void init(File configFile) {

        //create configuration object from the given file
        if (configuration == null)
        {
            configuration = new Configuration(configFile);
            loadConfiguration();
        }
    }

    @SubscribeEvent
    public void onConfigurationChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
    {
        if (event.modID.equalsIgnoreCase(Reference.MOD_ID))
        {
            loadConfiguration();
        }
    }

    private static void loadConfiguration()
    {
        if (configuration.hasChanged())
        {
            configuration.save();
        }
    }
}

GameRegistryItems Class - Makes ItemRegistering less of a hassle = less typing contributed by @SoraZodia
Code:
/** Item registry class, have methods to make
* item registation in the GameRegistry a bit easier/less
* typing.
*
* THE init() METHOD MUST BE CALLED FOR IT TO WORK*/
public class GameRegistryItems {

    private static String MODID;
    private static CreativeTabs tabs;

    /**
    * Intitizate the MODID and CreativeTabs variable for the rest of the class to use.
    * This must be called before any other methods in this class or funny stuff may happen.
    * @param MOD_ID_String
    * @param CreativeTabs
    */
    public static void init(String modID, CreativeTabs tab){
        MODID = modID;
        tabs = tab;
    }

    /** A more steamline way to register your items, does all of the
    * extra stuff for you, just make sure your item object is initializated*/
    public static void registerItems(Item item, String itemName, String imageName){
        GameRegistry.registerItem(item, itemName, MODID)
        .setCreativeTab(tabs)
        .setUnlocalizedName(itemName)
        .setTextureName(MODID + ":"+ imageName);
    }

    /** This method is used when the item's name is the same
    * as its texture name. Helps reduce repetivite typing #lazy:P.
    * Please make sure your item object is initializated */
    public static void registerItems(Item item, String name){
        GameRegistry.registerItem(item, name, MODID)
        .setCreativeTab(tabs)
        .setUnlocalizedName(name)
        .setTextureName(MODID + ":"+ name);
    }

}

NBT

NBTHelper Class - Used to make NBT not as much of a hassle
Code:
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;

public class NBTHelper
{
    public static boolean hasTag(ItemStack itemStack, String keyName)
    {
        return itemStack != null && itemStack.stackTagCompound != null && itemStack.stackTagCompound.hasKey(keyName);
    }

    public static void removeTag(ItemStack itemStack, String keyName)
    {
        if (itemStack.stackTagCompound != null)
        {
            itemStack.stackTagCompound.removeTag(keyName);
        }
    }

    /**
     * Initializes the NBT Tag Compound for the given ItemStack if it is null
     *
     * @param itemStack
     *         The ItemStack for which its NBT Tag Compound is being checked for initialization
     */
    private static void initNBTTagCompound(ItemStack itemStack)
    {
        if (itemStack.stackTagCompound == null)
        {
            itemStack.setTagCompound(new NBTTagCompound());
        }
    }

    public static void setLong(ItemStack itemStack, String keyName, long keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setLong(keyName, keyValue);
    }

    // String
    public static String getString(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setString(itemStack, keyName, "");
        }

        return itemStack.stackTagCompound.getString(keyName);
    }

    public static void setString(ItemStack itemStack, String keyName, String keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setString(keyName, keyValue);
    }

    // boolean
    public static boolean getBoolean(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setBoolean(itemStack, keyName, false);
        }

        return itemStack.stackTagCompound.getBoolean(keyName);
    }

    public static void setBoolean(ItemStack itemStack, String keyName, boolean keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setBoolean(keyName, keyValue);
    }

    // byte
    public static byte getByte(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setByte(itemStack, keyName, (byte) 0);
        }

        return itemStack.stackTagCompound.getByte(keyName);
    }

    public static void setByte(ItemStack itemStack, String keyName, byte keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setByte(keyName, keyValue);
    }

    // short
    public static short getShort(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setShort(itemStack, keyName, (short) 0);
        }

        return itemStack.stackTagCompound.getShort(keyName);
    }

    public static void setShort(ItemStack itemStack, String keyName, short keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setShort(keyName, keyValue);
    }

    // int
    public static int getInt(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setInteger(itemStack, keyName, 0);
        }

        return itemStack.stackTagCompound.getInteger(keyName);
    }

    public static void setInteger(ItemStack itemStack, String keyName, int keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setInteger(keyName, keyValue);
    }

    // long
    public static long getLong(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setLong(itemStack, keyName, 0);
        }

        return itemStack.stackTagCompound.getLong(keyName);
    }

    // float
    public static float getFloat(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setFloat(itemStack, keyName, 0);
        }

        return itemStack.stackTagCompound.getFloat(keyName);
    }

    public static void setFloat(ItemStack itemStack, String keyName, float keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setFloat(keyName, keyValue);
    }

    // double
    public static double getDouble(ItemStack itemStack, String keyName)
    {
        initNBTTagCompound(itemStack);

        if (!itemStack.stackTagCompound.hasKey(keyName))
        {
            setDouble(itemStack, keyName, 0);
        }

        return itemStack.stackTagCompound.getDouble(keyName);
    }

    public static void setDouble(ItemStack itemStack, String keyName, double keyValue)
    {
        initNBTTagCompound(itemStack);

        itemStack.stackTagCompound.setDouble(keyName, keyValue);
    }
}

NBTUpgradeList Class - Wrapper for NBTTagList to make them better contributed by @chbachman
Code:
public class NBTList<E extends INBTAble> implements List<E> {

    public final NBTTagList list;

    public NBTList() {
        this.list = new NBTTagList();
    }

    public NBTList(NBTTagList list) {
        this.list = list;
    }

    public NBTList(NBTTagCompound nbt) {
        this.list = nbt.getTagList("List", Constants.NBT.TAG_COMPOUND);
    }

    public NBTTagCompound addNBTTagCompound(NBTTagCompound nbt) {
        nbt.setTag("UpgradeList", this.list);

        return nbt;
    }

    @Override
    public int size() {
        return this.list.tagCount();
    }

    private E getUpgrade(NBTTagCompound nbt) {
        try {

            // E upgrade = //TODO: add getFromNBTMethodHERE

            // return upgrade;

        } catch (IndexOutOfBoundsException e) {
            return null;
        }
    }

    @Override
    public E get(int index) {
        NBTTagCompound nbt = this.list.getCompoundTagAt(index);

        if (nbt == null) {
            return null;
        }

        E upgrade = this.getUpgrade(nbt);

        if (upgrade == null) {
            this.list.removeTag(index);
            return this.get(index);
        }

        return upgrade;

    }

    @Override
    public boolean add(E upgrade) {

        this.list.appendTag(upgrade.getNBT());

        return true;
    }

    @Override
    public E set(int index, E element) {

        this.list.func_150304_a(index, element.getNBT());

        return element;
    }

    @Override
    public E remove(int index) {

        E upgrade = this.get(index);

        this.list.removeTag(index);

        return upgrade;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        for (E upgrade : c) {
            this.add(upgrade);
        }
        return true;
    }

    @Override
    public void clear() {
        for (int i = 0; i < this.size(); i++) {
            this.remove(i);
        }
    }

    @Override
    public boolean contains(Object o) {

        for (E upgrade : this) {
            if (upgrade.equals(o)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        for (Object o : this) {
            if (this.contains(o)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public int indexOf(Object o) {
        for (int i = 0; i < this.size(); i++) {
            E upgrade = this.get(i);
            if (upgrade.equals(o)) {
                return i;
            }
        }

        return -1;
    }

    @Override
    public boolean isEmpty() {
        return this.size() == 0;
    }

    @Override
    public int lastIndexOf(Object o) {
        for (int i = this.size() - 1; i >= 0; i--) {
            E upgrade = this.get(i);
            if (upgrade.equals(o)) {
                return i;
            }
        }

        return -1;
    }

    @Override
    public boolean remove(Object o) {
        for (int i = 0; i < this.size(); i++) {
            if (this.get(i).equals(o)) {
                this.remove(i);
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        for (Object o : c) {
            if (!this.remove(o)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;
    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        List<E> list = new ArrayList<E>();

        for (int i = fromIndex; i < toIndex; i++) {
            list.add(this.get(i));
        }

        return list;
    }

    @Override
    public Object[] toArray() {
        Object[] objects = new Object[this.size()];

        for (int i = 0; i < this.size(); i++) {
            objects[i] = this.get(i);
        }

        return objects;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T[] toArray(T[] a) {

        if (a.length < this.size()) {
            a = (T[]) this.toArray();
        } else {
            System.arraycopy(this.toArray(), 0, a, 0, this.size());
        }

        if (a.length > this.size()) {
            a[this.size()] = null;
        }

        return a;
    }

    public class IteratorUpgradeList implements ListIterator<E> {

        NBTList<E> list;
        int index = 0;

        public IteratorUpgradeList(NBTList<E> list) {
            this.list = list;
        }

        @Override
        public boolean hasNext() {
            return this.index != this.list.size();
        }

        @Override
        public E next() {
            return this.list.get(this.index++);
        }

        @Override
        public boolean hasPrevious() {
            return this.index != 0;
        }

        @Override
        public E previous() {
            return this.list.get(--this.index);
        }

        @Override
        public int nextIndex() {
            return this.index + 1;
        }

        @Override
        public int previousIndex() {
            return this.index - 1;
        }

        @Override
        public void remove() {
            this.list.remove(this.index);
        }

        @Override
        public void set(E e) {
            this.list.set(this.index, e);
        }

        @Override
        public void add(E e) {
            this.list.add(this.index, e);
        }
    }

    @Override
    public void add(int index, E element) {
        this.add(element);

    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        for (E upgrade : c) {
            this.add(index, upgrade);
        }

        return true;
    }

    @Override
    public ListIterator<E> listIterator() {
        return new IteratorUpgradeList(this);
    }

    @Override
    public Iterator<E> iterator() {
        return new IteratorUpgradeList(this);
    }

    @Override
    public ListIterator<E> listIterator(int index) {
        return new IteratorUpgradeList(this);
    }

}
GUI

GuiFactory Class - used for doing GUI stuff (I haven't used much, but I hear it is useful)
Code:
public class GuiFactory implements IModGuiFactory {

    @Override
    public void initialize(Minecraft minecraftInstance) {

    }

    @Override
    public Class<? extends GuiScreen> mainConfigGuiClass() {
        return ModGuiConfig.class;
    }

    @Override
    public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
        return null;
    }

    @Override
    public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
        return null;
    }
}

ModGuiConfig Class - Again haven't used much, but I am told it is useful (Requires Reference/ConfigurarionHandler)
Code:
public class ModGuiConfig extends GuiConfig{

    public ModGuiConfig(GuiScreen guiScreen)
        {
            super(guiScreen,
                    new ConfigElement(ConfigurationHandler.configuration.getCategory(Configuration.CATEGORY_GENERAL)).getChildElements(),
                    Reference.MOD_ID,
                    false,
                    false,
                    GuiConfig.getAbridgedConfigPath(ConfigurationHandler.configuration.toString()));
        }

}

Block Related Classes

BlockTool Class - a class with tools to use with your blocks Contributed by @McJty
Code:
public class BlockTools {
    public static final int MASK_ORIENTATION = 0x7;
    public static final int MASK_REDSTONE = 0x8;

    public static int getOrientation(int metadata) {
        return metadata & MASK_ORIENTATION;
    }

    public static int setOrientation(int metadata, int orientation) {
        return (metadata & ~MASK_ORIENTATION) | orientation;
    }

    public static boolean getRedstoneSignal(int metadata) {
        return (metadata & MASK_REDSTONE) != 0;
    }

    public static int setRedstoneSignal(int metadata, boolean signal) {
        if (signal) {
            return metadata | MASK_REDSTONE;
        } else {
            return metadata & ~MASK_REDSTONE;
        }
    }

    public static int determineOrientation(World world, int x, int y, int z, EntityLivingBase entityLivingBase) {
        if (MathHelper.abs((float) entityLivingBase.posX - x) < 2.0F && MathHelper.abs((float)entityLivingBase.posZ - z) < 2.0F) {
            double d0 = entityLivingBase.posY + 1.82D - entityLivingBase.yOffset;

            if (d0 - y > 2.0D) {
                return 1;
            }

            if (y - d0 > 0.0D) {
                return 0;
            }
        }
        int l = MathHelper.floor_double((entityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
        return l == 0 ? 2 : (l == 1 ? 5 : (l == 2 ? 3 : (l == 3 ? 4 : 0)));
    }
}

OreDictionary

OreHelper Class - useful when working with the ore dictionary contributed by @goldenapple and taken from Flaxbeard's Steam Power Mod (Requires LogHelper Class for full functionality)
Code:
public class OreHelper {
    public static boolean isItemThisOre(ItemStack item, String ore){
        for (int o : OreDictionary.getOreIDs(item)) {
            if (OreDictionary.getOreName(o).equals(ore)) {
                return true;
            }
        }
        return false;
    }
    //Requires the LogHelper class
    public static void dumpAllOres(){
        for (String l : OreDictionary.getOreNames()){
            LogHelper.info(l);
        }
    }
}

If y'all have any code snippets you would like to share please post them down below and I may add them. Specify a section you want them in (in bold) or if there are none ask for me to create a new one
May I have the power to directly copy this code into a mod? Same for everyone else
 
  • Like
Reactions: GreatOrator

ljfa

New Member
Jul 29, 2019
2,761
-46
0
One thing about the LogHelper:
The FMLLog.log method takes a string and a vararg list of objects and uses String.format internally. Why not make use of it since sometimes you want to print numbers and stuff into the log? My own LogHelper looks like this:
Code:
public class LogHelper {
   public static void log(Level logLevel, String format, Object... data) {
     FMLLog.log(Reference.MODNAME, logLevel, format, data);
   }
  
   public static void trace(String format, Object... data) {
     log(Level.TRACE, format, data);
   }
  
   public static void debug(String format, Object... data) {
     log(Level.DEBUG, format, data);
   }
  
   public static void info(String format, Object... data) {
     log(Level.INFO, format, data);
   }
  
   public static void warn(String format, Object... data) {
     log(Level.WARN, format, data);
   }
  
   public static void error(String format, Object... data) {
     log(Level.ERROR, format, data);
   }
  
   public static void fatal(String format, Object... data) {
     log(Level.FATAL, format, data);
   }
}
(public domain)
And you can still print other objects into the log by using "%s" as format string. %s can actually take any Object as parameter.
 

VapourDrive

New Member
Jul 29, 2019
536
-8
1
These ideas of lib mods seem great but who really wants to use code they didn't write? I would much rather write code myself even if just for the experience and learning.
 
  • Like
Reactions: SatanicSanta

VapourDrive

New Member
Jul 29, 2019
536
-8
1
Then why do frameworks exist?
Well its like the difference behind saying "I want to make my own gocart instead of buying one" and saying "I want to build my own car to drive". The go cart you throw together and enjoy the fields behind your house, but a car needs to meet intense criteria and you aren't the only person it may effect while on the road.
 

ratchet freak

Well-Known Member
Nov 11, 2012
1,198
243
79
this is a better NBTUpgradeList Class
Code:
public class NBTList<E extends INBTAble> extends AbstractList<E> implements RandomAccess {
   public final NBTTagList list;
   
   public NBTList() {
     this.list = new NBTTagList();
   }
   
   public NBTList(NBTTagList list) {
     this.list = list;
   }
   
   public NBTList(NBTTagCompound nbt) {
     this.list = nbt.getTagList("List", Constants.NBT.TAG_COMPOUND);
   }
   
   public NBTTagCompound addNBTTagCompound(NBTTagCompound nbt) {
     nbt.setTag("UpgradeList", this.list);
     return nbt;
   }
   
   @Override
   public int size() {
     return this.list.tagCount();
   }
   
   private E getUpgrade(NBTTagCompound nbt) {
     try {
       // E upgrade = //TODO: add getFromNBTMethodHERE
       // return upgrade;
     } catch(IndexOutOfBoundsException e) {
       return null;
     }
   }
   
   @Override
   public E get(int index) {
     NBTTagCompound nbt = this.list.getCompoundTagAt(index);
     if(nbt == null) {
       return null;
     }
     E upgrade = this.getUpgrade(nbt);
     if(upgrade == null) {
       this.list.removeTag(index);
       return this.get(index);
     }
     return upgrade;
   }
   
   @Override
   public boolean add(int index, E upgrade) {
     this.list.appendTag(upgrade.getNBT());
     return true;
   }
   
   @Override
   public E set(int index, E element) {
     this.list.func_150304_a(index, element.getNBT());
     return element;
   }
   
   @Override
   public E remove(int index) {
     E upgrade = this.get(index);
     this.list.removeTag(index);
     return upgrade;
   }
}

Extends from the skeleton AbstractList<E> so only the get, set, remove and add methods need to be implemented
 
  • Like
Reactions: chbachman