diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java index 800ee10ec..75074019c 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitUtil.java @@ -150,9 +150,9 @@ public class BukkitUtil { switch (e.getType()) { case EXPERIENCE_ORB: return new BukkitExpOrb(toLocation(e.getLocation()), e.getUniqueId(), ((ExperienceOrb)e).getExperience()); - /*case PAINTING: // TODO: Figure out what celticminstrel broke + case PAINTING: Painting paint = (Painting) e; - return new BukkitPainting(toLocation(e.getLocation()), paint.getArt(), paint.getFacing(), e.getUniqueId());*/ + return new BukkitPainting(toLocation(e.getLocation()), paint.getArt(), paint.getFacing(), e.getUniqueId()); case DROPPED_ITEM: return new BukkitItem(toLocation(e.getLocation()), ((Item)e).getItemStack(), e.getUniqueId()); default: diff --git a/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitEntity.java b/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitEntity.java index 432db68ff..c25354796 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitEntity.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitEntity.java @@ -45,6 +45,6 @@ public class BukkitEntity extends LocalEntity { @Override public boolean spawn(Location weLoc) { org.bukkit.Location loc = BukkitUtil.toLocation(weLoc); - return loc.getWorld().spawnCreature(loc, type) != null; + return loc.getWorld().spawn(loc, type.getEntityClass()) != null; } } diff --git a/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitPainting.java b/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitPainting.java index f3e5921c9..a15058f06 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitPainting.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/entity/BukkitPainting.java @@ -21,16 +21,51 @@ package com.sk89q.worldedit.bukkit.entity; import com.sk89q.worldedit.Location; import com.sk89q.worldedit.bukkit.BukkitUtil; import org.bukkit.Art; +import org.bukkit.Bukkit; import org.bukkit.block.BlockFace; import org.bukkit.entity.EntityType; import org.bukkit.entity.Painting; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.UUID; /** * @author zml2008 */ public class BukkitPainting extends BukkitEntity { + private static int spawnTask = -1; + private static final Deque spawnQueue = new ArrayDeque(); + + private class QueuedPaintingSpawn { + private final Location weLoc; + + public QueuedPaintingSpawn(Location weLoc) { + this.weLoc = weLoc; + } + + public void spawn() { + spawnRaw(weLoc); + } + } + private static class PaintingSpawnRunnable implements Runnable { + @Override + public void run() { + synchronized (spawnQueue) { + QueuedPaintingSpawn spawn; + while ((spawn = spawnQueue.poll()) != null) { + try { + spawn.spawn(); + } catch (Throwable t) { + t.printStackTrace(); + continue; + } + } + spawnTask = -1; + } + } + } + private final Art art; private final BlockFace facingDirection; public BukkitPainting(Location loc, Art art, BlockFace facingDirection, UUID entityId) { @@ -39,12 +74,29 @@ public class BukkitPainting extends BukkitEntity { this.facingDirection = facingDirection; } + /** + * Queue the painting to be spawned at the specified location. + * This operation is delayed so that the block changes that may be applied can be applied before the painting spawn is attempted. + * + * @param weLoc The WorldEdit location + * @return Whether the spawn as successful + */ public boolean spawn(Location weLoc) { + synchronized (spawnQueue) { + spawnQueue.add(new QueuedPaintingSpawn(weLoc)); + if (spawnTask == -1) { + spawnTask = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Bukkit.getServer().getPluginManager().getPlugin("WorldEdit"), new PaintingSpawnRunnable(), 1L); + } + } + return true; + } + + public boolean spawnRaw(Location weLoc) { org.bukkit.Location loc = BukkitUtil.toLocation(weLoc); Painting paint = loc.getWorld().spawn(loc, Painting.class); if (paint != null) { - paint.setFacingDirection(facingDirection); - paint.setArt(art); + paint.setFacingDirection(facingDirection, true); + paint.setArt(art, true); return true; } return false;