diff --git a/src/main/java/net/glowstone/GlowWorld.java b/src/main/java/net/glowstone/GlowWorld.java index c084396962..0fee854168 100644 --- a/src/main/java/net/glowstone/GlowWorld.java +++ b/src/main/java/net/glowstone/GlowWorld.java @@ -1411,6 +1411,35 @@ public T spawn(Location location, Class clazz, return null; // TODO: work on type mismatches } + //Needed for Events which mutate Entities before they are spawned + public T spawn(Location location, T entity, SpawnReason reason) + throws IllegalArgumentException { + checkNotNull(entity).setRawLocation(location, false); + checkNotNull(reason); + checkNotNull(location); + try { + EntitySpawnEvent spawnEvent = null; + if (entity instanceof LivingEntity) { + spawnEvent = EventFactory.getInstance() + .callEvent(new CreatureSpawnEvent((LivingEntity) entity, reason)); + } else if (!(entity instanceof Item)) { // ItemSpawnEvent is called elsewhere + spawnEvent = EventFactory.getInstance().callEvent(new EntitySpawnEvent(entity)); + } + if (spawnEvent != null && spawnEvent.isCancelled()) { + // TODO: separate spawning and construction for better event cancellation + entity.remove(); + } else { + List spawnMessage = entity.createSpawnMessage(); + getRawPlayers().stream().filter(player -> player.canSeeEntity(entity)) + .forEach(player -> player.getSession().sendAll(spawnMessage + .toArray(new Message[spawnMessage.size()]))); + } + } catch (Throwable t) { + GlowServer.logger.log(Level.SEVERE, "Unable to spawn entity: ", t); + } + return entity; + } + /** * Spawns an entity. * diff --git a/src/main/java/net/glowstone/entity/GlowLightningStrike.java b/src/main/java/net/glowstone/entity/GlowLightningStrike.java index f7a3caef2a..688e99f32e 100644 --- a/src/main/java/net/glowstone/entity/GlowLightningStrike.java +++ b/src/main/java/net/glowstone/entity/GlowLightningStrike.java @@ -8,7 +8,10 @@ import net.glowstone.EventFactory; import net.glowstone.GlowWorld; import net.glowstone.block.GlowBlock; +import net.glowstone.entity.monster.GlowPigZombie; +import net.glowstone.entity.passive.GlowPig; import net.glowstone.entity.physics.BoundingBox; +import net.glowstone.io.entity.EntityStorage; import net.glowstone.net.GlowSession; import net.glowstone.net.message.play.entity.SpawnLightningStrikeMessage; import org.bukkit.Location; @@ -20,9 +23,12 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LightningStrike; +import org.bukkit.entity.Pig; import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.PigZapEvent; import org.bukkit.util.Vector; /** @@ -113,6 +119,19 @@ public void pulse() { ((Damageable) entity) .damage(5, this, EntityDamageEvent.DamageCause.LIGHTNING); } + if (entity instanceof Pig) { + GlowPig pig = (GlowPig) entity; + GlowPigZombie zombie = EntityStorage.create(GlowPigZombie.class, location); + PigZapEvent event = new PigZapEvent(pig, this, zombie); + if (EventFactory.getInstance().callEvent(event).isCancelled()) { + zombie.remove(); + } else { + // Only the custom name is copied, all other attributes are overwritten + zombie.setCustomName(pig.getCustomName()); + pig.remove(); + world.spawn(location, zombie, CreatureSpawnEvent.SpawnReason.LIGHTNING); + } + } entity.setFireTicks(entity.getMaxFireTicks()); } // TODO: Spawn Skeletontrap