Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. One thing that may be an issue that I've run into before: try switching the order of where you init your blocks versus init your items. If you think about it, you're setting up a seed that tries to reference a block instance during construction, but that block isn't registered yet. So switch it to this: ModBlocks.init(); ModItems.init(); I should add this warning about registration order in my tutorial...
  2. If it is your custom entity, you can override the onDeath() method. For general entities you can use handle the LivingDeathEvent.
  3. It kinda sounds like your stats are never getting changed on the server extended properties and then they are being saved and loaded. One thing I do is I actually sync the entire NBTTagCompound of the extended properties. ByteBufUtils allows you to read and write a whole tag compound. Assuming you don't have a lot of properties, it isn't really that wasteful to send the whole thing and it makes the coding a lot easier than making a packet to sync each property type. Otherwis, I just say add a bunch of System.out.println() statements that are informative in each method to help you trace the execution. You should be able to print out the values as you put them into the packets and as you receive them, you should be able to trace the values on both the client and server side to see if they get out of sync. Basically you just need to do some old fashioned debugging/
  4. Not sure why @Kwibble was being hard on you because you had actually tried the right method and if you hadn't encountered it before you may not ever have realized that the float value is really more of a percentage so has limited range. 1.0F = maximum, 0.0F = minimum and you can guess what values in between do. Now you know.
  5. One way to do it is just to handle a tick event, probably world tick event. You can check every tick, but could also just check once a second or whatever you think is responsive enough for your need. You can then look at all existing EntityCow and save their positions in a array, map or list and then compare them with previous value, then flag as changed. Do you understand what I mean?
  6. I think the concepts should be same with regular seed and seed food. I know there was a lot of info in my tutorial so you may have missed it but I explained that if you don't want it to be a seed food: "Note: If you don't want it to be a food, you could just extend Item while implementing IPlantable." Basically an item becomes a seed by implementing IPlantable. I also explain the important bits about how it determines if you can actually plant it, like the crop type, etc. Anyway, you said that it was "crashing" when you're trying to plant it. Looking at your crash code it is just a null pointer exception. When is this crash happening? Right when you try to start the game? Or after you're playing and try to plant the seed?
  7. I have a tutorial on making custom crops: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-creating-custom.html
  8. In theory this works, but it's bad practice. At some point in the future FML / Forge might even put a system in place to prevent this, for good reasons. Don't put stuff in packages that are not yours. See? Already made a mistake IF you were to use this method. You have to keep in mind that you are in a package which is not yours. If another mod would do the same thing, and also name their class EntityPassiveAccessor (as that's the first name that comes to mind, right?) - BOOM. So please people, use Reflection or AccessTransformers. If used correctly, Reflection is barely slower than normal method invocation and unless you're working in time-critical areas of the code (Rendering, things that happen every tick, etc.) you will be just fine by using Reflection. Using ATs also recently got a whole lot easier since now you don't even need to make a Coremod to use them. Thanks for the ideas on why this might be bad idea. I should use reflection more often, but it has always seemed to me to be more hacking than modding, but since it is a solid way to do most of these things I guess it is the way to go. I need to revisit ATs as well. Too bad simply changing package isn't good idea -- it is sooo easy!
  9. I don't know much about playing sound, but it seems that most of your problem is related to having the repeat and the resource and other fields and methods are mostly protected. I have used a trick before, and it probably isn't good Java practice, but you can say that your class belongs to package net.minecraft.client.audio and then it will have access to all the protected fields in the various sound-related classes. In your class you can make public methods that expose those fields to the rest of your mod's classes. I'm not sure what the side effect, if any, of referencing the package as a minecraft package. It seems to make the IDE happy, and in Eclipse at least it creates a folder in my workspace and not in the file folders where the minecraft package library actually resides. Anyway, since you're working so hard at this figured I'd throw you a tip even though I'm not very familiar with doing much with sound in mods.
  10. Are your models in assets? Are you sure the assets are exported properly (into correct locations in resulting jar)? Do you see any console errors related to the models? Also, it seems to be worse that just not showing the models, it doesn't even have a space for them. To me that means that the item itself isn't registered to the tab. I know your code and your Eclipse testing shows that they do work, but obviously something is wrong in the exported version. I would add debug console statements to the constructors of those items to confirm that they are indeed being created. You may want to print out all the items in the game in the postInit() portion of the FML life cycle, to confirm that they are there.
  11. @diesieben07, what do you think about creating an "accesser" class in a Minecraft package to get to protected methods and fields? For example, the problem here is that the getExperiencePoints() method is protected (strangely). But I found I can access it and achieve the OP's goal of intercepting the xp drop to top it up with more xp like this. CoolAlias suggested this method to someone yesterday, and I just had to try it out. It seems to work! I create a class (in my project) that says it's in the same Minecraft package as the EntityAnimal for example. package net.minecraft.entity.passive; import net.minecraft.entity.player.EntityPlayer; public class EntityPassiveAccessor { public static int getPassiveXP(EntityAnimal theEntity, EntityPlayer thePlayer) { // DEBUG System.out.println("Last attack by player: Accessed Passive Entity XP"); return theEntity.getExperiencePoints(thePlayer); } } Notice the package in the class is a Minecraft package. And then I can now access the method from within my project by calling this class. For example, I can handle the living drops event like this: @SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true) public void onEvent(LivingDropsEvent event) { if (event.source.getEntity() instanceof EntityPlayer) { EntityPlayer thePlayer = (EntityPlayer) event.source.getEntity(); // DEBUG System.out.println("Killed by a player"); if (event.entityLiving instanceof EntityAnimal) { EntityAnimal entityAnimal = (EntityAnimal)event.entityLiving; // DEBUG System.out.println("The animal's XP drop is ="+net.minecraft.entity.passive.EntityPassiveAccessor.getPassiveXP(entityAnimal, thePlayer)); } } } You can see that I am now calling that class which has a method that accesses the protected method in the EntityAnimal class. And the console output from when I kill a cow looks like this was successful: Killed by a player Last attack by player: Accessed Passive Entity XP The animal's XP drop is =3 Of course I could then check the XP and if I wanted to drop some extra I could do that in the handler event. Anyway, it seems to work to create a class within my project that is actually in package elsewhere. Is that bad practice? Is there an actual problem with this?
  12. Hmmm, weird. I thought I looked for that because I'm quite aware of it for LivingHurtEvent, but guess I missed it in LivingDropsEvent. Yeah, that helps me do what I want. I still think it is weird that getLastAttacker() is useless for animal entities, but oh well -- part of the fun of modding is building up knowledge of these peculiarities. One thing I've definitely learned is you can't just trust the name of a method, but you really have to trace back its source to ensure it is doing what you want. Another example that really screwed me up for a while is that there is a method in EntityLivingBase called isClientWorld() that mistakenly returns true for server world -- that took me a while to debug ... I like hunting for useful methods, but there are some that are definitely misnamed.
  13. I'm not sure this is the right field. This is field to attack, but I want the field of the last attacker (i.e. what attacked it last). Also, entityLivingToAttack field is private, although I guess you're saying I can access it by virtue of being passed through the public method getAITarget(). But again I don't want the attack target, I want the entity that last attacked. I think I can just set lastAttacker field myself. I'm thinking that in LivingHurtEvent I can check if it is null, and if not I can set it to the damage source entity. I'm going to try that and will report back.
  14. Thanks coolalias for tracing it. Yeah it seems dumb that it isn't overridden in every entity. Probably only used in mobs that have retaliation AI or something. I guess I can create an extended property to EntityAnimal to create my own tracking of last attacker, but seems like bit of a pain. Or maybe I can set it in event handler for living hurt. Have to consider this further...
  15. I was just trying to use the LivingDropsEvent to check last attacker to affect some drops, and started by testing on killing a cow. However, I noticed that the getLastAttacker() always returned null. To speed up my testing I tried a similar thing on LivingHurtEvent and still the same. Now I know the LivingHurtEvent has a DamageSource field and that works fine. But the LivingDropsEvent doesn't seem to have that. And I'm curious why the last attacker is null for the cow. In my event handler I have simply: @SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true) public void onEvent(LivingHurtEvent event) { // DEBUG System.out.println("Entity hurt, entity = "+event.entityLiving.toString()); if (event.entityLiving.getLastAttacker() != null) { System.out.println("Last attacker was "+event.entityLiving.getLastAttacker().toString()); } else { System.out.println("Last attacker was null"); } Then I run it and attack some cows. The console output happily shows this event being triggered indicating the cow entity at the location I'm attacking, but it always says the last attacker was null, even after multiple attacks (I thought perhaps on first attack it might not be set yet). If I switch to checking event.source, it correctly finds that the player was attacking. But again I want to detect last attacker in a different event that doesn't have source field, plus I'm curious about the issue. Last attacker always null: what's up with that?
  16. You can change the AI of vanilla mobs directly. However, passive animals don't have a targetTasks list, so I don't think it would be easy to add hostile AI tasks. So I think what you want to do is create your own custom EntityHostileCow, EntityHostileSheep, etc. that extend the original passive animal. But you would add target AI tasks similar to what hostile mobs have. Then you would handle the LivingSpawnEvent, and if the event.entityLiving instanceof EntityCow you'd replace it with your EnityHostileCow, and so forth. If your custom classes extend the vanilla ones, then they should generally be treated as the original, except the AI would be different. Note that to successfully attack a mob also needs to register an attackDamage attribute.
  17. Thanks both of you. Pretty much what I expected. Need to bring original item along with the entity. Data watcher is interesting as it would save the packet sync. I need to look at that additional spawn data interface, also looks interesting and isn't something I noticed before.
  18. Okay, I've been happily modding entities for a while now, with custom models and renderer classes and it worked well. I recently tried to do something that required something to be dynamically passed to the renderer and when I really thought about how the renderer registration works I started to confuse myself. The confusion came about because I was creating an egg-like throwable item and so I copied the render class for the snowball item. However, the constructor for the snowball takes an Item parameter and so at the time of registration you have to pass an instance to it. But my problem is that each instance of my item may render differently (mostly different colors). So I think it won't work directly because the Item instance passed to the RenderSnowball during registration will be different than the instance of the item I'm actually wanting to render. In other words it will render the original item passed and not the current one that created the entity being thrown. I just want to confirm that point, as I guess I'll have to go through some hoops to make it work. Basically my plan is to have the throwable entity get the custom render information from the item at the time it is thrown, and then pass that back to the renderer. Not sure if my explanation above is clear. My question is specifically whether the RenderSnowball will render the Item as registered rather than the item as used to create the entity. My review of the code indicates: yes.
  19. Guys, you should really use @Override annotation so your IDE (Eclipse in my case) will check for you whether you've got the method name and parameter types correct. In Java, if you made a simple spelling mistake in the method name it will think you did it purposefully and won't create any warning. But it will never get called because the properly named method will exist in the parent class and get run from there. There are two ways to use @Override to check. One is you can get in the habit of always putting @Override when you think you're using an inherited method. The other way (I do this cause I'm a bit lazy) is to set up your Eclipse so that on save it will add the @Override for you. If you do that, then the idea is that when you save (and you should save often) you should look to confirm that @Override was added where expected. If you had used it in this case, you wouldn't be arguing about whether there was such a method, or whether it was added in 1.7.x -- the IDE would tell you right away if it was an existing method. In any case, not using @Override will cause you to make mistakes that will be very hard to catch later. Use @Override!
  20. It's telling you what you did wrong--you didn't make a constructor that doesn't have parameters but then you called it without parameters. I think you should read a book on Java. There is a very simple book I recommend called Java in Easy Steps that is really short and isn't boring but covers all the main topics. But not to be mean, but if you don't understand constructors you won't be able to program mods. I don't think you should just put start id in the new instance call, the int parameter is meant to represent the rarity of the item. From Item class comment: how often the item is chosen, higher number is higher chance(lower is lower) For the error regarding the super call, it seems that maybe you imported the wrong Item class. Can you post your code to show the imports in your class?
  21. Also check your console for error messages indicating it isn't finding the texture asset. If you see those, then it means you either don't have the texture in the right place, or it can't be found because you didn't reference it properly.
  22. If it is a custom item, then I think you just need to override the method onItemUse() or maybe onItemRightClick() depending on how you want it to work. In that method you can just teleport back to the spawn point, I think just by setting the position back to the spawn position. You shouldn't need to kill the player to do that. You can just set the player position to the spawn position. The last spawn position if they Player slept in a bed is from the getBedLocation() method. If that returns null, then it means they haven't slept in a bed so you need to get the original spawn location which I believe is from worldObj.getSpawnPoint() method.
  23. Wow that is interesting.
  24. Did you read my tutorial on events I linked in previous post?
  25. Are you sure that your event handler is being called? Like you properly created an event handler on the right bus? You want to make sure that is working before fiddling around with the formatting.
×
×
  • Create New...

Important Information

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