Few questions involving entity events (Entities in general, rather)

Discussion in 'Plugin Development' started by DrBoweNur, Jul 10, 2011.

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

    DrBowe

    1) When using onEntityDeath, I've noticed that there's no way to check for the killer if the killer was an entity. (or maybe there is, I just cant find it)

    Would I be able to accomplish this same task by using onEntityDamageByEntity, and using isDead() to check whether or not that specific event killed off the entity?

    2) Is there any way to 'force' explode a creeper? I currently have a spell that causes arrows to make creepers explode, (but it doesnt actually do that, I use a hack-ish workaround of removing the creeper and creating an explosion at the creepers location)

    However, I feel like using the createExplosion method would not trigger any event for anti-griefing and blast control plugins. Ideally, I'd like for this spell to only cause actual explosion damage if creeper explosions are allowed.

    Thus, my question: Can I actually force-explode the creeper, thus launching the explode event?
     
  2. Offline

    krinsdeath

    You may be able to cast an event using getLastDamageCause() in onEntityDeath.

    Code:
    	@Override
    	public void onEntityDeath(EntityDeathEvent event) {
    		if (event.getEntity() instanceof Player) {
    			Player player = (Player) event.getEntity();
    			if (player.getLastDamageCause() instanceof EntityDamageByEntityEvent) {
    				EntityDamageByEntityEvent evt = (EntityDamageByEntityEvent) player.getLastDamageCause();
    				// do code here
    			}
    		}
    	}
    
    As for your second question, I have no idea what you mean so I can't really answer it. When do you want to cause the creeper to explode?
     
  3. Offline

    DrBowe

    I'm simply asking if there is a way to 'force' a creeper to explode (if any conidition is met, really), and make it appear natural to the server.
    Example:
    Arrow --> Creeper
    Currently, my skill is something along these lines
    Code:java
    1.  
    2. //Check for creeper on projectile hit event, etc etc, blah blah
    3. Creeper c;
    4. getWorld().createExplosion(c.getLocation(), 3, false);
    5. c.remove();
    6.  


    However, this will not throw the event to plugins such as Blast Control, which are meant to prevent creeper-explosions. Thus, it wouldn't get prevented.
     
  4. Offline

    DrAgonmoray

    No, you can't force a creeper to explode :|
     
  5. Offline

    DrBowe

    Oh well, guess I'll have to figure out some work-around to allow people to choose whether or not it damages blocks.
     
  6. Offline

    DrAgonmoray

    I'm wondering if there is some way into tricking bukkit/the plugin into thinking it's a creeper explosion
     
  7. Offline

    DrBowe

    That was my first thought, actually. But I figured that in order for that to work, you'd need to somehow relate the explosion to a creeper in the first place. Currently, createExplosion is the only thing I have to work with.
    I have considered spawning tnt with 0 fuse, however. But I dont want the block to show up client side.
     
  8. Offline

    Hretsam

    You guys mean something like this:

    Code:
                CraftCreeper creeper = (CraftCreeper) event.getEntity();
                creeper.getHandle().setPowered(true);
     
  9. Offline

    DrBowe

    @Hretsam
    I was under the impression that setPowered() is used to toggle the 'powered creeper' state, as in, when a creeper gets struck by lightning.

    Is that really to make the creeper explode?
    Yeah, thats not for triggering the explosion, it's for triggering whether or not it has the blue animation around it. (and if it will have an increased explosion radius)
     
  10. Offline

    Hretsam

    Oh i forgot about that, just a sec.
     
  11. Offline

    DrBowe

    @krinsdeath
    BTW, thanks for the answer to the first one. Works like a charm.
    Before, I was trying to cast directly from death --> damageByEntity (which isnt possible)
     
  12. Offline

    Hretsam

    ok try this:
    Its not the most clean way, but it should work.

    Code:
    if (event.getEntity() instanceof CraftCreeper){
                float explosionsize = 7;
                Location loc = event.getEntity().getLocation();
                ((CraftWorld) event.getEntity().getWorld()).getHandle().createExplosion(((CraftEntity) event.getEntity()).getHandle(), loc.getX(), loc.getY(), loc.getZ(), explosionsize, true);
                event.getEntity().remove();
            }
     
  13. Offline

    DrBowe

    @Hretsam
    I'm going to assume I need an additional lib other than Bukkit, seeing as nothing with Craft able to be imported.
    I'm also going to assume that lib is CraftBukkit, give me a sec
     
  14. Offline

    Hretsam

    Yeah forgot to mention that, i always use the CraftBukkit library, as it allows you to bypass some things
     
  15. Offline

    DrBowe

    Yeah, got it all compiled and ready to go. Just need to download Blast Control to actually test whether its throwing the right events.

    @Hretsam

    Good attempt, but no cigar. Its still not 'tricking' the server into thinking that a creeper exploded, therefor the event never fires (thus the explosion isnt preventable by any external plugin)

    On a completely unrelated note, is anyone having issues with onProjectileHit, where it only fires the event for arrows once they're picked up (or if they hit a mob/player)?
    With snowballs and eggs, it will fire when they hit any block, making the location easy to obtain. But arrows...something's not quite right with them.

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

    Hretsam

    Hmm, i'll try some things and will get back to you tomorrow.
     
  17. Offline

    krinsdeath

    You can try to pull off the same thing as your onEntityDeath event (for projectiles), but cast it inside onEntityDamage:

    Code:
    @Override
    public void onEntityDamage(EntityDamageEvent event) {
      if (event.getEntity().getLastDamageCause() instance of EntityDamageByProjectileEvent) {
        // do stuff here
      }
    }
    
     
  18. Offline

    Crash

    You can try to manually throw the event when you kill the creeper
     
  19. Offline

    DrBowe

    How might I go about doing this, though? I cant see a viable way of throwing it without defining it as a Custom Event, which then defeats the purpose of external plugins blocking it.
     
  20. Offline

    nisovin

    Create a new ExplosionPrimeEvent, then call it from the PluginManager. After, check its cancelled state, and only continue with your code if it wasn't cancelled.
     
  21. Offline

    Hretsam

    The whole idea behind this is that the event is called as a creeper explosion, so its caught with an other plugin.

    Here try this, it works for me
    Code:
        @Override
        public void onEntityDamage(EntityDamageEvent event) {
    
            if (event.getEntity() instanceof CraftCreeper) {
                if (event instanceof EntityDamageByProjectileEvent) {
                    EntityDamageByProjectileEvent pevent = (EntityDamageByProjectileEvent) event;
                    if (pevent.getDamager() instanceof CraftPlayer) {
                        float explosionsize = 7;
                        Location loc = event.getEntity().getLocation();
                        ((CraftWorld) event.getEntity().getWorld()).getHandle().createExplosion(((CraftEntity) event.getEntity()).getHandle(), loc.getX(), loc.getY(), loc.getZ(), explosionsize, false);
                        event.getEntity().remove();
                    }
                }
            }
        }
     
  22. Offline

    nisovin

    Your point? Plugins that prevent creeper explosions cancel the ExplosionPrimeEvent. Calling the explosion directly like that is important, but it won't generate an ExplosionPrimeEvent, which is important if he wants to check other plugins for cancellation.
     
  23. Offline

    Hretsam

    I am very much aware how to stop a creeper's explosion. But if there is an other plugin that logs creeper explosions, or does special action with it you cant just call an explosion or cancel it.
    Just calling an ExplosionPrimeEvent will not make something explode.
    Also not all plugins stop creeper explosions at the ExplosionPrimeEvent, you can also stop it at the EntityExplodeEvent.

    I get what you trying to say but what i understand from DrBoweNur the event must be called instant , and handled like a normal creeper explosion.
     
  24. Offline

    nisovin

    I think you misunderstand what I'm suggesting. I'm not saying to just call that event and hope everything works, I know perfectly well that just calling an event doesn't do anything. I'm saying you need to call that event first, check if it's cancelled, and if not, proceed with the code you provided. If you don't, any plugins that use that event to cancel explosions won't work with your plugin. If you check the code in EntityCreeper, you'd see that that's exactly what happens when a creeper is about to explode. Both events must be called if you want to support all plugins that might be watching for explosions.

    If you don't want to look it up yourself, here's the relevant section from EntityCreeper.java:

    Code:
    ExplosionPrimeEventevent=newExplosionPrimeEvent(CraftEntity.getEntity(this.world.getServer(),this),radius,false);
    this.world.getServer().getPluginManager().callEvent(event);
    if(!event.isCancelled()){
        this.world.createExplosion(this,this.locX,this.locY,this.locZ,event.getRadius(),event.getFire());
        this.die();
    }else{
        this.fuseTicks=0;
    }
     
  25. Offline

    Hretsam

    Oh yeah, i misunderstood you.
    I agree, both event should be called to make it work correctly.
     
Thread Status:
Not open for further replies.

Share This Page