Thornack Posted September 29, 2015 Posted September 29, 2015 Hi everyone, This question may be simple or may be difficult but how would you get a mob to use an item just like the player does? My mob entities have their own inventory and their inventory is full of attack items that use onItemRightClick and onItemUse to attack other entities. My question is how would you get the mob to use these items (call onItemRightClick and call onItemUse etc etc) just like the player does. Any ideas? Quote
coolAlias Posted September 30, 2015 Posted September 30, 2015 You'll have to implement all of that yourself. Typically, AI is used to simulate the ability of computer-controlled entities to behave as though they were intelligent players, so your best bet is to create some AI tasks that handle the logic for you and then add them to your entities' task lists. This can be very powerful when combined with some custom interfaces, e.g. IEntityItemUser, that allow your AI and Entity classes to interact more effortlessly. Or you can hard-code it all into your entity's onUpdate methods. EDIT: On second thought, I don't think you're going to be able to do it the way you want - all of the item use methods take an EntityPlayer parameter that you obviously won't be able to furnish from your non-player entity, and even if you come up with a way to hack one in there (or pass null), you will either have to restrict the usable items to ones of your own making that don't rely on that parameter, or expect things to go very very wrong. However, if you are okay with passing null, you can make an interface for items that can be used by mobs, such as IMobUsable, and give them methods to call when used by mobs instead of players. Not ideal, but that's the best I can think of. Quote http://i.imgur.com/NdrFdld.png[/img]
Thornack Posted September 30, 2015 Author Posted September 30, 2015 Hmm ok, I will look into youre first suggestion. Id like to accomplish this somehow as it would make things very very awesome for my mod Quote
Thornack Posted October 1, 2015 Author Posted October 1, 2015 Ok I am having some trouble here. I need to implement my own version of onUsingTick so that it can be called only when my entity is using the item. (But when the player uses theitem I need it to continue to use the vanilla onUsing tick) but I am unsure how to do this. in my onLivingUpdate method inside my entity class I am trying to implement all of the player logic that causes a player to use an item so that my custom entity can use the item instead. Basically the following @Override public void onLivingUpdate(){ super.onLivingUpdate(); if (this.attackInUse != null) { ItemStack itemstack = this.getCurrentAttack(); if (itemstack == this.attackInUse) { if (attackInUseCount <= 0) { this.onAttackUseFinish(); } else { attackInUse.getItem().onUsingTick(attackInUse, this, attackInUseCount); if (--this.attackInUseCount == 0 && !this.worldObj.isRemote) { this.onAttackUseFinish(); } } } else { this.clearAttackInUse(); } } } I think I did everything correctly so far with a few minor modifications it should work ok but im stuck on the onUsingTick method. I need to be able to have the new onUsingTick available so that I can do attackInUse.getItem().onUsingTick(attackInUse,(EntityCustom) this, attackInUseCount); where currently vanilla doesnt allow this since the second parameter needs to be a EntityPlayer. public ItemStack[] attacks = new ItemStack[4]; public int currentAttack; private ItemStack attackInUse; private int attackInUseCount; public ItemStack getCurrentAttack() { return this.currentAttack < 4 && this.currentAttack >= 0 ? this.attacks[this.currentAttack] : null; } public void setAttackItemInUse(ItemStack itemStack, int maxItemUseDuration) { if (itemStack != this.attackInUse) { if (maxItemUseDuration <= 0) return; this.attackInUse = itemStack; this.attackInUseCount = maxItemUseDuration; if (!this.worldObj.isRemote) { this.setEating(true); } } } public void clearAttackInUse() { this.attackInUse = null; this.attackInUseCount = 0; if (!this.worldObj.isRemote) { this.setEating(false); } } protected void onAttackUseFinish() { if (this.attackInUse != null) { int i = this.attackInUse.stackSize; /**may cause problems*/ ItemStack itemstack = this.attackInUse.onFoodEaten(this.worldObj, null); if (itemstack != this.attackInUse || itemstack != null && itemstack.stackSize != i) { this.attacks[this.currentAttack] = itemstack; if (itemstack != null && itemstack.stackSize == 0) { this.attacks[this.currentAttack] = null; } } this.clearAttackInUse(); } } @Override public void onLivingUpdate(){ super.onLivingUpdate(); if (this.attackInUse != null) { ItemStack itemstack = this.getCurrentAttack(); if (itemstack == this.attackInUse) { if (attackInUseCount <= 0) { this.onAttackUseFinish(); } else { attackInUse.getItem().onUsingTick(attackInUse, this, attackInUseCount); if (--this.attackInUseCount == 0 && !this.worldObj.isRemote) { this.onAttackUseFinish(); } } } else { this.clearAttackInUse(); } } } I have a CustomItem class which extends the vanilla Item class. My CustomItem class is then extended by my attack item class. The attack items are the items that I want my entity to be able to use. But in order for this to work I need to be able to have the entity call the onItemRightClick and onItemUse methods. Inside this class is where I put my custom onUsingTick that I need to be able to call to set my item in use, but I am unsure how to do that. public class CustomItem extends Item { public CustomItem() { super(); setMaxStackSize(64); } /** * Called each tick while using an item. * @param stack The Item being used * @param player The Entity using the item * @param count The amount of time in tick the item has been used for continuously */ public void onUsingTick(ItemStack stack, EntityCustom customEntity, int count) { } @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister iconRegister) { this.itemIcon = iconRegister.registerIcon(CustomMod.modid + ":" + this.getUnlocalizedName().substring(5)); } } Im not sure how to implement the onUsingTick method that is in my generic CustomItem class rather than the one that is inside the vanilla Item class. I cant use the vanilla one since it requires the player as a parameter and obviously I cannot make my custom mob a player entity. Basically to make my item useable by both the player and the entity I am trying to implement a second onItemRightClick method that replaces the player parameter with the custom entity parameter so that it can be called by my entity from its AI public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityCustom customEntity) { int fatigueMultiplier = 1; if(ball == true && (getCooldown(itemStack) == 0)){ fatigueMultiplier = 2; EntityRangedAttackBase distanceAttack = new EntityRangedAttack(world, customEntity).setType(attackType).setArea(damageRadius); distanceAttack.setBaseDamageForProjectileAttack(baseDmg); setCooldown(itemStack, 30); if (!world.isRemote) { WorldHelper.playSoundAtEntity(customEntity,BattleSoundsList.WHOOSH, 0.4F, 0.5F); world.spawnEntityInWorld(distanceAttack); } } else if(ball ==false){ customEntity.setAttackItemInUse(itemStack,getMaxItemUseDuration(itemStack)); } return itemStack; } Any ideas how to implement the onUsingTick method from inside my customItem class rather than the regular vanilla onUsingTick method?? Or any ideas on how to implement what I am trying to achieve in a simpler way?? Quote
Thornack Posted October 1, 2015 Author Posted October 1, 2015 Nvm Im stupid if(attackInUse.getItem() instanceof CustomItem){ CustomItem attack = (CustomItem ) attackInUse.getItem(); attack.onUsingTick(attackInUse, this, attackInUseCount); } Quote
coolAlias Posted October 2, 2015 Posted October 2, 2015 I strongly suggest you use an interface for your additional item methods instead of a 'base' class - it will be far more flexible, both for you and for anyone that may write addons for your mod. Just as a simple example, you have your CustomItem class that extends Item and adds one or more methods for interacting with the mob item in use. All fine and dandy. BUT, now imagine you have a custom sword that, logically, extends ItemSword, but you want your mobs to be able to use it, too... now what? You are stuck. Java does not support multiple inheritance, so you cannot extend both ItemSword and CustomItem at the same time, and you have to either add an additional check in your item use logic to account for the sword exception, OR you have to duplicate all of the ItemSword code in a new class that extends CustomItem, and even then that custom sword that isn't a sword will not play well with some other mods that check for instances of ItemSword in their logic. The solution is interfaces: public interface IMobUsable { void onUsingTick(ItemStack stack, EntityLivingBase (or EntityCustom) entity, int useCount); } Now ANY item can implement this interface and be usable by your mobs, even items from other mods if the author wants to make their item(s) compatible with your mobs. Quote http://i.imgur.com/NdrFdld.png[/img]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.