Teach EnderDragon how to throw EntityExplosionEvents when it breaks blocks
We also teach CraftWorld how to explode an event, taken from Explosion.a(boolean) (the code that breaks blocks and drops them on the ground). The EnderDragon has a flag that slows it down when it hits unbreakable blocks: Obsidian, White Stone or Bedrock. It might be useful to extend the event so that plugins can set this. Letting the API set the default yield for an explosion event has been deprecated, so we now set the default yield using the appropriate constructor.
Dieser Commit ist enthalten in:
Ursprung
4e318dd1c8
Commit
b08b85bd26
@ -1,12 +1,18 @@
|
|||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
// CraftBukkit start
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
public class EntityEnderDragon extends EntityComplex {
|
public class EntityEnderDragon extends EntityComplex {
|
||||||
|
|
||||||
public double a;
|
public double a;
|
||||||
@ -455,6 +461,10 @@ public class EntityEnderDragon extends EntityComplex {
|
|||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
boolean flag1 = false;
|
boolean flag1 = false;
|
||||||
|
|
||||||
|
// CraftBukkit start - create a list to hold all the destroyed blocks
|
||||||
|
List<org.bukkit.block.Block> destroyedBlocks = new ArrayList<org.bukkit.block.Block>();
|
||||||
|
CraftWorld craftWorld = this.world.getWorld();
|
||||||
|
// CraftBukkit end
|
||||||
for (int k1 = i; k1 <= l; ++k1) {
|
for (int k1 = i; k1 <= l; ++k1) {
|
||||||
for (int l1 = j; l1 <= i1; ++l1) {
|
for (int l1 = j; l1 <= i1; ++l1) {
|
||||||
for (int i2 = k; i2 <= j1; ++i2) {
|
for (int i2 = k; i2 <= j1; ++i2) {
|
||||||
@ -463,7 +473,10 @@ public class EntityEnderDragon extends EntityComplex {
|
|||||||
if (j2 != 0) {
|
if (j2 != 0) {
|
||||||
if (j2 != Block.OBSIDIAN.id && j2 != Block.WHITESTONE.id && j2 != Block.BEDROCK.id) {
|
if (j2 != Block.OBSIDIAN.id && j2 != Block.WHITESTONE.id && j2 != Block.BEDROCK.id) {
|
||||||
flag1 = true;
|
flag1 = true;
|
||||||
this.world.setTypeId(k1, l1, i2, 0);
|
// CraftBukkit start - add blocks to list rather than destroying them
|
||||||
|
//this.world.setTypeId(k1, l1, i2, 0);
|
||||||
|
destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2));
|
||||||
|
// CraftBukkit end
|
||||||
} else {
|
} else {
|
||||||
flag = true;
|
flag = true;
|
||||||
}
|
}
|
||||||
@ -473,6 +486,19 @@ public class EntityEnderDragon extends EntityComplex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flag1) {
|
if (flag1) {
|
||||||
|
// CraftBukkit start - set off an EntityExplodeEvent for the dragon exploding all these blocks
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity();
|
||||||
|
EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
// this flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down.
|
||||||
|
// We should consider adding an event extension for it, or perhaps returning true if the event is cancelled.
|
||||||
|
return flag;
|
||||||
|
} else {
|
||||||
|
for (org.bukkit.block.Block block : event.blockList()) {
|
||||||
|
craftWorld.explodeBlock(block, event.getYield());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat();
|
double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat();
|
||||||
double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat();
|
double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat();
|
||||||
double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat();
|
double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat();
|
||||||
|
@ -185,7 +185,7 @@ public class Explosion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList);
|
EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F);
|
||||||
this.world.getServer().getPluginManager().callEvent(event);
|
this.world.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
arraylist.clear();
|
arraylist.clear();
|
||||||
|
@ -895,4 +895,21 @@ public class CraftWorld implements World {
|
|||||||
public File getWorldFolder() {
|
public File getWorldFolder() {
|
||||||
return ((WorldNBTStorage)world.getDataManager()).getDirectory();
|
return ((WorldNBTStorage)world.getDataManager()).getDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void explodeBlock(Block block, float yield) {
|
||||||
|
// First of all, don't explode fire
|
||||||
|
if (block.getType().equals(Material.FIRE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int blockId = block.getTypeId();
|
||||||
|
int blockX = block.getX();
|
||||||
|
int blockY = block.getY();
|
||||||
|
int blockZ = block.getZ();
|
||||||
|
// following code is lifted from Explosion.a(boolean), and modified
|
||||||
|
net.minecraft.server.Block.byId[blockId].dropNaturally(this.world, blockX, blockY, blockZ, block.getData(), yield, 0);
|
||||||
|
block.setType(org.bukkit.Material.AIR);
|
||||||
|
// not sure what this does, seems to have something to do with the 'base' material of a block.
|
||||||
|
// For example, WOODEN_STAIRS does something with WOOD in this method
|
||||||
|
net.minecraft.server.Block.byId[blockId].a_(this.world, blockX, blockY, blockZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren