Solved Need help with entity hit on ProjectileHitEvent

Discussion in 'Plugin Development' started by FuryCharger, Sep 25, 2016.

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

    FuryCharger

    hi! i have huge problems with this code. basically what i need to do is, after a snowball with the name i want is launched hits a living entity, cause a lightning effect and cause damage (not included).
    Now, it does everything correctly, but problem is that i have problems with dealing the lightning.
    What i need to do is: if the snowball directly hits the entity, damage JUST THAT ENTITY, otherwise nothing.
    As what i want to do is also bypassing invincibility ticks whenever i hit entity with any snowball, i can't use EntityDamageEvent as it would work just after first snowball lands so i can reset invincibility ticks, but i want invincibility ticks reset as the entity gets hit
    So i'm trying with ProjectileHitEvent, which is giving me tons of problems.
    I have tried with locations and distance without success, and i've tried with block coords, which are unreliable, so please, please, please, please, please, please, please, if you know what to do, help me
    i'm making this for 1.8
    Thanks everyone for help!!

    Code:
        @EventHandler
        public void onEntityProjHit(ProjectileHitEvent event){
            if(SnowballToPlayer.containsKey(event.getEntity().getEntityId())) {
                Entity projectile = event.getEntity();
                 UUID owner = SnowballToPlayer.get(event.getEntity().getEntityId());
                 Location landed = projectile.getLocation();
               
               
                for(Entity entity : projectile.getWorld().getLivingEntities()){
                    if((landed.getBlockX() == entity.getLocation().getBlockX())&&
                            (landed.getBlockZ() == entity.getLocation().getBlockZ())&&
                            (landed.getBlockY() == entity.getLocation().getBlockY())){ //this if is the last of my tests, which resulted to be pretty useless
                         World world = (World) projectile.getWorld();
                         world.strikeLightningEffect(entity.getLocation());
                         }
                 SnowballToPlayer.remove(owner);
                     }
                }
            }
     
    Last edited by a moderator: Sep 25, 2016
  2. Offline

    Evonoucono

    @FuryCharger
    First of all your for loop of all entities could simply search through all entities nearby a certain location with:
    Code:
    world.getNearbyEntities(location, distanceX, distanceY, distance Z);
    the way you have it will compare locations to potentially hundreds of entities so that's no good.
    Also maybe you could try using fake lightning and then using entity.damage(double); it worked for me.
    Fake lightning doesn't deal damage but just displays the lightning:
    Code:
    EntityLightning lightning = new EntityLightning((((CraftWorld) loc.getWorld()).getHandle()), loc.getX(), loc.getY(), loc.getZ(), true);
            MinecraftServer.getServer().getPlayerList().sendPacketNearby(null, loc.getX(), loc.getY(), loc.getZ(), LightningViewDistance, 0, new PacketPlayOutSpawnEntityWeather(lightning));
            loc.getWorld().playSound(loc, Sound.ENTITY_LIGHTNING_THUNDER, (float) 1, 1);
    LightningViewDistance will be an integer for how far away players can see the lightning, since you have it so all players in that world can see and hear the lightning, maybe just set that value to be really high.
    You are also using 1.8 so some code may need to be modified
     
  3. Offline

    FuryCharger

    problem is not regarding the lightning, problem is regarding the fact that i haven't found a possible way to get the entity hit by the snowball and make the effect just for that specific entity, without doing anything to others, so that the lightning triggers just when the entity is hit directly by it without needing to do it for all nearby entities
     
  4. Offline

    Evonoucono

    Code:
        @EventHandler
        public void entDmgEntEvent(EntityDamageByEntityEvent e){
            if (e.getDamager() instanceof Snowball){
                if (e.getEntity() instanceof LivingEntity){
                    LivingEntity ent = (LivingEntity) e.getEntity();
                    ent.damage(6);
                    Location loc = ent.getLocation();
                    EntityLightning lightning = new EntityLightning((((CraftWorld) loc.getWorld()).getHandle()), loc.getX(), loc.getY(), loc.getZ(), true);
                    MinecraftServer.getServer().getPlayerList().sendPacketNearby(null, loc.getX(), loc.getY(), loc.getZ(), 200, 0, new PacketPlayOutSpawnEntityWeather(lightning));
                    loc.getWorld().playSound(loc, Sound.ENTITY_LIGHTNING_THUNDER, (float) 100, 1);
                }
            }
        }
    This will check if the damager is a snowball, get the entity hit, damage the entity hit, and spawn fake lightning for effect. Some things may need to be changed because you are using 1.8
     
  5. Offline

    FuryCharger

    nevermind with the help of a friend i've fully solved it. only problem is that if the snowball hits the block where the entity is standing it'll trigger the lightning anyway, but apart from that now the code if very accurate :)
    here it is as it should be and thank you for your help!
    Code:
    @EventHandler
        public void onEntityProjHit(ProjectileHitEvent event){
            if(SnowballToPlayer.containsKey(event.getEntity().getEntityId())) {
                 UUID owner = SnowballToPlayer.get(event.getEntity().getEntityId());
                 Player player = getServer().getPlayer(owner);
                Entity projectile = event.getEntity();
                 Location landed = projectile.getLocation();
                
                 List<Entity> nearby = projectile.getNearbyEntities(0.8, 1.9, 0.8);
                 if (nearby.isEmpty()) return;
                 else{
                     Entity nearest = player;
                    
                     for(Entity entity : nearby){ 
                                            
                         if (entity instanceof LivingEntity){
                            if (entity.equals(nearby.get(0))){
                                nearest = entity;
                                 }
                                if (entity instanceof Player){
                                    Player target = (Player) entity;
                                   if ((target.getGameMode()==GameMode.CREATIVE)||(target.getGameMode()==GameMode.SPECTATOR)||
                                               target.getUniqueId().equals(owner))
                                           continue;
                                   else if (target.getLocation().distanceSquared(landed)<
                                        nearest.getLocation().distanceSquared(landed)){
                                       if (entity.getLocation().getY()>landed.getY())
                                           nearest = target;
                                       }
                                    }
                                else if (entity.getLocation().distanceSquared(landed)<
                                nearest.getLocation().distanceSquared(landed)){
                                    if (entity.getLocation().getY()>landed.getY())
                                    nearest = entity;               
                                }
                            }   
                         }
                     LivingEntity damaged = (LivingEntity) nearest;
                     if (!(damaged.getUniqueId().equals(owner))){
                         damaged.setNoDamageTicks(0);
                         damaged.damage(8);
                         damaged.getWorld().strikeLightningEffect(damaged.getLocation());
                         if (damaged.isDead())
                             player.sendMessage("Nice hit! Your target now is dead!");
                         }
                     else return;
                     }
                SnowballToPlayer.remove(owner);
                }
            }
     
  6. Offline

    RenditionsRule

    @Evonoucono
    What is it with you and spoonfeeding...
     
  7. Offline

    Evonoucono

    @RenditionsRule
    When I was learning bukkit a while back I learned better with an explanation, followed by example code. Some people learn better with getting direction on how to do something, and then looking at example code linked with it. They can then modify it, and learn what everything does, as well as find useful information on different classes and methods in the example. When different things are obscure and hard to learn because of limited resources, spoon-feeding can be the only way people actually learn something. It really depends on who asks for the example though. They can either use the example in their plugin and not learn anything, or they can experiment with it, find out how it actually works, and learn from it. The bukkit forums has this thing where they think there is absolutely nothing good from giving out examples, but I just don't agree with it.
     
  8. @Evonoucono
    I think you've misunderstood a bit what "spoonfeeding" actually refers to. It refers to just solving the problem for the OP and giving the large portions of code, without any explanation. There's nothing wrong with examples, and they can be very good for letting people understand things, but you need to explain in detail what each part of the code does, not just post it with "try this:" or "use this, and change that argument here or there". The reason why the Bukkit community has decided to discourage spoonfeeding is because in the majority of cases, the person being spoonfed won't experiment with the code and find out how it works, especially if no or very little explanation is given.
     
  9. Offline

    Evonoucono

    @AlvinB
    I completely agree, but I hope, "especially if no or very little explanation is given." wasn't completely directed at me. Look at my first two posts on this page, I think I provided enough explanation of what things do. It could have been better but some things don't even need an explanation because they don't have a very broad purpose.
     
  10. @Evonoucono
    No, my post was more related to the statement that "The bukkit forums has this thing where they think there is absolutely nothing good from giving out examples".
     
    Evonoucono likes this.
Thread Status:
Not open for further replies.

Share This Page