Checking for a bow at full draw

Discussion in 'Plugin Development' started by bobblacksmith, Feb 14, 2014.

Thread Status:
Not open for further replies.
  1. Offline


    Ok, I realize I could just do event.getForce to check this if event was EntityShootBowEvent, but I need to do it with EntityDamageByEntityEvent.

    1. @EventHandler(priority = EventPriority.HIGH)
    2. @SuppressWarnings("deprecation")
    3. public void onShot(EntityDamageByEntityEvent e){
    4. Entity attacker;
    5. if(e.getDamager() instanceof Arrow) {
    6. attacker = ((Arrow)e.getDamager()).getShooter();
    7. if(attacker instanceof Player){
    8. Entity target;
    9. target = e.getEntity();
    10. ((Damageable) target).damage(9000);

    This is what I have right now, all I want to do is make sure that the player that shot the opposing entity had his/her bow at full draw.

    Also wondering how to set a permission for this, when I try the normal way it gives me an error.

    Thanks in advance!
  2. Offline


    You could probably do some test with how much damage a full draw does and check
    if (event.getDamage() >= 10.0)
  3. Offline


    I don't think that will work, the Power enchantment alone could break that check. Also I thought even a fully drawn bow does a variable amount of damage (not always >= 5 hearts - 10 damage)
  4. Offline


    If it does vary, find out much it varies and make it:
    if (event.getDamage() < 12 && event.getDamage() > 8) or something

    Edit: As for power enchantment, I'm quite sure there is a method to check for enchantments, so you can have the above if statement nested in one that checks for the power enchantment. Then if it has the enchantment at a certain level, the numbers can be adjusted accordingly
  5. Offline


    bobblacksmith You need to check for an EntityShootBowEvent. Check if the force is equal to the max force of a bow pull(I don't know the exact number), then add MetaData to the arrow. Instead of checking for the arrow's shooter being a player check for the arrow's MetaData.
    Just in case you don't know, this is MetaData:
    1. arrow.setMetaData("OneHitKO", new FixedMetaData(plugin, true));
    2. if(arrow.hasMetaData("OneHitKO"){
    4. }
  6. Offline


    I already said that I can't use EntityShootBowEvent because if I do that I can't get the entity the arrow damaged as far as I know, but if there is a way to do it please present it.
  7. Offline


    bobblacksmith you will need to use both EntityShootBowEvent and EntityDamageByEntityEvent here.

    As d3v1n302418 stated, you can attach metadata to your arrow when fired, in the EntityShootBowEvent.

    Then, in your EntityDamageByEntityEvent, you can check for arrows that have that metadata tag on them, and if found, you know that the arrow was fired from a fully-drawn bow.

    Note that metadata isn't the only way to handle this, but it is probably the easiest. The drawback is that metadata tag names (e.g. "OneHitKO") are global across all plugins, so care is needed to choose something hopefully unique to your plugin.

    The alternative would be to maintain a map of (Entity UUID -> data-tag) within your plugin and check that, but using metadata is more straightforward, since the metadata dies automatically along with the entity.
  8. Offline


    I will try this, but I was told I can only use one event at a time on a previous thread. How do I use multiple?
  9. Offline


    Just create a handler for each event! That's perfectly fine; you can create as many event handlers as you like in your plugin. Not quite sure what you mean by "one event at a time" - event handler don't all get called at once; they're called by CraftBukkit when it needs to let plugins know that something is happening.

    In this case, the EntityShootBowEvent handler will be called first, when the arrow is fired - that's when your plugin can attach some metadata to the arrow to indicate a full draw. The EntityDamageByEntityEvent handler will be called shortly after, if/when the arrow hits an entity - that's when your plugin can check whether or not the arrow has the metadata attached to it.
  10. Offline


  11. Offline


    Will this code do it?

    1. @EventHandler(priority = EventPriority.HIGH)
    2. public void getArrow(EntityShootBowEvent e) {
    3. if(e.getForce() == 1.0) {
    4. if(e.getProjectile() instanceof Arrow) {
    5. Entity arrow = e.getProjectile();
    6. e.getProjectile().setMetadata("armeta", new FixedMetadataValue(this, arrow));
    7. }
    8. }
    9. }
    10. @EventHandler(priority = EventPriority.HIGH)
    11. @SuppressWarnings("deprecation")
    12. public void onShot(EntityDamageByEntityEvent e) {
    13. Entity attacker = null;
    14. if(e.getDamager() instanceof Arrow) {
    15. if(e.getDamager().getMetadata("armeta") != null) {
    16. attacker = ((Arrow)e.getDamager()).getShooter();
    17. if(attacker instanceof Player){
    18. Entity target;
    19. target = e.getEntity();
    20. ((Damageable) target).damage(9000);
    21. }
    22. }
    23. }
    24. }
    25. }

    I am not able to test it right now myself.
  12. Offline


    Better to test it yourself later than post it here :p
Thread Status:
Not open for further replies.

Share This Page