Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/06/17 in all areas

  1. If you create a new entity, you may have stumbled across the Attribute System, for example if you want a custom max. health value. Now a detailed explanation on what the Attribute System actually is can be found here: http://minecraft.gamepedia.com/Attribute Here I will show you how to create your own Attributes for your entity and modify all of them in code. NOTE: all attribute classes mentioned in this tutorial can be found in the package net.minecraft.entity.ai.attributes. Create a new Attribute Step 1: To create a new attribute, you first need to create a new IAttribute instance (preferably static final in your entity registry class or somewhere). Now you don't need to make a new class which implements that interface! Minecraft provides us with a standard class currently used for all its own Attributes called RangedAttribute. The constructor of that has the following parameters: IAttribute parentIn - a parent attribute if available, can be null String unlocalizedNameIn - the unlocalized name of the attribute. You can't add an attribute with the same name to an entity, so I usually precede the name with my Mod ID separated with a dot like TurretMod.MOD_ID + ".maxAmmoCapacity" double defaultValue - the default value of the attribute. This value is set as base value when the entity is first created. It can't be lower than the minimum nor higher than the maximum value or else it will throw an IllegalArgumentException double minimumValueIn - the minimum value of the attribute. This value is usually 0.0D. If the entity's attribute value falls below that, this value is used for it instead. It can't be bigger than the maximum value or else it will throw an IllegalArgumentException double maximumValueIn - the maximum value of the attribute. This value is usually Double.MAX_VALUE. If the entity's attribute value falls above that, this value is used for it instead. It can't be smaller than the minimum value or else it will throw an IllegalArgumentException Now at the end, my IAttribute instance variable looks like this: public static final IAttribute MAX_AMMO_CAPACITY = new RangedAttribute(null, TurretMod.MOD_ID + ".maxAmmoCapacity", 256.0D, 0.0D, Double.MAX_VALUE); But wait! If you want to share the attribute value and modifiers with the client, you'll need to call setShouldWatch(true) on that variable. The same way you can disable it, for whatever reason, with false instead of true as the parameter value. Conveniently it returns itself, so you can make a neat one-liner like this: public static final IAttribute MAX_AMMO_CAPACITY = new RangedAttribute(null, TurretMod.MOD_ID + ".maxAmmoCapacity", 256.0D, 0.0D, Double.MAX_VALUE).setShouldWatch(true); Step 2: Great, now you have this useless variable the entity doesn't know about. To make it useful and working with the entity, you first need to register it to the entity's attribute list. To do so, override applyEntityAttributes()(if you've not already done so while changing the entity's max. health) and call this.getAttributeMap().registerAttribute(MY_OWN_ATTRIBUTE_VARIABLE), where MY_OWN_ATTRIBUTE_VARIABLE is firstly an overly long name, but more importantly your variable of your attribute instance created in Step 1. Here's an example from my mod: @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); // Make sure to ALWAYS call the super method, or else max. health and other attributes from Minecraft aren't registered!!! this.getAttributeMap().registerAttribute(TurretAttributes.MAX_AMMO_CAPACITY); } Step 3: The attribute is now instanciated and registered, but how do I use its value? Simple! Just call this.getEntityAttribute(MY_OWN_ATTRIBUTE_VARIABLE).getAttributeValue(). It returns a double. If you want it to be an int, just use the MathHelper from Minecraft, for example MathHelper.ceiling_double_int(doubleVal) Modify an Attribute Now, to modify an attribute, there are 2 ways of doing so: 1. modify its base value This is simple and straight forward, and as mentioned 2 times here so far, you may have already done this via the entity's max. health attribute. But to be complete, here's how you change the base value of an attribute with the example on the max. health: this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); //sets the entity max. health to 40 HP (20 hearts) Please note: this does NOT get synched with the client! If you need to edit the base value, make sure you use packets if you want it to be shared (or change it on both sides). Otherwise use modifiers! 2. add modifiers to the attribute This is a "reversable" way of changing the attribute value w/o messing with the base value. What we will do here is essentally this: http://minecraft.gamepedia.com/Attribute#Modifiers That said, much like the Attribute Instance, we need to create our own AttributeModifier instance variable. Conveniently, there is already a class for us to use called AttributeModifier. It's constructor parameters are as follows: UUID idIn - the UUID of this modifier, much like the Attribute name, this needs to be unique per Attribute. I usually give it a pre-defined, hardcoded Ver. 4 UUID via UUID.fromString("MY-UUID"), which was generated on this site. Mine looks like this: UUID.fromString("e6107045-134f-4c54-a645-75c3ae5c7a27") String nameIn - the Modifier name, can be anything except empty, preferably readable and unique for the Attribute. Since the "uniqueness" of the modifier is already defined in the UUID, you can have duplicate names. double amountIn - the Modifier value, can be anything. Note that the attribute, as prevously explained, has a min/max value and it can't get past that! int operationIn - the Operation of the Modifier (careful, magic numbers over here!). Have a direct quote from the Minecraft Wiki: Brief explanation: Operation number is the value you feed the parameter. I also made an enum for it complete with javadoc for you to copy (with credits of course) if you want: https://github.com/SanAndreasP/SAPManagerPack/blob/master/java/de/sanandrew/core/manpack/util/EnumAttrModifierOperation.java Now I've covered the parameters, it's time to make a new instance like this: MY_CUSTOM_MODIFIER = new AttributeModifier(UUID.fromString("e6107045-134f-4c54-a645-75c3ae5c7a27"), "myCustomModifier420BlazeIt", 0.360D, EnumAttrModifierOperation.ADD_PERC_VAL_TO_SUM.ordinal()); You have the new modifier instance, but what do do with it? You can add or remove modifiers from an attribute like this (method names are self-explanatory): entity.getEntityAttribute(MY_ATTRIBUTE_INSTANCE).applyModifier(MY_CUSTOM_MODIFIER); entity.getEntityAttribute(MY_ATTRIBUTE_INSTANCE).removeModifier(MY_CUSTOM_MODIFIER); Alright, you know now everything there is to know about attributes... wait, there's one more thing: attributes are saved and loaded automatically by the entity, no need to do that manually! Just make sure the client knows about the Attribute (register it properly as I've shown).
    1 point
  2. Basically you just need to move all the code into a single for loop public class ItemGeneric { static public ItemBase item_nugget = null; static public ItemBase item_ingot = null; static public ItemBase item_chunk = null; public static void initItems() { for(EnumMaterialMetal enummaterial:EnumMaterialMetal.values()) { item_nugget = new ItemBase(enummaterial); item_nugget.setUnlocalizedName("nugget" + enummaterial.suffix); GameRegistry.register(item_nugget.setRegistryName("nugget" + enummaterial.suffix)); OreDictionary.registerOre("nugget" + enummaterial.suffix, new ItemStack(item_nugget, 1, 0)); item_nugget.setCreativeTab(IndifferentOres.altTabItems); IndifferentOres.proxy.registerItemRenderer(item_nugget); item_ingot = new ItemBase(enummaterial); item_ingot.setUnlocalizedName("ingot" + enummaterial.suffix); GameRegistry.register(item_ingot.setRegistryName("ingot" + enummaterial.suffix)); OreDictionary.registerOre("ingot" + enummaterial.suffix, new ItemStack(item_ingot, 1, 0)); item_ingot.setCreativeTab(IndifferentOres.altTabItems); IndifferentOres.proxy.registerItemRenderer(item_ingot); item_chunk = new ItemBase(enummaterial); item_chunk.setMaxStackSize(enummaterial.MAX_STACK_SIZE); item_chunk.setUnlocalizedName("chunk" + enummaterial.suffix); GameRegistry.register(item_chunk.setRegistryName("chunk" + enummaterial.suffix)); OreDictionary.registerOre("chunk" + enummaterial.suffix, new ItemStack(item_chunk, 1, 0)); item_chunk.setCreativeTab(IndifferentOres.altTabChunks); IndifferentOres.proxy.registerItemRenderer(item_chunk); GameRegistry.addRecipe(new ItemStack(item_ingot), new Object[] {"###", "###", "###", '#', item_nugget}); // Nine Nuggets will make one ingot. GameRegistry.addShapelessRecipe(new ItemStack(item_nugget, 9), new ItemStack(item_ingot, 1)); // One Ingot will make nine nuggets GameRegistry.addSmelting(item_chunk, new ItemStack(item_nugget, 3), 1.0F); //One ore Chunk will make three nuggets. } } } Which could be optimised: public class ItemGeneric { protected static ItemBase getItem(EnumMaterialMetal enummaterial, String _type) { ItemBase item = new ItemBase(enummaterial); item.setMaxStackSize(enummaterial.MAX_STACK_SIZE); item.setUnlocalizedName(_type + enummaterial.suffix); GameRegistry.register(item.setRegistryName(_type + enummaterial.suffix)); OreDictionary.registerOre(_type + enummaterial.suffix, new ItemStack(item, 1, 0)); chunk.setCreativeTab(IndifferentOres.altTabChunks); IndifferentOres.proxy.registerItemRenderer(item); return item; } public static void initItems() { ItemBase item_nugget; ItemBase item_ingot; ItemBase item_chunk; for(EnumMaterialMetal enummaterial:EnumMaterialMetal.values()) { item_nugget = getItem(enummaterial,"nugget"); item_ingot = getItem(enummaterial,"ingot"); item_chunk = getItem(enummaterial,"chunk"); GameRegistry.addRecipe(new ItemStack(item_ingot), new Object[] {"###", "###", "###", '#', item_nugget}); // Nine Nuggets will make one ingot. GameRegistry.addShapelessRecipe(new ItemStack(item_nugget, 9), new ItemStack(item_ingot, 1)); // One Ingot will make nine nuggets GameRegistry.addSmelting(item_chunk, new ItemStack(item_nugget, 3), 1.0F); //One ore Chunk will make three nuggets. } } } Note that if you wanted to access the items you would need to store them in an array or list in the getItem code or ask the registry for them using their registry name.
    1 point
  3. With each loop, you are constantly overwriting the ItemBase fields, thus resulting in the field only containing the latest iteration of each loop. This is because a field can only hold 1 instance at a time. I recommend you use metadata to store each different nugget in 1 Item, each different nugget in 1 Item etc. You can also add every nugget and ingot to a single Item, but that would clutter your code a lot. Also, as you've stated, you currently don't have any experience in Java or another OOP language. While you may be able to pull it off, a lot of people couldn't and came to the forums with non-Minecraft, pure Java related questions, which sometimes is a PITA. So I, and a lot of other people on the forums, really recommend you to get a basic grasp of Java by any means other than Minecraft, just to get a better understanding of OOP in general.
    1 point
  4. Your AABB is not big enough. You're missing the fact that your block exists at (x,y,z) and has a SIZE of (1,1,1)
    1 point
  5. Set a breakpoint and step through your code in the debugger. Then you'll see what's happening (and probably why).
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.