Painting improvements. Thanks CelticMinstrel!

Implement get/setArt and facing direction for paintings; expanded painting break causes; added painting support to World.spawn
This commit is contained in:
EvilSeph 2011-10-01 13:31:28 -04:00
parent d53a155e4c
commit 22baa13894
3 changed files with 190 additions and 9 deletions

View File

@ -4,8 +4,11 @@ import java.util.ArrayList;
import java.util.List;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.entity.Painting;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakByWorldEvent;
import org.bukkit.event.painting.PaintingBreakEvent.RemoveCause;
import org.bukkit.event.painting.PaintingBreakEvent;
// CraftBukkit end
public class EntityPainting extends Entity {
@ -123,7 +126,17 @@ public class EntityPainting extends Entity {
this.f = 0;
if (!this.i()) {
// CraftBukkit start
PaintingBreakByWorldEvent event = new PaintingBreakByWorldEvent((org.bukkit.entity.Painting) this.getBukkitEntity());
Material material = this.world.getMaterial((int)this.locX, (int)this.locY, (int)this.locZ);
RemoveCause cause;
if (material.equals(Material.WATER)) {
cause = RemoveCause.WATER;
} else if (!material.equals(Material.AIR)) {
// TODO: This feels insufficient to catch 100% of suffocation cases
cause = RemoveCause.OBSTRUCTION;
} else {
cause = RemoveCause.PHYSICS;
}
PaintingBreakEvent event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), cause);
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
@ -204,11 +217,21 @@ public class EntityPainting extends Entity {
public boolean damageEntity(DamageSource damagesource, int i) {
if (!this.dead && !this.world.isStatic) {
// CraftBukkit start
PaintingBreakByEntityEvent event = new PaintingBreakByEntityEvent((org.bukkit.entity.Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity());
this.world.getServer().getPluginManager().callEvent(event);
PaintingBreakEvent event = null;
if (damagesource.getEntity() != null) {
event = new PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity());
} else {
if (damagesource == DamageSource.FIRE) {
event = new PaintingBreakEvent((Painting) this.getBukkitEntity(), RemoveCause.FIRE);
}
// TODO: Could put other stuff here?
}
if (event != null) {
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return true;
if (event.isCancelled()) {
return true;
}
}
if(!dead) {
@ -222,6 +245,25 @@ public class EntityPainting extends Entity {
return true;
}
// CraftBukkit start - copy of a method in Entity except for the CraftBukkit-specific code
// TODO: Better way?
public void a(EntityWeatherStorm entityweatherstorm) {
// CraftBukkit start
PaintingBreakByEntityEvent event = new PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), entityweatherstorm.getBukkitEntity());
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
// CraftBukkit end
++this.fireTicks;
if (this.fireTicks == 0) {
this.fireTicks = 300;
}
}
// CraftBukkit end
public void b(NBTTagCompound nbttagcompound) {
nbttagcompound.a("Dir", (byte) this.a);
nbttagcompound.setString("Motive", this.e.A);

View File

@ -20,6 +20,7 @@ import org.bukkit.event.weather.WeatherChangeEvent;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.world.SpawnChangeEvent;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Boat;
import org.bukkit.Chunk;
import org.bukkit.inventory.ItemStack;
@ -755,7 +756,37 @@ public class CraftWorld implements World {
}
} else if (Painting.class.isAssignableFrom(clazz)) {
// negative
Block block = getBlockAt(location);
BlockFace face = BlockFace.SELF;
if (block.getRelative(BlockFace.EAST).getTypeId() == 0) {
face = BlockFace.EAST;
} else if (block.getRelative(BlockFace.NORTH).getTypeId() == 0) {
face = BlockFace.NORTH;
} else if (block.getRelative(BlockFace.WEST).getTypeId() == 0) {
face = BlockFace.WEST;
} else if (block.getRelative(BlockFace.SOUTH).getTypeId() == 0) {
face = BlockFace.SOUTH;
}
int dir;
switch(face) {
case EAST:
default:
dir = 0;
break;
case NORTH:
dir = 1;
break;
case WEST:
dir = 2;
break;
case SOUTH:
dir = 3;;
break;
}
entity = new EntityPainting(world, (int) x, (int) y, (int) z, dir);
if (!((EntityPainting)entity).i()) {
entity = null;
}
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new EntityTNTPrimed(world, x, y, z);
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {

View File

@ -1,8 +1,16 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.server.EntityPainting;
import net.minecraft.server.EnumArt;
import net.minecraft.server.Packet25EntityPainting;
import net.minecraft.server.Packet29DestroyEntity;
import net.minecraft.server.WorldServer;
import org.bukkit.Art;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.entity.Painting;
public class CraftPainting extends CraftEntity implements Painting {
@ -12,8 +20,108 @@ public class CraftPainting extends CraftEntity implements Painting {
}
@Override
public String toString() {
return "CraftPainting";
public EntityPainting getHandle() {
return (EntityPainting) super.getHandle();
}
@Override
public String toString() {
return "CraftPainting[art=" + getArt() + "]";
}
public Art getArt() {
EnumArt art = getHandle().e;
// Since both EnumArt and Art have exactly the same enum constants, this works
return Art.getByName(art.toString());
}
public boolean setArt(Art art) {
return setArt(art, false);
}
public boolean setArt(Art art, boolean force) {
EntityPainting painting = getHandle();
EnumArt oldArt = painting.e;
EnumArt newArt = EnumArt.valueOf(art.toString());
painting.e = newArt;
painting.b(painting.a);
if(!force && !painting.i()) {
// Revert painting since it doesn't fit
painting.e = oldArt;
painting.b(painting.a);
return false;
}
this.update();
return true;
}
public BlockFace getAttachedFace() {
return getFacing().getOppositeFace();
}
public void setFacingDirection(BlockFace face) {
setFacingDirection(face, false);
}
public boolean setFacingDirection(BlockFace face, boolean force) {
Block block = getLocation().getBlock().getRelative(getAttachedFace()).getRelative(face.getOppositeFace()).getRelative(getFacing());
EntityPainting painting = getHandle();
int x = painting.b, y = painting.c, z = painting.d, dir = painting.a;
painting.b = block.getX();
painting.c = block.getY();
painting.d = block.getZ();
switch(face) {
case EAST:
default:
getHandle().b(0);
break;
case NORTH:
getHandle().b(1);
break;
case WEST:
getHandle().b(2);
break;
case SOUTH:
getHandle().b(3);
break;
}
if(!force && !painting.i()) {
// Revert painting since it doesn't fit
painting.b = x;
painting.c = y;
painting.d = z;
painting.b(dir);
return false;
}
this.update();
return true;
}
public BlockFace getFacing() {
switch(getHandle().a) {
case 0:
default:
return BlockFace.EAST;
case 1:
return BlockFace.NORTH;
case 2:
return BlockFace.WEST;
case 3:
return BlockFace.SOUTH;
}
}
private void update() {
WorldServer world = ((CraftWorld)getWorld()).getHandle();
EntityPainting painting = new EntityPainting(world);
painting.b = getHandle().b;
painting.c = getHandle().c;
painting.d = getHandle().d;
painting.e = getHandle().e;
painting.b(getHandle().a);
getHandle().die();
getHandle().velocityChanged = true; // because this occurs when the painting is broken, so it might be important
world.addEntity(painting);
this.entity = painting;
}
}