Being that your the event master, what would an event for an auto smelting enchantment look like? Btw its at the point where your gonna get a credit mention on my page lol
Oh, there's still quite a lot I have to learn about events. For auto-smelting, check out 'HarvestDropsEvent', located in minecraftforge/event/world/BlockEvent. It's called just before a block drops its stuff, so you can change what it drops from there.
I did an event on wearing armor, that is when I wear armor, then the rain, it's killing me, when I write: event.entityLiving.attackEntityFrom (DamageSource.cactus, 1); I start at the world the game crashes ....
For armor, it's probably easier to use the Item class method 'onArmorTickUpdate' by overriding it in your Armor class. That way, the method is only called when you are actually wearing your armor, rather than every tick no matter what.
As for your crash, you should post the crash log, but my guess is you're getting a null pointer somewhere and you need to check for it.
Ok, but you still need to post your crash log at the very least, and preferably the code that is causing the crash. If you look in the crash report where it says 'Null Pointer Exception', the following stack trace will give you all the lines leading up to where the object that was null is found. Look for your mod method and the line number. That's what you need to change.
Hello everyone,does someone know,how to do,that mana bar gui will change it's width depends on size of minecraft window? (I need mana bar on almost full screen,but it's can only be nowmal in litte window and small on big window ,or conversely)
Hello everyone,does someone know,how to do,that mana bar gui will change it's width depends on size of minecraft window? (I need mana bar on almost full screen,but it's can only be nowmal in litte window and small on big window ,or conversely)
Look into the class ScaledResoultion. (CTRL+SHIFT+T in eclipse should help you find it) that class should provide some help for ya
Hello everyone,does someone know,how to do,that mana bar gui will change it's width depends on size of minecraft window? (I need mana bar on almost full screen,but it's can only be nowmal in litte window and small on big window ,or conversely)
I don't know about the rest of you, but my gui scales automatically without touching any scaled resolution, both in the Eclipse environment and in Minecraft itself. Open Minecraft, go to the options menu and under video settings you should see a 'gui scale' button. Change it to 'auto'. Done.
And also, how to display current number of mana, like current level on xp bar?
Sounds like you know exactly where to look to find the answer to that one, doesn't it? To display strings, you need to use the FontRenderer. Do as Mazetar suggested and press 'ctrl-shift-t' then type in 'fontrenderer' if you want to see how it all works, but it will be easier for you to just look at other Gui's that use it, such as basically any inventory. Minecraft instance has a FontRenderer object, so you don't need to make a new one, just get it from Minecraft.
If I have too many of these events running every tick will it start to slow the game down dramatically?
That depends what you do each time one of the events is called
Not every event that you put in your EventHandler is called every tick, but only when that certain class of Event is posted to the event bus. So if you have a LivingFallEvent, it's only called when a living entity impacts the ground after falling (which is still quite often). Whatever extra processing you do for that Event is just that, extra processing. Minecraft still has to handle the vanilla event, i.e. calculating fall distance and inflicting damage on the entity, updating its position, etc., regardless of whether or not you have the 'event' in your handler.
If you have a LivingUpdateEvent, it is called every tick, but so is all the other code in all of the onUpdate methods up the chain of inherited Entity classes. Take a look in those methods to see just how much is being processed every single tick for just a single Entity, not to mention all the other things going on in the world. Chances are, the extra code you add won't amount to much. If it does, you may want to rethink how you're coding it, as there is probably a more efficient way.
I forgot to mention this in the tutorial, but if you're adding transparency, you've probably noticed the 3d character model is rendering in a very funky manner. The problem is we disabled the depth testing in the gui overlay, so re-enable it:
// NOTE: be sure to reset the openGL settings after you're done or your character model will be messed up
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthMask(true);
Added a section "Advanced Information". It's not really that advanced, but it goes beyond the basic needs most will require, covering setting listener priority levels, multiple listeners for a single event and more information on cancelable events. I'll try to keep it updated as I learn more.
I am having problems with this section of code, I want to add damage when these items are worn, what is happening though is that it works fine for no weapon, but say if I have a +5 damage platebody on, fists do 6 damage, and so does a wooden sword, a weapon that normall does 7 damage still does 7 and is not even effected.
Any idea what I am doing wrong?
Thanks!
Are you sure the damage isn't being applied? As in, have you done any debugging / println's to see the damage being done to the entity? You can put some println's in the vanilla class (just remember to take them out xD) or make a LivingHurtEvent method to print them out.
One thing that may prevent all of the damage from being properly inflicted is the hurt resistant time - any time an entity takes damage, it becomes temporarily immune to further damage. To get around this, instead of attacking the entity from player damage for each piece of armor / item held, simply add on to a float variable for the total damage you want to inflict and only attack the entity once at the end of the event.
Even better is to add on to event.ammount in LivingHurtEvent if the source of damage is from an EntityPlayer and never make a call to attackEntityFrom.
@ForgeSubscribe
public void onHurt(LivingHurtEvent event)
{
if (event.source.getEntity() instanceof EntityPlayer) {
// check each piece and add damage
if (chest.getItem() == mod_phat.chest) {
event.ammount += 4.0F; // or whatever amount you want
}
if (next item == next mod item) {
event.ammount += some other amount;
}
// and so on; this way the mob is attacked only once with the full damage amount you want
Problem is that I can't get the checks for what is being worn working in while in onHurt
@ForgeSubscribe
public void onHurt(LivingHurtEvent event)
{
EntityPlayer player = event.entityPlayer;
ItemStack boots = player.getCurrentItemOrArmor(1);
ItemStack legs = player.getCurrentItemOrArmor(2);
ItemStack chest = player.getCurrentItemOrArmor(3);
ItemStack helmet = player.getCurrentItemOrArmor(4);
if (event.source.getEntity() instanceof EntityPlayer) {
// check each piece and add damage
if (chest.getItem() == mod_phat.chest) {
event.ammount += 5.0F; // or whatever amount you want
}
if (chest.getItem() == mod_phat.chest) {
event.ammount += 3.0F; // or whatever amount you want
}
if (chest.getItem() == mod_phat.chest) {
event.ammount += 2.0F; // or whatever amount you want
}
}}
I tried adding another argument like attackentity event but that just crashed it.
There is no direct instance of EntityPlayer in LivingHurtEvent; there is event.entity which is the entity taking damage, and then there is the DamageSource which may or may not have an entity associated with it. In your case, you want to check if the DamageSource's getEntity() method returns an instance of EntityPlayer, like I showed in my code snippet, and use that entity as your EntityPlayer:
if (event.source.getEntity() instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) event.source.getEntity();
// now you've got your player to do with as you will
}
If you dissect DamageSource's code a little, you will see there are 2 methods, getSourceOfDamage and getEntity. When a player causes damage directly, then EntityDamageSource is used which then returns the player from either of the above two methods; when a player causes damage indirectly, such as from firing an arrow or throwing a potion, then EntityDamageSourceIndirect is used, and it distinguishes between the two methods: getSourceOfDamage() returns the entity directly responsible for the damage, e.g. the EntityArrow, and getEntity() returns the entity responsible for unleashing the source of damage, if any, such as the player shooting the arrow.
EDIT: To be more clear, you need to move your checks for equipped gear to within the if statement that checks for EntityPlayer, because before that you won't have a player to use.
wondering if you could give me any help, it's saying "proxy cannot be resolved" and "The method saveProxyData(EntityPlayer) is undefined for the type ExtendedPLayer"
wondering if you could give me any help, it's saying "proxy cannot be resolved" and "The method saveProxyData(EntityPlayer) is undefined for the type ExtendedPLayer"
Sorry yeah, that part is a bit confusing because I didn't write the exact code... perhaps I should look into re-writing that section
proxy is a reference to your CommonProxy class, but you will probably be using it statically:
// in your ExtendedProperties class:
public static final void saveProxyData(EntityPlayer player)
{
ExtendedPlayer playerData = ExtendedPlayer.get(player);
NBTTagCompound savedData = new NBTTagCompound();
playerData.saveNBTData(savedData);
CommonProxy.storeEntityData(getSaveKey(player), savedData);
}
// in the LivingDeathEvent:
if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) {
ExtendedPlayer.saveProxyData((EntityPlayer) event.entity);
}
For your event code, let me just point out some problems:
@ForgeSubscribe
public void EntityItemPickupEvent(EntityPlayer player, EntityItem item)
{
EntityXPOrb xp = (item.EntityXPOrb); // here you are assigning xp to the entity from the parameter
// then you're checking if the parameter is equal to the object you just assigned to the parameter???
if (item == xp); // <-- see that '; ' semi-colon there? that ends the if statement, so nothing is actually in this if statement...
{
// this is what you think is inside the if statement, but it's actually not for the above reason
}
}
Ok, now that that's out of the way, on to some solutions. It helps to write out step by step the logic of what you need to do:
1. EntityItemPickupEvent fires for EVERY item that is picked up, not just Xp orbs, so you need to check if the EntityItem is an EntityXpOrb before doing anything else. Use 'if (item instanceof EntityXPOrb)' to check
2. Once you know it's an xp orb, you want to add xp to the player's extended properties, so you'll need a method to add xp in your extended properties class and call that, using the amount of xp from the orb as a parameter. You'll also need to be able to access your extended properties from the event method, for which you can find many examples in the tutorial
3. EntityXPOrb has a method getXpValue() that should be pretty obvious what it does
And the problem is that xporbs are not items, they are entities.
Would changing EntityItem to just Entity still work?
EntityItem IS an Entity All items become entities when dropped, and turn back into items when picked up. During the event, they are still in their entity state.
// finally, we sync the data between server and client (we did this earlier in 3.3)
((ExtendedPlayer)(event.entity.getExtendedProperties(ExtendedPlayer.EXT_PROP_NAME))).syncProperties();
}
syncProperties is never made.
Sorry, that part is nested away in the Gui Overlay section, as that's where it came up as necessary to synchronize data and I renamed it to 'sync()'. Unless you want to display how much xp the player has in a Gui or something of that nature, you probably don't need to worry about synchronization; just store the data on the server side xD
EDIT: Thanks for pointing that out - I've placed a notice in section 3.4 reminding people to look in 3.3 for the initial discussion on synchronization, rather than going straight to DataWatcher.
Also if I only have one value at the moment do I need to bother with anything like
// save player data:
proxy.storeEntityData(((EntityPlayer) event.entity).username + ExtendedPlayer.EXT_PROP_NAME, playerData);
// save living data:
proxy.storeEntityData(((EntityPlayer) event.entity).username + ExtendedLiving.EXT_PROP_NAME, playerData);
// load player data:
NBTTagCompound playerData = proxy.getEntityData(((EntityPlayer) event.entity).username + ExtendedPlayer.EXT_PROP_NAME);
// load living data
NBTTagCompound playerData = proxy.getEntityData(((EntityPlayer) event.entity).username + ExtendedLiving.EXT_PROP_NAME);
Yes and no.
Yes, if you want your data to persist across player death, you will still need to save and load the data somehow. I find storing it in the CommonProxy to be easy, but you could also set up an IPlayerTracker class which is nice if you need additional methods for tracking players.
No, you don't need to bother with the different EXT_PROP_NAMEs, but it will make your life easier if you ever decide to add different kinds of properties in the future.
Oh, there's still quite a lot I have to learn about events. For auto-smelting, check out 'HarvestDropsEvent', located in minecraftforge/event/world/BlockEvent. It's called just before a block drops its stuff, so you can change what it drops from there.
For armor, it's probably easier to use the Item class method 'onArmorTickUpdate' by overriding it in your Armor class. That way, the method is only called when you are actually wearing your armor, rather than every tick no matter what.
As for your crash, you should post the crash log, but my guess is you're getting a null pointer somewhere and you need to check for it.
Make high-quality models in the Techne. And do the model in Blender.
Ok, but you still need to post your crash log at the very least, and preferably the code that is causing the crash. If you look in the crash report where it says 'Null Pointer Exception', the following stack trace will give you all the lines leading up to where the object that was null is found. Look for your mod method and the line number. That's what you need to change.
What do you mean? Section 3.3 already covers rendering current mana / max mana in a mana bar on the screen. Do you want to do it the other way around?
Look into the class ScaledResoultion. (CTRL+SHIFT+T in eclipse should help you find it) that class should provide some help for ya
By using a GUI Overlay.
You can read about it here:
www.minecraftforge.net/wiki/Gui_Overlay
That shows how to implement it for a buff/debuff bar but you should easily be able to see how you can customize it to be your bar
I don't know about the rest of you, but my gui scales automatically without touching any scaled resolution, both in the Eclipse environment and in Minecraft itself. Open Minecraft, go to the options menu and under video settings you should see a 'gui scale' button. Change it to 'auto'. Done.
Sounds like you know exactly where to look to find the answer to that one, doesn't it? To display strings, you need to use the FontRenderer. Do as Mazetar suggested and press 'ctrl-shift-t' then type in 'fontrenderer' if you want to see how it all works, but it will be easier for you to just look at other Gui's that use it, such as basically any inventory. Minecraft instance has a FontRenderer object, so you don't need to make a new one, just get it from Minecraft.
That depends what you do each time one of the events is called
Not every event that you put in your EventHandler is called every tick, but only when that certain class of Event is posted to the event bus. So if you have a LivingFallEvent, it's only called when a living entity impacts the ground after falling (which is still quite often). Whatever extra processing you do for that Event is just that, extra processing. Minecraft still has to handle the vanilla event, i.e. calculating fall distance and inflicting damage on the entity, updating its position, etc., regardless of whether or not you have the 'event' in your handler.
If you have a LivingUpdateEvent, it is called every tick, but so is all the other code in all of the onUpdate methods up the chain of inherited Entity classes. Take a look in those methods to see just how much is being processed every single tick for just a single Entity, not to mention all the other things going on in the world. Chances are, the extra code you add won't amount to much. If it does, you may want to rethink how you're coding it, as there is probably a more efficient way.
In short, I wouldn't worry about it too much
Are you sure the damage isn't being applied? As in, have you done any debugging / println's to see the damage being done to the entity? You can put some println's in the vanilla class (just remember to take them out xD) or make a LivingHurtEvent method to print them out.
One thing that may prevent all of the damage from being properly inflicted is the hurt resistant time - any time an entity takes damage, it becomes temporarily immune to further damage. To get around this, instead of attacking the entity from player damage for each piece of armor / item held, simply add on to a float variable for the total damage you want to inflict and only attack the entity once at the end of the event.
Even better is to add on to event.ammount in LivingHurtEvent if the source of damage is from an EntityPlayer and never make a call to attackEntityFrom.
There is no direct instance of EntityPlayer in LivingHurtEvent; there is event.entity which is the entity taking damage, and then there is the DamageSource which may or may not have an entity associated with it. In your case, you want to check if the DamageSource's getEntity() method returns an instance of EntityPlayer, like I showed in my code snippet, and use that entity as your EntityPlayer:
If you dissect DamageSource's code a little, you will see there are 2 methods, getSourceOfDamage and getEntity. When a player causes damage directly, then EntityDamageSource is used which then returns the player from either of the above two methods; when a player causes damage indirectly, such as from firing an arrow or throwing a potion, then EntityDamageSourceIndirect is used, and it distinguishes between the two methods: getSourceOfDamage() returns the entity directly responsible for the damage, e.g. the EntityArrow, and getEntity() returns the entity responsible for unleashing the source of damage, if any, such as the player shooting the arrow.
EDIT: To be more clear, you need to move your checks for equipped gear to within the if statement that checks for EntityPlayer, because before that you won't have a player to use.
I'm attempting to follow your Tutorial, and I'm having a bit of trouble with the bit about keeping the value after death, specifically these lines.
proxy.storeEntityData(((EntityPlayer) event.entity).username, playerData);
// call our handy static one-liner to save custom data to the proxy
PlayerValues.saveProxyData((EntityPlayer) event.entity);
}
wondering if you could give me any help, it's saying "proxy cannot be resolved" and "The method saveProxyData(EntityPlayer) is undefined for the type ExtendedPLayer"
Sorry yeah, that part is a bit confusing because I didn't write the exact code... perhaps I should look into re-writing that section
proxy is a reference to your CommonProxy class, but you will probably be using it statically:
See TechGuy's great tutorial on mod annotation.
For your event code, let me just point out some problems:
Ok, now that that's out of the way, on to some solutions. It helps to write out step by step the logic of what you need to do:
1. EntityItemPickupEvent fires for EVERY item that is picked up, not just Xp orbs, so you need to check if the EntityItem is an EntityXpOrb before doing anything else. Use 'if (item instanceof EntityXPOrb)' to check
2. Once you know it's an xp orb, you want to add xp to the player's extended properties, so you'll need a method to add xp in your extended properties class and call that, using the amount of xp from the orb as a parameter. You'll also need to be able to access your extended properties from the event method, for which you can find many examples in the tutorial
3. EntityXPOrb has a method getXpValue() that should be pretty obvious what it does
EntityItem IS an Entity All items become entities when dropped, and turn back into items when picked up. During the event, they are still in their entity state.
Sorry, that part is nested away in the Gui Overlay section, as that's where it came up as necessary to synchronize data and I renamed it to 'sync()'. Unless you want to display how much xp the player has in a Gui or something of that nature, you probably don't need to worry about synchronization; just store the data on the server side xD
EDIT: Thanks for pointing that out - I've placed a notice in section 3.4 reminding people to look in 3.3 for the initial discussion on synchronization, rather than going straight to DataWatcher.