Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Everything posted by coolAlias

  1. You can intercept all mouse actions using MouseEvent from minecraft.forge.net.client.event. event.button // id of button: 0 left, 1, right, -1 wheel event.buttonstate // true when pressed, false when released event.dwheel // mouse wheel amount event.setResult(Event.Result.DENY) // prevents the click from processing, but button.pressed will still be true event.setCanceled(true) // completely cancels the button press, such that button.pressed is not set to true If you want to see this in action, you can take a look at how I handle user input for my Zelda Sword Skills mod. In the ZSSEventHandler class, search for 'onMouseChanged'. Here's the github link: https://github.com/coolAlias/ZeldaSwordSkills/blob/master/src/zeldaswordskills/handler/ZSSEventHandler.java
  2. It's the same as entityInit in Entity classes; it gets called during entity construction, so you could put the exact same code in your constructor and it would have the same effect. The benefit of the init method in IExtendedEntityProperties is that it provides a world object, but I haven't found it (the extra world parameter) particularly useful because the entity itself isn't yet finished constructing.
  3. Take a look at the code for the player inventory GUI; the player model is rendered (skin and all) is rendered within the larger gui screen.
  4. You can add datawatcher in either the init or in the constructor, doesn't really matter since init is called during class construction anyway.
  5. If everything is saving and loading properly, then you're fine. The problem is that the client-side data is not automatically synchronized, so you have to do it yourself. Either: a) send a packet to the client with the data and set it manually; this is best done from somewhere like the EntityJoinWorldEvent to avoid NPE of the client-side properties b) use DataWatcher to store your data instead of class fields; advantage is that everything else is automatic; disadvantage is you are using an extremely limited resource (data watcher slots) There are tutorials on the Forge wiki about both packets and data watcher, both of which are referenced on this list: http://mazetar.com/mctuts/displayTutorials.php Alternatively, you can check out my tutorial on IExtendedEntityProperties here: http://www.minecraftforum.net/topic/1952901-eventhandler-and-iextendedentityproperties/#entry24051513
  6. That would be pretty dangerous Instead, I've just coded a custom explosion class that can handle much wider variety of specifications, yet still retains the functionality of and can be substituted for the vanilla class. This way, I can just set a variable to ignore liquids and still maintain a not-too destructive explosion, along with all sorts of other fun things. Thanks again for the help. I still don't know why I didn't check the actual explosion resistance of water...
  7. Ah, Draco to the rescue Don't know why I didn't see that myself <facepalm>. Derp.
  8. I'm not trying to destroy the water, I'm trying to destroy blocks with explosions that happen IN the water. Of course I could just write my own methods instead of using the vanilla Explosion class, but I'm puzzled that I can't seem to find where Minecraft decides that the explosion is in water and then prevents it from destroying blocks. Thanks for the reply, though.
  9. I've been poring through all the code related to Explosions that I can find, which apparently isn't much, because I can't find where it decides that blocks cannot be destroyed while underwater. Here's everything I could find out about explosions: Nowhere in there do I see any reference to water or anything that would prevent blocks from being destroyed when the explosion occurs in water. What am I missing here?
  10. If your container Item is kept in sync when using it from the equipped slot, then it should be as simple as using that exact same method for when it's accessed from the custom slot. For example, if you are using the Item's onUpdate method to save the inventory contents, it is not called automatically for custom slots, only vanilla inventory slots. Use Forge's LivingUpdateEvent to check if the entity/player has your custom inventory slot and, if so, get the stack from there and call the onUpdate method for the item. If you don't have your container Item inventory saved and synchronized even just when right-clicked, then you need to go back and get that part working first.
  11. Yep, that seems about right. Thanks for the help!
  12. Thanks for confirming my suspicions. Looking more closely into the code, I see the portal is created in ServerConfigurationManager.transferEntityToWorld, which seems to get called no matter what method was originally used to teleport. I haven't had any luck using setPositionAndUpdate unless I send the player back to the original portal; how far away did you set their position? This is what I tried which works for not returning to the nether, but it still spawns a portal:
  13. Solution (thanks to Draco): Set the player's position with setPositionAndUpdate, adjusting x and z by at least one so the player doesn't spawn directly in the created portal. If you don't want a portal to generate at all, you must set the player's position at least 32+ blocks away from their initial position as set by travelToDimension. Be sure to use the player's world object rather than one passed in from the method parameters after using travelToDimension, as the worldObj has changed. Problem: I'm trying to make an item that when used teleports the player back to the overworld from the nether, but everytime I use it, the change dimension screen shows but I end up right back in the nether: public void onPlayerStoppedUsing(ItemStack stack, World world, EntityPlayer player, int ticksRemaining) { switch(player.dimension) { case -1: player.travelToDimension(0); break; } default: ; } If I travel far enough from the first nether portal, this code will create a new nether portal in whatever chunk I happen to spawn in (still in the Nether). I do see the overworld for a second, so I believe I am teleporting, but it is immediately sending me back... I'm thinking it spawns the player directly in a portal... I tried using 'player.setInPortal()' before changing dimension to try to prevent the player from teleporting immediately, but that didn't work. Any ideas?
  14. Thanks for the idea, but I just ended up using a packet: // this is in the Item's onUpdate method: if (isHeld) { if (entity instanceof EntityPlayer) { if (world.isRemote && Minecraft.getMinecraft().currentScreen == null) { PacketDispatcher.sendPacketToServer(new BombTickPacket().makePacket()); } } else { tickBomb(stack, world, entity); } } else { stack.getTagCompound().setInteger("time", 0); } As you can see, when held by a player, it does nothing if on the server side; instead, it checks for an open screen on the client side and if there isn't one, sends a packet telling the server to 'tick' the bomb, which is a method that has the same stuff that used to be in the onUpdate method. It's a simple solution to a simple problem; I was just wondering if there wasn't another way to do it is all.
  15. That's what my plan is, I was just hoping that I may have overlooked something that would obviate the need for an extra packet. It just seems like something that should be easily detectable with an instance of the player, even the server side version, but I have combed through the available methods and fields multiple times and come up with nada. Thanks, though.
  16. I've got an item that writes to NBT while held on each Item update tick, but I only want it to update if no gui screens are open. player.openContainer is never null; in normal gameplay ContainerPlayer is constantly open, which also happens to be open when the player's normal inventory is open. FMLClientHandler.instance().getClient().inGameHasFocus would seem like a good choice, and it works when only running the regular client, but this crashes if run on the server (obviously) and I can't just run the Item update on the client side. So it would seem this option is not SMP compatible. Am I just failing to see how to use these to solve my problem, or are there any other options that are SMP compatible?
  17. Be sure you only register your SoundHandler class on the client side, or you will crash when you try to run your mod on a server environment (because the event's SoundManager is a client side only class). Easiest way to ensure that is to put the registration in your ClientProxy. P.S. volume AND pitch can both have pretty much any value; vanilla often uses random values for the pitch especially so that the sound doesn't always sound the same: // from ItemBow; note the final parameter for pitch is different every time the bow fires, // but volume, in this particular case, is set at 1.0F par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F);
  18. Here's a tutorial on IExtendedEntityProperities: http://www.minecraftforum.net/topic/1952901-eventhandler-and-iextendedentityproperties/#entry24051513 Like diesieben07 said, that's the easiest way to add extra information to existing entities (and yes, it saves to NBT).
  19. While adding items to LivingDropsEvent's drops list, I noticed that sometimes when I killed the mob my item would spawn, but then quickly disappear. Using spawnEntityInWorld directly from the event has the same effect. EntityLivingBase mob = event.entityLiving; ItemStack orb = getOrbDrop(mob); // this just returns an itemstack to drop if (orb != null) { // tried this one first: event.drops.add(new EntityItem(mob.worldObj, mob.posX, mob.posY, mob.posZ, orb)); // then I tried the following instead: mob.worldObj.spawnEntityInWorld(new EntityItem(mob.worldObj, mob.posX, mob.posY, mob.posZ, orb)); // both with the same result } I thought it might be something to do with spawning the item directly on the mob's position, getting cleared when the mob is marked for removal or something like that, but in the entityDropItem method that's exactly how they create the EntityItems, so... what's going on here? EDIT: Figured it out. If I use 'copy()' on the ItemStack when I construct the EntityItem, everything works as intended. I suppose that's what I get for using a static method to return my ItemStack // working code mob.worldObj.spawnEntityInWorld(new EntityItem(mob.worldObj, mob.posX, mob.posY, mob.posZ, orb.copy()));
  20. You, good sir, deserve a beer. That was the most clear and concise argument against reflection I have ever seen.
  21. That's just so damn sneaky So which would be considered dirtier, reflection or a foreign accessor class? I've managed to stay clear of both until now :-/
  22. Ooooh, I never thought of adding a class to a vanilla package! I was trying to figure out how to make a wrapper like that, and all I could think of was making a class extend EntityLivingBase, which of course wouldn't help at all because none of the vanilla mobs would even use that class... Is it not considered taboo to add custom classes to vanilla packages? It's not editing any vanilla code, though, so I don't see why not Anyway, that's a great idea! I've got my flag built in to the way the skill works, so the second event shouldn't be a problem. Thanks for the tip though.
  23. Thanks for the reply. Yes, AttackEntityEvent could work, but if I'm not mistaken then once attackTargetEntityWithCurrentItem is called it's back to the same problem - getting it to use the new DamageSource - because attacking with the current item always causes 'player' damage. As for reflection, yes, that thought crossed my mind, but it seems so dirty I'll wait a while and see if any new ideas are forthcoming, but reflection may indeed be the best bet in this scenario.
  24. I'm making a skill that allows the player to charge up an attack and then strike, causing all of the normal sword damage but ignoring armor. I've considered many different ways of doing this, but all of them seem to require me to simulate (read 'copy / paste') significant portions of the vanilla attack code or are otherwise not good options. Let me outline what I've considered: 1. In LivingHurtEvent, make a call to 'damageEntity' with a new, armor-ignoring DamageSource and either cancel the event or set the ammount to zero; Benefits: no adverse effect on any of the other attack calculations Problem is that 'damageEntity' is protected, so I'd have to copy / paste that code into my own method 2. somehow reassign the DamageSource in LivingAttackEvent; this would be ideal, but I don't think it's possible because the event's DamageSource field is 'final' (which makes perfect sense, but still ) 3. cancel LivingAttackEvent and make a new call to attackEntityFrom with the new DamageSource; this one just no, the problems far outweigh any benefit that might be gained, since among other things this would cause 'attackEntityFrom' to return false in the player's 'attackTargetEntityWithCurrentItem' method mid-strike, but I still need that to return true for the rest of the calculation Number '1' is currently my top option, but I thought I'd ask if anyone knows of a better way. Thanks for any ideas.
  25. If you don't have an ItemStack or TileEntity for the IInventory, then you need to save it to the player. Use IExtendedEntityProperties. You can check http://www.minecraftforum.net/topic/1949352-creating-an-item-that-stores-an-inventory/ to see an example.
×
×
  • Create New...

Important Information

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