Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Everything posted by coolAlias

  1. Just be aware that the above solution (which is very slick) requires anyone using your mod to have Java 8, whereas Minecraft itself I believe still targets the severely outdated Java 6. Might want to note that in your mod description, but even then, there is bound to be someone that doesn't read it and hasn't updated Java and complains to you about it
  2. It's called once on the client and once on the server. Only damage the item, change NBT, etc. on the server (when the world is NOT remote), and play sound for the player to hear on the client. If you want others to hear the sound, you can also initiate a sound on the server view World#playSoundEffect or something like that and it will propagate to nearby clients.
  3. Two things: 1. Your message class must have an empty constructor 2. In your message handler, 'EWDInventory inventory = message.getInventory();' is completely pointless, as you don't actually send any data. You have to implement IMessage#toBytes and IMessage#fromBytes to send and receive data. However, in your particular case, you may not need to send any data at all other than the base packet as you can snag the inventory from player.openContainer.
  4. You should see something like this in the ItemBow class (at least in 1.8.0 and earlier): if (!player.capabilities.isCreativeMode) { player.inventory.consumeInventoryItem(Items.arrow); } That's one way you can consume an item. As for the entity, you should make a custom entity rather than trying to use the vanilla ender pearl entity - that way you can make it do whatever you want.
  5. Make sure you spawn the EntityItem using a COPY of the ItemStack (i.e. dropstack.copy()) - IIRC, #getSmeltingResult returns only a single ItemStack instance, not a new one each time, so after you have picked up the first stack dropped, every drop after that will have a stack size of zero. Usually in that case, however, the item will still spawn but picking it up doesn't give you anything. It's possible they have changed this behavior since 1.7.10/1.8.
  6. You need to give your mob some AI. Using vanilla classes, you can add things like: // your mob will wander aimlessly tasks.addTask(5, new EntityAIWander(this, 1.0D)); // your mob will move towards and attack players targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); There are lots of other examples in vanilla code - check out the various mobs such as Zombies, Skeletons, etc. Spiders are a good example of a custom movement / navigation type, and you can override #getBlockPathWeight in any mob using movement AI to modify what it considers a good path.
  7. The ItemBow class' #onPlayerStoppedUsing method implementation shows you how to do all of those things - it's worth a read through and is pretty much copy-paste ready once you figure out what's going on.
  8. There isn't really a great way to do this, but one way is to subscribe to EntityJoinWorldEvent, check for EntityArrow, and replace it with your own arrow class that has overridden #onUpdate to rewrite the targeting logic to ignore friendly units BEFORE trying to attack them and thus before killing the arrow entity. Downside is it won't work very well with other mods that add arrows, as you either don't bother replacing modded arrows or the modded arrows get replaced and lose whatever specialness they were supposed to have. It'll be interesting to see if anyone has a more robust solution.
  9. Your logic appears to be problematic: if(!(event.entityLiving instanceof EntityTobieKing)){ return; // returning if entity is not an EntityTobieKING } if (event.entityLiving instanceof EntityTobieQueen){ // how will this ever be true??? Unless EntityTobieQueen extends EntityTobieKing, that second statement will never be true.
  10. It would be preferable to find a way to do it without modifying any core classes, if possible. Client input is mostly handled from EntityPlayerControllerMP, i.e. that's where the action packets get sent from, and that's where I'd start looking for possible hooks. If there isn't anything in there that strikes you as usable, you could check out the Minecraft class which is where the actual client input (keyboard etc.) is monitored. I haven't coded in a long while, but it may be possible via KeyInputEvent to immediately set the key binding's pressed state to false to prevent the attack action. if (Keyboard.getEventKey() == mc.gameSettings.keyBindAttack.getKeyCode()) { KeyBinding.setKeyBindState(Keyboard.getEventKey(), false); } Worth a shot, but you'll probably still get a swing.
  11. What that means is you did not call #setTagCompound(newTag) when you created a new tag, so if the ItemStack didn't have a tag to begin with, it doesn't after your method, either. Typical implementation to ensure non-null tag: if (!stack.hasTagCompound()) { stack.setTagCompound(new NBTTagCompound()); } NBTTagCompound tag = stack.getTagCompound();
  12. When overriding that method, make sure to still return true for some cases, e.g. @Override public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { return !ItemStack.areItemsEqual(oldStack, newStack); // maybe also add || slotChanged } A better solution, however, is to avoid updating NBT every tick and instead store the world time at which the next event should happen, then simply compare the current time against the NBT each tick: // whenever time should be set: long next = world.getTotalWorldTime() + 12000; stack.getTagCompound().setLong('nextWhatever', next); // checking each tick: if (world.getTotalWorldTime() > stack.getTagCompound().getLong('nextWhatever')) { // do whatever you need to do, then set the next time again Not only will you not have to bother with shouldCauseReequipAnimation, but it is also more efficient as you only write to NBT once per cycle, rather than every single tick.
  13. MouseEvent's event.button field is equal to the key code +100, so subtract 100 to get the actual key code, e.g.: if (event.button - 100 == Minecraft.getMinecraft().gameSettings.keyBindAttack.getKeyCode()) { // attack key pressed You need to handle both MouseEvent and KeyInputEvent as the latter does not fire for mouse keys (unless that has been changed since 1.8.0). However, as you've discovered, KeyInputEvent is not cancellable, so once the player presses the attack key, they will already be attacking. I'm not sure if there is a way to completely intercept the attack without a core mod (or at least a lot of hackery), but if you're not opposed to the idea, you can allow the first attack to swing, but require the player to keep holding down the attack key in order to charge up until the attack triggers on its own. That's what I did in my various Sword Skill mods, and it works pretty well.
  14. Exactly as Draco mentioned - the book Item is simply a convenient way to open a GUI, it doesn't actually contain any data itself. Quest data would presumably be tied to the player entity, so that is what you should attach any Quest Capability system to (IExtendedEntityProperties pre-1.8.9). Note also that GUIs are completely client side, whereas your quest data is going to be stored and handled server side, so you need to send any data you wish to display to the client via packet when the player joins the world and whenever that data changes.
  15. It's practically exactly the same as previous versions: 1. Create your Entity class 2. Register it via EntityRegistry#registerModEntity 3. Register a Render class for it via your ClientProxy Optional: add spawns, spawn egg (via #registerModEntity), or some other method of adding your entity to the world, depending on what it actually is.
  16. PlayerEvent.Clone, but you shouldn't send packets from there; instead, use EntityJoinWorldEvent (or possibly RespawnEvent, though I've never tried that one) if you need to sync data after player death and respawn.
  17. Aside from several serious Java errors (e.g. a semi-colon after a condition: 'if (condition);') and formatting issues (e.g. funky / unclear nesting of if statements), it is possible that you aren't actually calling whatever CommonProxy method is supposed to register it. Show your CommonProxy and your main class.
  18. Where are you sending the packet from? Show that code, too. Btw, you should not be using Minecraft.getMinecraft() directly - use your proxies: // CommonProxy /** * Returns a side-appropriate EntityPlayer for use during message handling */ public EntityPlayer getPlayerEntity(MessageContext ctx) { return ctx.getServerHandler().playerEntity; } /** * Returns the current thread based on side during message handling, * used for ensuring that the message is being handled by the main thread */ public IThreadListener getThreadFromContext(MessageContext ctx) { return ctx.getServerHandler().playerEntity.getServerForPlayer(); } // ClientProxy: @Override public EntityPlayer getPlayerEntity(MessageContext ctx) { return (ctx.side.isClient() ? mc.thePlayer : super.getPlayerEntity(ctx)); } @Override public IThreadListener getThreadFromContext(MessageContext ctx) { return (ctx.side.isClient() ? mc : super.getThreadFromContext(ctx)); } // message code: YourMod.proxy.getThreadFromContext(ctx).addScheduledTask(... EntityPlayer player = YourMod.proxy.getPlayerEntity(ctx);
  19. You didn't use the code as I wrote it, and you are using local variables instead of class fields. - wasFlyingAllowed needs to be a class field so that it is remembered from tick to tick rather than being recalculated every tick. - You don't need allowFlying at all - remove it. - You moved your code to disable flying inside of your check for if (allowFlying), meaning that as soon as you are not allowed to fly, it is impossible for your code to disable it... - Please take time to study basic Java and logic: if (wasFlyingAllowed) { } else if (wasFlyingAllowed) { // this is the same condition you just checked - how can it possibly ever run? // dead code }
  20. Because in his example, he wants to limit 'count' to a value between 0 and 2. int count = 0; #someTickingMethod: if (count != 1) { // fire bullet } count = (count + 1) % 3; Tick Count Modulo 0 0 (0 + 1) % 3 = 1 1 1 (1 + 1) % 3 = 2 2 2 (2 + 1) % 3 = 0 3 0 (0 + 1) % 3 = 1 4 1 (1 + 1) % 3 = 2 5 2 (2 + 1) % 3 = 0 Make sense now?
  21. @gummby8 Technically that could work, but you don't want to let the client dictate anything like that. Using your setup, a player could easily write a hack that sends client->server packets granting themselves as many different materials as they wish.
  22. It doesn't really matter whether it's just an Entity or an EntityItem (which is just a specific type of Entity) - you can do whatever you want within your own class. But anyway, yes, you can do it easily. Make your Entity class ownable and set the owner to the player you want to pick it up. Only allow this player to 'pick up' the entity object. Send the owner information to the client side via IEntityAdditionalSpawnData, and in your custom render class, only render if the current client player is the same as the entity's owner. That's all you need.
  23. All you need to do is add 'public boolean wasFlyingAllowed = false' to your event handler, set it to true when your armor is all on, and then only disable flying if it's true and not all of your armor is allowed: // Note: you should check for NULL on all of these or you WILL crash if (boots.getItem() == SlurpiesDonglesItems.topaz_boots && chestplate.getItem() == SlurpiesDonglesItems.topaz_chestplate && leggings.getItem() == SlurpiesDonglesItems.topaz_leggings && helmet.getItem() == SlurpiesDonglesItems.topaz_helmet) { event.player.capabilities.allowFlying = true; event.player.fallDistance = 0.0F; wasFlyingAllowed = true; } elseif (wasFlyingAllowed) { wasFlyingAllowed = false; // now you won't be constantly setting allowFlying to false if (!event.player.capabilities.isCreativeMode) { event.player.capabilities.isFlying = false; event.player.capabilities.allowFlying = false; } }
  24. You are not wrong; where you err is in assuming that armor is always going to remain in InventoryPlayer. I edited in some examples - armor breaks, is tossed or otherwise moved out of inventory directly from the equipment slot, or a mod simply sets it the slot to null or a different item. In all of those cases, the armor will not get a chance to have an update tick after being unequipped, and you'll be unable to toggle off whatever ability you had toggled on. If, however, you were using AttributeModifiers rather than relying on update ticks, then it would be fine. Too bad there isn't an 'allow flying' attribute modifier... hmm... 'flySpeed' as a new SharedMonsterAttribute, anyone?
  25. You DO need to use the PlayerTickEvent because Armor doesn't tick when it's not worn*, so the only way to remove the flying effect when no longer wearing your armor is via a tick event. The trick to mod compatibility is to set allowFlying to true every tick that it should be true, but only set it to false ONCE when the condition is no longer met. To do that, you need a separate boolean 'wasFlyingAllowed'. This way, you only toggle flying off once, and any other mod that says flying is still allowed sets it during their tick event. Note that it's still not perfect - if your tick event is last to evaluate, there will be one tick in which the player cannot fly and will begin to fall (if you also set #isFlying to false), even though the very next tick they will be allowed to fly again. It's a wonder there isn't yet a universal way to ensure inter-mod flying compatibility (at least that I've heard of), given how many mods add it. * Yes, it still has #onUpdate called while in the player's inventory, but that won't happen if the armor is destroyed, moved to another inventory directly, etc. #onUpdate is not a reliable method of toggling off an ability.
×
×
  • Create New...

Important Information

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