Paper/src/main/java/org/bukkit/craftbukkit/CraftWorld.java

845 lines
29 KiB
Java
Raw Normal View History

2010-12-27 03:13:03 +01:00
package org.bukkit.craftbukkit;
import org.bukkit.craftbukkit.entity.*;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
import java.util.ArrayList;
2010-12-27 03:13:03 +01:00
import java.util.HashMap;
import java.util.List;
import java.util.Random;
2011-07-13 06:06:07 +02:00
import java.util.UUID;
import net.minecraft.server.*;
import org.bukkit.entity.Arrow;
import org.bukkit.Effect;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
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.entity.Boat;
2010-12-27 03:13:03 +01:00
import org.bukkit.Chunk;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.bukkit.BlockChangeDelegate;
import org.bukkit.Bukkit;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.ChunkSnapshot;
2011-01-02 09:40:27 +01:00
import org.bukkit.Location;
import org.bukkit.TreeType;
2010-12-27 03:13:03 +01:00
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
2010-12-27 03:13:03 +01:00
public class CraftWorld implements World {
private final WorldServer world;
2011-06-04 00:35:05 +02:00
private Environment environment;
private final CraftServer server = (CraftServer)Bukkit.getServer();
private HashMap<Integer, CraftChunk> unloadedChunks = new HashMap<Integer, CraftChunk>();
private final ChunkGenerator generator;
private final List<BlockPopulator> populators = new ArrayList<BlockPopulator>();
2011-02-02 00:32:18 +01:00
private static final Random rand = new Random();
2010-12-27 03:13:03 +01:00
public CraftWorld(WorldServer world, ChunkGenerator gen, Environment env) {
2010-12-27 03:13:03 +01:00
this.world = world;
this.generator = gen;
environment = env;
2010-12-27 03:13:03 +01:00
}
2011-05-14 16:29:42 +02:00
public void preserveChunk(CraftChunk chunk) {
2011-03-11 20:39:09 +01:00
chunk.breakLink();
2011-05-14 16:29:42 +02:00
unloadedChunks.put((chunk.getX() << 16) + chunk.getZ(), chunk);
}
2011-05-14 16:29:42 +02:00
public Chunk popPreservedChunk(int x, int z) {
return unloadedChunks.remove((x << 16) + z);
}
2010-12-27 03:13:03 +01:00
public Block getBlockAt(int x, int y, int z) {
2011-02-01 23:49:28 +01:00
return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y & 0x7F, z & 0xF);
2010-12-27 03:13:03 +01:00
}
public int getBlockTypeIdAt(int x, int y, int z) {
2011-01-29 22:50:29 +01:00
return world.getTypeId(x, y, z);
}
2011-01-03 22:56:09 +01:00
public int getHighestBlockYAt(int x, int z) {
return world.getHighestBlockYAt(x, z);
2011-01-03 22:56:09 +01:00
}
2011-02-02 00:32:18 +01:00
2011-01-16 00:00:01 +01:00
public Location getSpawnLocation() {
ChunkCoordinates spawn = world.getSpawn();
return new Location(this, spawn.x, spawn.y, spawn.z);
2011-01-16 00:00:01 +01:00
}
2011-03-01 03:21:27 +01:00
public boolean setSpawnLocation(int x, int y, int z) {
try {
Location previousLocation = getSpawnLocation();
world.worldData.setSpawn(x, y, z);
// Notify anyone who's listening.
SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation);
server.getPluginManager().callEvent(event);
2011-03-01 03:21:27 +01:00
return true;
} catch (Exception e) {
return false;
}
}
2010-12-27 03:13:03 +01:00
public Chunk getChunkAt(int x, int z) {
return this.world.chunkProviderServer.getChunkAt(x, z).bukkitChunk;
2010-12-27 03:13:03 +01:00
}
public Chunk getChunkAt(Block block) {
2011-01-18 12:37:01 +01:00
return getChunkAt(block.getX() >> 4, block.getZ() >> 4);
2010-12-27 03:13:03 +01:00
}
2011-02-01 23:49:28 +01:00
public boolean isChunkLoaded(int x, int z) {
return world.chunkProviderServer.isChunkLoaded(x, z);
2010-12-27 03:13:03 +01:00
}
2011-02-04 21:11:57 +01:00
public Chunk[] getLoadedChunks() {
Object[] chunks = world.chunkProviderServer.chunks.values().toArray();
org.bukkit.Chunk[] craftChunks = new CraftChunk[chunks.length];
for (int i = 0; i < chunks.length; i++) {
net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) chunks[i];
2011-02-09 21:00:17 +01:00
craftChunks[i] = chunk.bukkitChunk;
}
return craftChunks;
2011-02-04 21:11:57 +01:00
}
2011-02-01 23:49:28 +01:00
public void loadChunk(int x, int z) {
loadChunk(x, z, true);
}
public boolean unloadChunk(int x, int z) {
return unloadChunk(x, z, true);
}
public boolean unloadChunk(int x, int z, boolean save) {
return unloadChunk(x, z, save, false);
}
public boolean unloadChunkRequest(int x, int z) {
return unloadChunkRequest(x, z, true);
}
public boolean unloadChunkRequest(int x, int z, boolean safe) {
if (safe && isChunkInUse(x, z)) {
return false;
}
world.chunkProviderServer.queueUnload(x, z);
return true;
}
public boolean unloadChunk(int x, int z, boolean save, boolean safe) {
if (safe && isChunkInUse(x, z)) {
return false;
}
net.minecraft.server.Chunk chunk = world.chunkProviderServer.getOrCreateChunk(x, z);
if (save) {
chunk.removeEntities();
world.chunkProviderServer.saveChunk(chunk);
world.chunkProviderServer.saveChunkNOP(chunk);
}
preserveChunk((CraftChunk) chunk.bukkitChunk);
world.chunkProviderServer.unloadQueue.remove(x, z);
world.chunkProviderServer.chunks.remove(x, z);
world.chunkProviderServer.chunkList.remove(chunk);
return true;
}
2011-03-02 21:27:44 +01:00
public boolean regenerateChunk(int x, int z) {
unloadChunk(x, z, false, false);
world.chunkProviderServer.unloadQueue.remove(x, z);
2011-03-02 21:27:44 +01:00
net.minecraft.server.Chunk chunk = null;
if (world.chunkProviderServer.chunkProvider == null) {
chunk = world.chunkProviderServer.emptyChunk;
2011-03-02 21:27:44 +01:00
} else {
chunk = world.chunkProviderServer.chunkProvider.getOrCreateChunk(x, z);
2011-03-02 21:27:44 +01:00
}
chunkLoadPostProcess(chunk, x, z);
refreshChunk(x, z);
return chunk != null;
}
public boolean refreshChunk(int x, int z) {
if (!isChunkLoaded(x, z)) {
2011-03-02 21:27:44 +01:00
return false;
}
int px = x << 4;
int pz = z << 4;
2011-03-02 21:27:44 +01:00
// If there are more than 10 updates to a chunk at once, it carries out the update as a cuboid
// This flags 16 blocks in a line along the bottom for update and then flags a block at the opposite corner at the top
// The cuboid that contains these 17 blocks covers the entire chunk
// The server will compress the chunk and send it to all clients
for (int xx = px; xx < (px + 16); xx++) {
world.notify(xx, 0, pz);
2011-03-02 21:27:44 +01:00
}
world.notify(px, 127, pz + 15);
2011-03-02 21:27:44 +01:00
return true;
}
public boolean isChunkInUse(int x, int z) {
Player[] players = server.getOnlinePlayers();
for (Player player : players) {
Location loc = player.getLocation();
if (loc.getWorld() != world.chunkProviderServer.world.getWorld()) {
continue;
}
// If the chunk is within 256 blocks of a player, refuse to accept the unload request
// This is larger than the distance of loaded chunks that actually surround a player
// The player is the center of a 21x21 chunk grid, so the edge is 10 chunks (160 blocks) away from the player
if (Math.abs(loc.getBlockX() - (x << 4)) <= 256 && Math.abs(loc.getBlockZ() - (z << 4)) <= 256) {
2011-03-02 19:50:39 +01:00
return true;
}
}
2011-03-02 19:50:39 +01:00
return false;
}
public boolean loadChunk(int x, int z, boolean generate) {
if (generate) {
// Use the default variant of loadChunk when generate == true.
return world.chunkProviderServer.getChunkAt(x, z) != null;
}
world.chunkProviderServer.unloadQueue.remove(x, z);
net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) world.chunkProviderServer.chunks.get(x, z);
if (chunk == null) {
chunk = world.chunkProviderServer.loadChunk(x, z);
2011-03-02 21:27:44 +01:00
chunkLoadPostProcess(chunk, x, z);
}
return chunk != null;
}
2011-03-02 21:27:44 +01:00
private void chunkLoadPostProcess(net.minecraft.server.Chunk chunk, int x, int z) {
if (chunk != null) {
world.chunkProviderServer.chunks.put(x, z, chunk);
world.chunkProviderServer.chunkList.add(chunk);
chunk.loadNOP();
chunk.addEntities();
if (!chunk.done && world.chunkProviderServer.isChunkLoaded(x + 1, z + 1) && world.chunkProviderServer.isChunkLoaded(x, z + 1) && world.chunkProviderServer.isChunkLoaded(x + 1, z)) {
world.chunkProviderServer.getChunkAt(world.chunkProviderServer, x, z);
2011-03-02 21:27:44 +01:00
}
if (world.chunkProviderServer.isChunkLoaded(x - 1, z) && !world.chunkProviderServer.getOrCreateChunk(x - 1, z).done && world.chunkProviderServer.isChunkLoaded(x - 1, z + 1) && world.chunkProviderServer.isChunkLoaded(x, z + 1) && world.chunkProviderServer.isChunkLoaded(x - 1, z)) {
world.chunkProviderServer.getChunkAt(world.chunkProviderServer, x - 1, z);
2011-03-02 21:27:44 +01:00
}
if (world.chunkProviderServer.isChunkLoaded(x, z - 1) && !world.chunkProviderServer.getOrCreateChunk(x, z - 1).done && world.chunkProviderServer.isChunkLoaded(x + 1, z - 1) && world.chunkProviderServer.isChunkLoaded(x, z - 1) && world.chunkProviderServer.isChunkLoaded(x + 1, z)) {
world.chunkProviderServer.getChunkAt(world.chunkProviderServer, x, z - 1);
2011-03-02 21:27:44 +01:00
}
if (world.chunkProviderServer.isChunkLoaded(x - 1, z - 1) && !world.chunkProviderServer.getOrCreateChunk(x - 1, z - 1).done && world.chunkProviderServer.isChunkLoaded(x - 1, z - 1) && world.chunkProviderServer.isChunkLoaded(x, z - 1) && world.chunkProviderServer.isChunkLoaded(x - 1, z)) {
world.chunkProviderServer.getChunkAt(world.chunkProviderServer, x - 1, z - 1);
}
}
2011-01-20 21:57:33 +01:00
}
2011-02-01 23:49:28 +01:00
public boolean isChunkLoaded(Chunk chunk) {
return isChunkLoaded(chunk.getX(), chunk.getZ());
}
2011-02-01 23:49:28 +01:00
public void loadChunk(Chunk chunk) {
loadChunk(chunk.getX(), chunk.getZ());
((CraftChunk) getChunkAt(chunk.getX(), chunk.getZ())).getHandle().bukkitChunk = chunk;
2011-01-04 16:54:41 +01:00
}
public WorldServer getHandle() {
return world;
}
2011-02-01 23:49:28 +01:00
2011-02-22 01:43:12 +01:00
public org.bukkit.entity.Item dropItem(Location loc, ItemStack item) {
2011-01-15 20:53:20 +01:00
net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(
item.getTypeId(),
item.getAmount(),
item.getDurability()
2011-01-15 20:53:20 +01:00
);
EntityItem entity = new EntityItem(world, loc.getX(), loc.getY(), loc.getZ(), stack);
entity.pickupDelay = 10;
world.addEntity(entity);
2011-05-14 16:29:42 +02:00
// TODO this is inconsistent with how Entity.getBukkitEntity() works.
// However, this entity is not at the moment backed by a server entity class so it may be left.
2011-02-22 01:43:12 +01:00
return new CraftItem(world.getServer(), entity);
2011-01-08 21:48:45 +01:00
}
2011-02-02 00:32:18 +01:00
2011-02-22 01:43:12 +01:00
public org.bukkit.entity.Item dropItemNaturally(Location loc, ItemStack item) {
double xs = world.random.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
double ys = world.random.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
double zs = world.random.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
2011-01-08 21:48:45 +01:00
loc = loc.clone();
loc.setX(loc.getX() + xs);
loc.setY(loc.getY() + ys);
loc.setZ(loc.getZ() + zs);
2011-01-08 21:48:45 +01:00
return dropItem(loc, item);
}
2011-01-15 20:53:20 +01:00
public Arrow spawnArrow(Location loc, Vector velocity, float speed, float spread) {
2011-01-02 09:40:27 +01:00
EntityArrow arrow = new EntityArrow(world);
arrow.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), 0, 0);
world.addEntity(arrow);
2011-01-02 09:40:27 +01:00
arrow.a(velocity.getX(), velocity.getY(), velocity.getZ(), speed, spread);
return (Arrow) arrow.getBukkitEntity();
2011-01-02 09:40:27 +01:00
}
2011-02-02 00:32:18 +01:00
/**
* @deprecated use {@link #spawn(Location, Class)} instead
*/
@Deprecated
public Minecart spawnMinecart(Location loc) {
return spawn(loc, Minecart.class);
}
2011-02-02 00:32:18 +01:00
/**
* @deprecated use {@link #spawn(Location, Class)} instead
*/
@Deprecated
public StorageMinecart spawnStorageMinecart(Location loc) {
return spawn(loc, StorageMinecart.class);
}
2011-02-02 00:32:18 +01:00
/**
* @deprecated use {@link #spawn(Location, Class)} instead
*/
@Deprecated
public PoweredMinecart spawnPoweredMinecart(Location loc) {
return spawn(loc, PoweredMinecart.class);
}
2011-02-02 00:32:18 +01:00
/**
* @deprecated use {@link #spawn(Location, Class)} instead
*/
@Deprecated
public Boat spawnBoat(Location loc) {
return spawn(loc, Boat.class);
}
2011-02-02 00:32:18 +01:00
public LivingEntity spawnCreature(Location loc, CreatureType creatureType) {
LivingEntity creature;
try {
EntityLiving entityCreature = (EntityLiving) EntityTypes.a(creatureType.getName(), world);
entityCreature.setPosition(loc.getX(), loc.getY(), loc.getZ());
2011-03-30 00:40:46 +02:00
creature = (LivingEntity) CraftEntity.getEntity(server, entityCreature);
world.addEntity(entityCreature, SpawnReason.CUSTOM);
} catch (Exception e) {
// if we fail, for any reason, return null.
creature = null;
}
return creature;
}
public LightningStrike strikeLightning(Location loc) {
EntityWeatherStorm lightning = new EntityWeatherStorm(world, loc.getX(), loc.getY(), loc.getZ());
world.strikeLightning(lightning);
return new CraftLightningStrike(server, lightning);
}
public LightningStrike strikeLightningEffect(Location loc) {
EntityWeatherStorm lightning = new EntityWeatherStorm(world, loc.getX(), loc.getY(), loc.getZ(), true);
world.strikeLightning(lightning);
return new CraftLightningStrike(server, lightning);
}
public boolean generateTree(Location loc, TreeType type) {
return generateTree(loc, type, world);
}
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
switch (type) {
case BIG_TREE:
2011-02-02 00:32:18 +01:00
return new WorldGenBigTree().generate(delegate, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
case BIRCH:
2011-02-02 00:32:18 +01:00
return new WorldGenForest().generate(delegate, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
case REDWOOD:
2011-02-02 00:32:18 +01:00
return new WorldGenTaiga2().generate(delegate, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
case TALL_REDWOOD:
2011-02-02 00:32:18 +01:00
return new WorldGenTaiga1().generate(delegate, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
case TREE:
default:
2011-02-02 00:32:18 +01:00
return new WorldGenTrees().generate(delegate, rand, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
}
2011-02-02 00:32:18 +01:00
public TileEntity getTileEntityAt(final int x, final int y, final int z) {
2011-01-29 22:50:29 +01:00
return world.getTileEntity(x, y, z);
}
2011-01-08 03:29:57 +01:00
public String getName() {
return world.worldData.name;
2011-01-08 03:29:57 +01:00
}
2011-07-05 05:48:27 +02:00
@Deprecated
2011-01-08 03:29:57 +01:00
public long getId() {
return world.worldData.getSeed();
2011-01-08 03:29:57 +01:00
}
2011-07-13 06:06:07 +02:00
public UUID getUID() {
return world.getUUID();
2011-07-05 05:48:27 +02:00
}
@Override
public String toString() {
2011-02-07 02:22:43 +01:00
return "CraftWorld{name=" + getName() + '}';
}
2011-02-01 15:53:39 +01:00
public long getTime() {
long time = getFullTime() % 24000;
if (time < 0) time += 24000;
return time;
}
public void setTime(long time) {
long margin = (time - getFullTime()) % 24000;
if (margin < 0) margin += 24000;
setFullTime(getFullTime() + margin);
}
public long getFullTime() {
return world.getTime();
2011-02-01 15:53:39 +01:00
}
public void setFullTime(long time) {
world.setTime(time);
2011-05-14 16:29:42 +02:00
// Forces the client to update to the new time immediately
for (Player p: getPlayers()) {
CraftPlayer cp = (CraftPlayer) p;
cp.getHandle().netServerHandler.sendPacket(new Packet4UpdateTime(cp.getHandle().getPlayerTime()));
}
2011-02-01 15:53:39 +01:00
}
public boolean createExplosion(double x, double y, double z, float power) {
return createExplosion(x, y, z, power, false);
}
public boolean createExplosion(double x, double y, double z, float power, boolean setFire) {
return world.createExplosion(null, x, y, z, power, setFire).wasCanceled ? false : true;
}
public boolean createExplosion(Location loc, float power) {
return createExplosion(loc, power, false);
}
public boolean createExplosion(Location loc, float power, boolean setFire) {
return createExplosion(loc.getX(), loc.getY(), loc.getZ(), power, setFire);
}
public Environment getEnvironment() {
return environment;
}
2011-06-04 00:35:05 +02:00
public void setEnvironment(Environment env) {
if (environment != env) {
environment = env;
world.worldProvider = WorldProvider.byDimension(environment.getId());
2011-06-04 00:35:05 +02:00
}
}
public Block getBlockAt(Location location) {
return getBlockAt(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
public int getBlockTypeIdAt(Location location) {
return getBlockTypeIdAt(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
public int getHighestBlockYAt(Location location) {
return getHighestBlockYAt(location.getBlockX(), location.getBlockZ());
}
public Chunk getChunkAt(Location location) {
return getChunkAt(location.getBlockX() >> 4, location.getBlockZ() >> 4);
}
public ChunkGenerator getGenerator() {
return generator;
}
public List<BlockPopulator> getPopulators() {
return populators;
}
public Block getHighestBlockAt(int x, int z) {
return getBlockAt(x, getHighestBlockYAt(x, z), z);
}
public Block getHighestBlockAt(Location location) {
return getHighestBlockAt(location.getBlockX(), location.getBlockZ());
}
public Biome getBiome(int x, int z) {
BiomeBase base = getHandle().getWorldChunkManager().getBiome(x, z);
if (base == BiomeBase.RAINFOREST) {
return Biome.RAINFOREST;
} else if (base == BiomeBase.SWAMPLAND) {
return Biome.SWAMPLAND;
} else if (base == BiomeBase.SEASONAL_FOREST) {
return Biome.SEASONAL_FOREST;
} else if (base == BiomeBase.FOREST) {
return Biome.FOREST;
} else if (base == BiomeBase.SAVANNA) {
return Biome.SAVANNA;
} else if (base == BiomeBase.SHRUBLAND) {
return Biome.SHRUBLAND;
} else if (base == BiomeBase.TAIGA) {
return Biome.TAIGA;
} else if (base == BiomeBase.DESERT) {
return Biome.DESERT;
} else if (base == BiomeBase.PLAINS) {
return Biome.PLAINS;
} else if (base == BiomeBase.ICE_DESERT) {
return Biome.ICE_DESERT;
} else if (base == BiomeBase.TUNDRA) {
return Biome.TUNDRA;
} else if (base == BiomeBase.HELL) {
return Biome.HELL;
} else if (base == BiomeBase.SKY) {
return Biome.SKY;
}
return null;
}
public double getTemperature(int x, int z) {
return getHandle().getWorldChunkManager().a((double[])null, x, z, 1, 1)[0];
}
public double getHumidity(int x, int z) {
return getHandle().getWorldChunkManager().getHumidity(x, z);
}
2010-12-27 03:13:03 +01:00
private final class ChunkCoordinate {
public final int x;
public final int z;
2010-12-27 03:13:03 +01:00
public ChunkCoordinate(final int x, final int z) {
this.x = x;
this.z = z;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ChunkCoordinate other = (ChunkCoordinate) obj;
if (this.x != other.x) {
return false;
}
if (this.z != other.z) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + this.x;
hash = 53 * hash + this.z;
return hash;
}
}
public List<Entity> getEntities() {
List<Entity> list = new ArrayList<Entity>();
2011-02-02 00:32:18 +01:00
for (Object o: world.entityList) {
if (o instanceof net.minecraft.server.Entity) {
net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o;
Entity bukkitEntity = mcEnt.getBukkitEntity();
// Assuming that bukkitEntity isn't null
if (bukkitEntity != null) {
list.add(bukkitEntity);
}
}
}
2011-02-02 00:32:18 +01:00
return list;
}
public List<LivingEntity> getLivingEntities() {
List<LivingEntity> list = new ArrayList<LivingEntity>();
2011-02-02 00:32:18 +01:00
for (Object o: world.entityList) {
if (o instanceof net.minecraft.server.Entity) {
net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o;
Entity bukkitEntity = mcEnt.getBukkitEntity();
2011-02-02 00:32:18 +01:00
// Assuming that bukkitEntity isn't null
if (bukkitEntity != null && bukkitEntity instanceof LivingEntity) {
list.add((LivingEntity) bukkitEntity);
}
}
}
2011-02-02 00:32:18 +01:00
return list;
}
2011-02-24 20:37:53 +01:00
public List<Player> getPlayers() {
List<Player> list = new ArrayList<Player>();
for (Object o : world.entityList) {
2011-02-24 20:37:53 +01:00
if (o instanceof net.minecraft.server.Entity) {
net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o;
2011-02-24 20:37:53 +01:00
Entity bukkitEntity = mcEnt.getBukkitEntity();
2011-02-24 20:37:53 +01:00
if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) {
list.add((Player) bukkitEntity);
2011-02-24 20:37:53 +01:00
}
}
}
return list;
}
public void save() {
// Writes level.dat
world.saveLevel();
// Saves all chunks/regions
world.chunkProvider.saveChunks(true, null);
}
2011-04-22 11:18:13 +02:00
public boolean hasStorm() {
return world.worldData.hasStorm();
2011-04-22 11:18:13 +02:00
}
public void setStorm(boolean hasStorm) {
CraftServer server = world.getServer();
WeatherChangeEvent weather = new WeatherChangeEvent((org.bukkit.World) this, hasStorm);
server.getPluginManager().callEvent(weather);
if (!weather.isCancelled()) {
world.worldData.setStorm(hasStorm);
// These numbers are from Minecraft
if (hasStorm) {
setWeatherDuration(rand.nextInt(12000) + 12000);
} else {
setWeatherDuration(rand.nextInt(168000) + 12000);
}
2011-04-22 11:18:13 +02:00
}
}
public int getWeatherDuration() {
return world.worldData.getWeatherDuration();
2011-04-22 11:18:13 +02:00
}
public void setWeatherDuration(int duration) {
world.worldData.setWeatherDuration(duration);
2011-04-22 11:18:13 +02:00
}
2011-04-22 12:13:21 +02:00
public boolean isThundering() {
return world.worldData.isThundering();
2011-04-22 12:13:21 +02:00
}
public void setThundering(boolean thundering) {
CraftServer server = world.getServer();
ThunderChangeEvent thunder = new ThunderChangeEvent((org.bukkit.World) this, thundering);
server.getPluginManager().callEvent(thunder);
if (!thunder.isCancelled()) {
world.worldData.setThundering(thundering);
// These numbers are from Minecraft
if (thundering) {
setThunderDuration(rand.nextInt(12000) + 3600);
} else {
setThunderDuration(rand.nextInt(168000) + 12000);
}
2011-04-22 12:13:21 +02:00
}
}
2011-04-22 12:13:21 +02:00
public int getThunderDuration() {
return world.worldData.getThunderDuration();
2011-04-22 12:13:21 +02:00
}
public void setThunderDuration(int duration) {
world.worldData.setThunderDuration(duration);
2011-04-22 12:13:21 +02:00
}
public long getSeed() {
return world.worldData.getSeed();
}
2011-04-30 00:34:37 +02:00
public boolean getPVP() {
return world.pvpMode;
}
public void setPVP(boolean pvp) {
world.pvpMode = pvp;
}
public void playEffect(Player player, Effect effect, int data) {
playEffect(player.getLocation(), effect, data, 0);
}
public void playEffect(Location location, Effect effect, int data) {
playEffect(location, effect, data, 64);
2011-04-30 00:34:37 +02:00
}
public void playEffect(Location location, Effect effect, int data, int radius) {
int packetData = effect.getId();
Packet61 packet = new Packet61(packetData, location.getBlockX(), location.getBlockY(), location.getBlockZ(), data);
int distance;
for (Player player : getPlayers()) {
2011-06-10 08:56:42 +02:00
distance = (int) player.getLocation().distance(location);
if (distance <= radius) {
((CraftPlayer) player).getHandle().netServerHandler.sendPacket(packet);
}
}
}
@SuppressWarnings("unchecked")
public <T extends Entity> T spawn(Location location, Class<T> clazz) throws IllegalArgumentException {
if (location == null || clazz == null) {
throw new IllegalArgumentException("Location or entity class cannot be null");
}
net.minecraft.server.Entity entity = null;
double x = location.getX();
double y = location.getY();
double z = location.getZ();
float pitch = location.getPitch();
float yaw = location.getYaw();
// order is important for some of these
if (Boat.class.isAssignableFrom(clazz)) {
entity = new EntityBoat(world, x, y, z);
} else if (Egg.class.isAssignableFrom(clazz)) {
entity = new EntityEgg(world, x, y, z);
} else if (FallingSand.class.isAssignableFrom(clazz)) {
entity = new EntityFallingSand(world, x, y, z, 0);
} else if (Fireball.class.isAssignableFrom(clazz)) {
entity = new EntityFireball(world);
((EntityFireball) entity).setPositionRotation(x, y, z, yaw, pitch);
Vector direction = location.getDirection().multiply(10);
((EntityFireball) entity).setDirection(direction.getX(), direction.getY(), direction.getZ());
} else if (Snowball.class.isAssignableFrom(clazz)) {
entity = new EntitySnowball(world, x, y, z);
} else if (Minecart.class.isAssignableFrom(clazz)) {
2011-06-18 18:30:50 +02:00
if (PoweredMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecart(world, x, y, z, CraftMinecart.Type.PoweredMinecart.getId());
2011-06-18 18:30:50 +02:00
} else if (StorageMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecart(world, x, y, z, CraftMinecart.Type.StorageMinecart.getId());
} else {
entity = new EntityMinecart(world, x, y, z, CraftMinecart.Type.Minecart.getId());
}
} else if (Arrow.class.isAssignableFrom(clazz)) {
entity = new EntityArrow(world);
entity.setPositionRotation(x, y, z, 0, 0);
} else if (LivingEntity.class.isAssignableFrom(clazz)) {
if (Chicken.class.isAssignableFrom(clazz)) {
entity = new EntityChicken(world);
} else if (Cow.class.isAssignableFrom(clazz)) {
entity = new EntityCow(world);
} else if (Creeper.class.isAssignableFrom(clazz)) {
entity = new EntityCreeper(world);
} else if (Ghast.class.isAssignableFrom(clazz)) {
entity = new EntityGhast(world);
} else if (Pig.class.isAssignableFrom(clazz)) {
2011-06-20 00:03:54 +02:00
entity = new EntityPig(world);
} else if (Player.class.isAssignableFrom(clazz)) {
// need a net server handler for this one
} else if (Sheep.class.isAssignableFrom(clazz)) {
entity = new EntitySheep(world);
} else if (Skeleton.class.isAssignableFrom(clazz)) {
entity = new EntitySkeleton(world);
} else if (Slime.class.isAssignableFrom(clazz)) {
entity = new EntitySlime(world);
} else if (Spider.class.isAssignableFrom(clazz)) {
entity = new EntitySpider(world);
} else if (Squid.class.isAssignableFrom(clazz)) {
entity = new EntitySquid(world);
} else if (Wolf.class.isAssignableFrom(clazz)) {
entity = new EntityWolf(world);
} else if (PigZombie.class.isAssignableFrom(clazz)) {
entity = new EntityPigZombie(world);
} else if (Zombie.class.isAssignableFrom(clazz)) {
entity = new EntityZombie(world);
}
if (entity != null) {
entity.setLocation(x, y, z, pitch, yaw);
}
} else if (Painting.class.isAssignableFrom(clazz)) {
// negative
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new EntityTNTPrimed(world, x, y, z);
} else if (Weather.class.isAssignableFrom(clazz)) {
// not sure what this can do
entity = new EntityWeatherStorm(world, x, y, z);
} else if (LightningStrike.class.isAssignableFrom(clazz)) {
// what is this, I don't even
} else if (Fish.class.isAssignableFrom(clazz)) {
// this is not a fish, it's a bobber, and it's probably useless
entity = new EntityFish(world);
entity.setLocation(x, y, z, pitch, yaw);
}
if (entity != null) {
world.addEntity(entity);
return (T) entity.getBukkitEntity();
}
throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName());
}
public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) {
return CraftChunk.getEmptyChunkSnapshot(x, z, this, includeBiome, includeBiomeTempRain);
}
public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) {
world.setSpawnFlags(allowMonsters, allowAnimals);
}
public boolean getAllowAnimals() {
return world.allowAnimals;
}
public boolean getAllowMonsters() {
return world.allowMonsters;
}
2010-12-27 03:13:03 +01:00
}