TnT implementation in Sponge

First of all, I come from Bukkit, am quite new in Sponge and am still trying hard to find my bearings here. So this post might be totally off topic here - I beg your pardon if it is.

I’ve developed a few smallish plugins for Bukkit, and one of them was about TnT, which I altered to be throwable (as in grenades). With Bukkit, the whole TnT implementation was cumbersome; with transitions from an Item (when in hand or inventory) to a Block (when placed) to an Entity (when primed). What specifically was totally missing was an event to be fired at the moment the TnT is primed. Bukkit only had one event which fired exactly one tick before the explosion, but no event for when (and where) it was primed.

What are the thoughts on this in Sponge - will the TnT be handled differently (in a better way)?

Since a primed TNT is nothing more than an entity, shoudn’t it trigger an event that indicates a created entity? I haven’t worked with Bukkit but wouldn’t it be something like EntityCreateEvent?

Well I don’t know what it should be but I know for a fact that this was something that was entirely missing from Bukkit. It was requested many times, but denied for reasons unknown to me.

Hmm that is interesting. It would really surprise me though if there weren’t something like an EntityCreateEvent or EntitySpawnEvent or something like that since it’s a very basic concept in Minecraft.

Nope. Believe me there isn’t one which gives the coordinates of the location where the priming happens. This was very weird to me, and I never could understand why it is so.

Well I just checked it and I haven’t found any event that would indicate a general entity bein spawned. There are special ones for Creatures or Items, but none for entities in general.
So yea that would be something that should really be done better in Sponge.
A simple EntitySpawnEvent which fires on any entity that is spawned would already do the job.

2 Likes

So far I know, All Entity based stuff will be managed by the component system (outdated) and a edited build of Artemis.

I believe TnT should have a special event that says what primed it.

In a perfect world, we’d have a collection of what primed parent in the event and the upmost parent would say what ignited the first TnT and from what location it was triggered.

  • TNT @ 1,2,3 ignited by
  • TNT @ 1,5,6 ignited by
    • TNT @ 2,5,7 ignited by
      • Player @ 1,5,6
1 Like

In Bukkit a primed TnT caused an Entity Spawn event. If you created one via code you would need to throw an event for it.

Firing off an event every time any sort of entity spawns is a bad idea. The game uses entities all over the place, most of the time we don’t want to care about every single entity. A TNT primed event seems more reasonable.

You can’t NOT have an entity spawn event, it’s only when you spawn one through your own plugin you would need to fire off an event to let other plugins know. The same as notifying other plugins when you change a players health.

IIRC, even if a plugin manually spawns an entity, Bukkit would fire the EntitySpawnEvent. you’re right about changing players health, etc. but I seem to recall World.spawnEntity(…) fire’s the event on it’s own.

For the third time: no it doesn’t. Please believe me, I did everything to get this done, but couldn’t. I remember even starting a couple of discussions to ask from other Bukkit members about this, but got no suitable answer. There ISN’T an event whatsoever which gets fired when a TnT gets primed, and which gets me any useful information, like the coordinates where the priming happened. Actually, I couldn’t find an event at all which gets fired when the TnT gets primed.

EDIT: And yes, I am manually spawning the entity, not by anyone actually priming it (with redstone, flint&steel etc.).

I verified in the code. It only raises an event for living entities, items and projectiles.

src/main/java/net/minecraft/server/World.java
public boolean addEntity(Entity entity, SpawnReason spawnReason) :

// CraftBukkit start
org.bukkit.event.Cancellable event = null; 
if (entity instanceof EntityLiving && !(entity instanceof EntityPlayer)) { 
    boolean isAnimal = entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal || entity instanceof EntityGolem; 
    boolean isMonster = entity instanceof EntityMonster || entity instanceof EntityGhast || entity instanceof EntitySlime; 
 
    if (spawnReason != SpawnReason.CUSTOM) { 
        if (isAnimal && !allowAnimals || isMonster && !allowMonsters)  { 
            entity.dead = true; 
            return false; 
        } 
   } 

   event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason); 
} else if (entity instanceof EntityItem) { 
    event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity); 
} else if (entity.getBukkitEntity() instanceof org.bukkit.entity.Projectile) { 
    // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead 
    event = CraftEventFactory.callProjectileLaunchEvent(entity); 
} 

if (event != null && (event.isCancelled() || entity.dead)) { 
    entity.dead = true; 
    return false; 
} 
// CraftBukkit end 

I can understand why in Bukkit’s event system this was restricted. Otherwise, mass TnT explosions (where tens or hundreds of TnT blocks are primed) would have raised a massive amount of EntityCreate (or something similar) events. I don’t think living entities ever get created as fast as primed TnT could.

I think this boils down to us needing a more advanced event system, where priming events could be monitored for individual TnT blocks, instead of monitoring them all. Something similar has already been asked for:

2 Likes

So @TnT will be implemented into Sponge? FINALLY! (Lel jk)

This is a great idea!