[Bow] Help With Archery

Discussion in 'Plugin Development' started by sethrem, Oct 14, 2014.

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

    sethrem

    Hello my felloe Bukkitians,
    I was wondering if there was a way to make it so when someone shoots an arrow and hits another entity, a play in specific it would bounce twice at most. Ok so your probably confused right? But don't worry he comes the hardcore breakdown of this. If the Damager(The Arrow Shooter) shoots a bow and it(the arrow) hits another entity(Another Player) the arrow has the potential to bounce off and hit up to two more entities(two other players), but it would only bounce off to players within a certain radius around the hit entity.
    Thank you in advanced. :D
     
  2. Offline

    Monkey_Swag

    Hmmmm not too sure if it would be possible to fire another arrow to a nearby player. However, you could damage players around the location where the arrow landed.
     
    BeefySticks likes this.
  3. Offline

    BeefySticks

    Wouldn't you be able to change the velocity of which the arrow is going?
    I'm not so good with this but I think this MIGHT be possible to a extent.

    Also, I've seen you on the forums a lot! Thanks for helping others out! +1 :p
     
  4. Offline

    TheCwispyOne

    Maybe you could get an entity that is less than a certain distance from the player that got hit. You then make the player that got hit fire an arrow and set the vector so that it goes toward the entity close to the player that got hit.
     
  5. Offline

    teej107

    I've seen it done on a server so it is possible. How they did it, I don't know exactly. They are a couple methods that I have in mind that could work.
     
  6. Offline

    BeefySticks

    How about getting a player that is nearby and changing the spawning a arrow at the direction of that player where the last arrow landed. It might look like a double bounce.
     
  7. Offline

    sethrem

    TheCwispyOne BeefySticks Monkey_Swag teej107
    EDIT: I Don't mind if the arrow "bounces" I'm mainly wondering how to damage another entity within a distance of the attacked entity. Thanks in advanced. And thanks for the current replies.
     
  8. Offline

    BeefySticks

    sethrem
    I created this code real quick for you!

    Code:java
    1.  
    2. @EventHandler
    3. public void onDamage(EntityDamageEvent event) {
    4. Player player = (Player) event.getEntity();
    5. DamageCause arrow = event.getCause();
    6. double radius = 3D;
    7. List<Entity> nearplayers = player.getWorld().getEntities();
    8.  
    9. if(arrow.PROJECTILE != null) {
    10.  
    11. // CHECK IF IS ARROW
    12.  
    13.  
    14. for(Entity e : nearplayers) {
    15. if(event.getEntity() instanceof Player && event.getEntity() != null) {
    16. ((Damageable) e).damage(3);
    17. }
    18. }
    19. }
    20. }
    21. }
     
  9. Offline

    Monkey_Swag

    BeefySticks thanks for the nice comment. I love to help people out. I used to get help (and still do). I just want to give back to the community :)
     
  10. Offline

    teej107

    That code erm.... could use some work.
    • Your not using the radius variable
    • nearplayers is targeting every entity in the world
    • arrow.PROJECTILE != null will always be true
    • event.getEntity() instanceof Player is also a null check, not need for event.getEntity() != null
    To fix:
    1. You want near players? getNearbyEntities(double x, double y, double z)
    2. To properly check is the projectile is an arrow.... I would actually use the EntityDamageByEntityEvent since it has this: getDamager(). You can then do
      Code:java
      1. getDamager() instanceof Arrow
      to properly check if the damager is an arrow.
     
  11. Offline

    sethrem

    I can't manage to get it, could you please provide me with some code?
     
  12. Offline

    BeefySticks

    Thanks for correcting me!
     
  13. Offline

    teej107

    You give me your attempted code and we can work off of that. You can also use BeefySticks code as long as you apply the fixes I suggested.
     
  14. Offline

    MeRPG

    So wait... Do you want it to bounce a certain direction? Or to bounce always towards another entity in range?
    Either way I can help you guys write something.
     
  15. Offline

    sethrem

    teej107 I mean it works but it doesn't register the player as a "death" and I get an error every single time I shoot the arrow at a person.
    Code:java
    1. List<Entity> nearplayers = victim.getNearbyEntities(3.0, 3.0, 3.0);
    2. for (Entity e2 : nearplayers) {
    3. if (victim instanceof Player) {
    4. ((Damageable) e2).damage(20.0);
    5. victim.damage(20.0);
    6. }
    7. }


    Then The Error

    Code:java
    1. [16:28:59 ERROR]: Could not pass event EntityDamageByEntityEvent to OITQ v1.0
    2. org.bukkit.event.EventException
    3. at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:427) ~[craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    4. at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    5. at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:481) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    6. at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:466) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    7. at org.bukkit.craftbukkit.v1_7_R1.event.CraftEventFactory.callEvent(CraftEventFactory.java:94) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    8. at org.bukkit.craftbukkit.v1_7_R1.event.CraftEventFactory.callEntityDamageEvent(CraftEventFactory.java:382) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    9. at org.bukkit.craftbukkit.v1_7_R1.event.CraftEventFactory.handleEntityDamageEvent(CraftEventFactory.java:410) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    10. at net.minecraft.server.v1_7_R1.EntityLiving.damageEntity(EntityLiving.java:656) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    11. at net.minecraft.server.v1_7_R1.EntityHuman.damageEntity(EntityHuman.java:746) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    12. at net.minecraft.server.v1_7_R1.EntityPlayer.damageEntity(EntityPlayer.java:446) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    13. at net.minecraft.server.v1_7_R1.EntityArrow.h(EntityArrow.java:228) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    14. at net.minecraft.server.v1_7_R1.World.entityJoinedWorld(World.java:1338) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    15. at net.minecraft.server.v1_7_R1.World.playerJoinedWorld(World.java:1319) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    16. at net.minecraft.server.v1_7_R1.World.tickEntities(World.java:1207) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    17. at net.minecraft.server.v1_7_R1.WorldServer.tickEntities(WorldServer.java:480) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    18. at net.minecraft.server.v1_7_R1.MinecraftServer.u(MinecraftServer.java:637) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    19. at net.minecraft.server.v1_7_R1.DedicatedServer.u(DedicatedServer.java:250) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    20. at net.minecraft.server.v1_7_R1.MinecraftServer.t(MinecraftServer.java:545) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    21. at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:457) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    22. at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617) [craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    23. Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_7_R1.entity.CraftArrow cannot be cast to org.bukkit.entity.Damageable
    24. at me.events.PlayerListener.onHit(PlayerListener.java:137) ~[?:?]
    25. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_11]
    26. at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_11]
    27. at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_11]
    28. at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_11]
    29. at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:425) ~[craftbukkit.jar:git-Bukkit-1.7.2-R0.2-b2974jnks]
    30. ... 19 more


    Line 137 is :
    Code:java
    1. ((Damageable) e2).damage(20.0);


    Bounce towards another entity within a certain radius of the first hit(Player who got hit by the bow) player.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 14, 2016
  16. Offline

    MeRPG

    This line is what is throwing the error...
    ((Damageable) e2).damage(20.0);
    Probably because not all entities are damageable. Add a check.


    Ok alot of things were misplaced.
    So like this:
    Code:java
    1. List<Entity> nearplayers = victim.getNearbyEntities(3.0, 3.0, 3.0);
    2. for (Entity e2 : nearplayers) {
    3. if (e2 instanceof Player) {
    4. ((Damageable) e2).damage(20.0);
    5. }
    6. }
    7. victim.damage(20.0);
     
    ChipDev likes this.
  17. Offline

    JjPwN1

    Code:java
    1. if(event.getEntity() instanceof Player && event.getDamager() instanceof Arrow){
    2. Arrow arrow = event.getDamager();
    3. if(arrow.getShooter() != null && arrow.getShooter() instanceof Player){
    4. Random rand = new Random();
    5. if((rand.nextInt((max - min) + 1) + min) == 1){
    6. List<Entity> nearby = event.getEntity().getNearbyEntities(radius, radius, radius);
    7. if(nearby.size() > 0){
    8. for(Entity e : nearby){
    9. if(e instanceof Player && e.getId() != event.getEntity().getId() && e.getId() != event.getDamager().getId()){
    10. Arrow a = arrow.getLocation().getWorld().spawnEntity(arrow.getLocation(), EntityType.ARROW);
    11. a.setShooter(arrow.getShooter());
    12. Vector vec = new Vector((e.getLocation().getX() - event.getEntity().getLocation().getX()), 0, (e.getLocation().getZ() - event.getEntity().getLocation().getZ()));
    13. a.setVelocity(vec.multiply(0.3));
    14. break;
    15. }
    16. }
    17. }
    18. }
    19. }
    20. }

    This is what I would do for bouncing from one player to the next only one time. You'll have to find a way to make it bounce a second time yourself.

    This code will check if the damaged entity is a player, check if the damager is an arrow, check if the arrow's shooter is a player, generate a chance, get any nearby players within a certain radius, and spawn a new arrow and set its velocity towards a nearby player.
     
  18. Offline

    MeRPG

    I would use MetaData. But, it appears that my eclipse crashed. So it isn't done.
    But I finished it in notepad++... Should work.
    Code:java
    1. @EventHandler
    2. public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent e) {
    3. if(e.getCause()==DamageCause.PROJECTILE) {
    4. if(e.getDamager() instanceof Arrow && e.getEntity() instanceof Player) {
    5. Player player = (Player) e.getEntity();
    6. Arrow arrow = (Arrow) e.getDamager();
    7. Object o = getMetadata(arrow, "Bounces", this);
    8. int bounces = 0;
    9. if(o!=null)
    10. bounces = ((int) o);
    11. if(bounces<2) {
    12. List<Entity> nearplayers = player.getNearbyEntities(3.0, 3.0, 3.0);
    13. Player closest = null;
    14. for (Entity e2 : nearplayers) {
    15. if (e2 instanceof Player) {
    16. if(closest==null)
    17. closest = (Player) e2;
    18. if(e2.getLocation().distance(player.getLocation())<closest.getLocation().distance(player.getLocation()))
    19. closest = (Player) e2;
    20. }
    21. }
    22. if(closest!=null) {
    23. Vector v = new Vector(closest.getLocation().getX()-player.getLocation().getX(),//I'm not sure if I got the vectors right... Please don't beat me up D:
    24. 0.2,//This value could use some tweaking
    25. closest.getLocation().getZ()-player.getLocation().getZ());
    26. Arrow arr = player.getWorld().spawnArrow(arrow.getLocation(), v.multiply(1.1D), 1F/*These could use some tweaking too*/, 0F);
    27. arr.setShooter(arrow.getShooter());
    28. setMetadata(arr, "Bounces", bounces+1, this);
    29. }
    30. }
    31. }
    32. }
    33. }
    34.  
    35. public void setMetadata(Metadatable object, String key, Object value, Plugin plugin) {
    36. object.setMetadata(key, new FixedMetadataValue(plugin, value));
    37. }
    38.  
    39. public Object getMetadata(Metadatable object, String key, Plugin plugin) {
    40. List<MetadataValue> values = object.getMetadata(key);
    41. for (MetadataValue value : values) {
    42. if (value.getOwningPlugin() == plugin) {
    43. return value.value();
    44. }
    45. }
    46. return null;
    47. }


    Let me know! :D



    EDIT: I got my eclipse working again and tested it out.
    It needed an update. The code above has been tweaked.
    It works! :D :)

    Oh, and if you are using eclipse, I'd recommend Control(Or Command)+Shift+F to fix the formatting issues from bukkits website.
     
Thread Status:
Not open for further replies.

Share This Page