Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-18 20:40:08 +01:00
Painting improvements. Thanks CelticMinstrel!
Implement get/setArt and facing direction for paintings; expanded painting break causes; added painting support to World.spawn
Dieser Commit ist enthalten in:
Ursprung
d53a155e4c
Commit
22baa13894
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren