Jump to content

[1.10.2, 1.11.2] Blocking only Melee Attacks with a custom Weapon?


ObliviousSpartan

Recommended Posts

Hi there,

This is my first time posting on these forums, so apologies in advance if I miss anything.

I am attempting to make a dagger weapon in a new mod I am making that will have the ability to block melee attacks, but not projectiles. In my attempts to do this, I've ran into a few issues. If I make use of the EnumAction.BLOCK in the method below, it will do the blocking animation I have specified, but it will block projectiles as well rather than using the custom behaviour I have put in a LivingAttackEvent method, which ignores projectiles.

@Override
public EnumAction getItemUseAction(ItemStack stack)
{
  return EnumAction.BLOCK;
}

As an alternative, I made a custom EnumAction known as MELEE_BLOCK using the method EnumHelper.addAction(), and by doing that, while it makes the blocking behaviour work properly, it doesn't make the weapon appear to visually block the attack, both in first and third person. In first person, the weapon disappears entirely, while in third person, the player just wields it as normal.

 

Here's the Item class, and the LivingAttackEvent method that is called for reference. The following code is based on my alternative custom EnumAction solution I have taken.

ItemParryingDagger:

Spoiler

public class ItemParryingDagger extends ItemWeaponBase implements IBlockingWeapon
{
	public static EnumAction MELEE_BLOCK = EnumHelper.addAction(Reference.ModID.toLowerCase() + ":melee_block");
	
	public ItemParryingDagger(String unlocName, ToolMaterial material, float weaponDamage) 
	{
		super(unlocName, material, weaponDamage, 2.5f, WeaponProperty.BLOCKING);
        this.addPropertyOverride(new ResourceLocation("blocking"), new IItemPropertyGetter()
        {
            @SideOnly(Side.CLIENT)
            public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn)
            {
                return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1.0F : 0.0F;
            }
        });
	}

    /**
     * returns the action that specifies what animation to play when the items is being used
     */
	@Override
    public EnumAction getItemUseAction(ItemStack stack)
    {
        return MELEE_BLOCK;
    }

    /**
     * How long it takes to use or consume an item
     */
	@Override
    public int getMaxItemUseDuration(ItemStack stack)
    {
        return 72000;
    }

	@Override
    public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
    {
        playerIn.setActiveHand(hand);
        return new ActionResult(EnumActionResult.SUCCESS, itemStackIn);
    }

	@Override
	public boolean canBlockProjectiles() 
	{
		return false;
	}

	@Override
	public boolean canBlockMelee() 
	{
		return true;
	}
}

 

Snippet of my mod's EventHandler class:

Spoiler

// Attack Event - Handles damage.
@SubscribeEvent
public void attackEvent(LivingAttackEvent ev)
{
	float damage = ev.getAmount();
		
	if(ev.getEntityLiving() instanceof EntityPlayer)
	{
		EntityPlayer player = (EntityPlayer)ev.getEntityLiving();
			
		if(player.getActiveItemStack() != Reference.ITEMSTACK_NULL)
		{
			ItemStack activeStack = player.getActiveItemStack();
				
			if(activeStack.getItem() instanceof IBlockingWeapon)
			{
				IBlockingWeapon weapon = (IBlockingWeapon)activeStack.getItem();
				DamageSource source = ev.getSource();
					
				if(weapon.canBlockMelee() && !source.isExplosion() && !source.isFireDamage() && !source.isMagicDamage() && !source.isProjectile() && !source.isUnblockable())
				{
					// Do knockback due to damage.
                    if (source.getSourceOfDamage() instanceof EntityLivingBase)
                    {
                        ((EntityLivingBase)source.getSourceOfDamage()).knockBack(player, 0.3F, player.posX - source.getSourceOfDamage().posX, player.posZ - source.getSourceOfDamage().posZ);
                    }
                    activeStack.damageItem(2, player);
                    player.worldObj.playSound((EntityPlayer)null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_KNOCKBACK, SoundCategory.PLAYERS, 0.8f, 0.8f);
                    ev.setCanceled(true);
				}
				else if(weapon.canBlockProjectiles() && ev.getSource().isProjectile())
				{
					player.playSound(SoundEvents.ENTITY_PLAYER_ATTACK_KNOCKBACK, 0.8f, 0.8f);
					ev.setCanceled(true);
				}
			}
		}
	}
}

 

Is there any way to use the EnumAction.BLOCK action to make the weapon only block specific types of damage sources? Or if there is not, how would I go about adding the player animations for blocking for both first- and third-person to account for my custom EnumAction?

Any help would be greatly appreciated.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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