/*******************************************************************************
* This file is part of ASkyBlock.
*
* ASkyBlock is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ASkyBlock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.wasteofplastic.askyblock.schematics;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Rotation;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.block.Sign;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.entity.Wolf;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.DirectionalContainer;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import com.wasteofplastic.askyblock.ASkyBlock;
import com.wasteofplastic.askyblock.Settings;
import com.wasteofplastic.askyblock.Settings.GameType;
import com.wasteofplastic.askyblock.commands.IslandCmd;
import com.wasteofplastic.askyblock.nms.NMSAbstraction;
import com.wasteofplastic.askyblock.util.Util;
import com.wasteofplastic.askyblock.util.VaultHelper;
import com.wasteofplastic.org.jnbt.ByteArrayTag;
import com.wasteofplastic.org.jnbt.ByteTag;
import com.wasteofplastic.org.jnbt.CompoundTag;
import com.wasteofplastic.org.jnbt.FloatTag;
import com.wasteofplastic.org.jnbt.IntTag;
import com.wasteofplastic.org.jnbt.ListTag;
import com.wasteofplastic.org.jnbt.NBTInputStream;
import com.wasteofplastic.org.jnbt.ShortTag;
import com.wasteofplastic.org.jnbt.StringTag;
import com.wasteofplastic.org.jnbt.Tag;
public class Schematic {
private ASkyBlock plugin;
//private short[] blocks;
//private byte[] data;
private short width;
private short length;
private short height;
private Map<BlockVector, Map<String, Tag>> tileEntitiesMap = new HashMap<BlockVector, Map<String, Tag>>();
//private HashMap<BlockVector, EntityType> entitiesMap = new HashMap<BlockVector, EntityType>();
private List<EntityObject> entitiesList = new ArrayList<EntityObject>();
private File file;
private String heading;
private String name;
private String perm;
private String description;
private int rating;
private boolean useDefaultChest;
private Material icon;
private Biome biome;
private boolean usePhysics;
private boolean pasteEntities;
private boolean visible;
private int order;
// These hashmaps enable translation between WorldEdit strings and Bukkit names
//private HashMap<String, EntityType> WEtoME = new HashMap<String, EntityType>();
private List<EntityType> islandCompanion;
private List<String> companionNames;
private ItemStack[] defaultChestItems;
// Name of a schematic this one is paired with
private String partnerName = "";
// Key blocks
private Vector bedrock;
private Vector chest;
private Vector welcomeSign;
private Vector topGrass;
private Vector playerSpawn;
//private Material playerSpawnBlock;
private NMSAbstraction nms;
private Set<Integer> attachable = new HashSet<Integer>();
private Map<String, Art> paintingList = new HashMap<String, Art>();
private Map<Byte, BlockFace> facingList = new HashMap<Byte, BlockFace>();
private Map<Byte, Rotation> rotationList = new HashMap<Byte, Rotation>();
private List<IslandBlock> islandBlocks;
//private boolean pasteAir;
private int durability;
private int levelHandicap;
private double cost;
public Schematic(ASkyBlock plugin) {
this.plugin = plugin;
// Initialize
name = "";
heading = "";
description = "Default Island";
perm = "";
icon = Material.MAP;
rating = 50;
useDefaultChest = true;
biome = Settings.defaultBiome;
usePhysics = Settings.usePhysics;
file = null;
islandCompanion = new ArrayList<EntityType>();
islandCompanion.add(Settings.islandCompanion);
companionNames = Settings.companionNames;
defaultChestItems = Settings.chestItems;
visible = true;
order = 0;
bedrock = null;
chest = null;
welcomeSign = null;
topGrass = null;
playerSpawn = null;
//playerSpawnBlock = null;
partnerName = "";
}
@SuppressWarnings("deprecation")
public Schematic(ASkyBlock plugin, File file) throws IOException {
this.plugin = plugin;
// Initialize
short[] blocks;
byte[] data;
name = file.getName();
heading = "";
description = "";
perm = "";
icon = Material.MAP;
rating = 50;
useDefaultChest = true;
biome = Settings.defaultBiome;
usePhysics = Settings.usePhysics;
islandCompanion = new ArrayList<EntityType>();
islandCompanion.add(Settings.islandCompanion);
companionNames = Settings.companionNames;
defaultChestItems = Settings.chestItems;
pasteEntities = false;
visible = true;
order = 0;
bedrock = null;
chest = null;
welcomeSign = null;
topGrass = null;
playerSpawn = null;
//playerSpawnBlock = null;
partnerName = "";
attachable.add(Material.STONE_BUTTON.getId());
attachable.add(Material.WOOD_BUTTON.getId());
attachable.add(Material.COCOA.getId());
attachable.add(Material.LADDER.getId());
attachable.add(Material.LEVER.getId());
attachable.add(Material.PISTON_EXTENSION.getId());
attachable.add(Material.REDSTONE_TORCH_OFF.getId());
attachable.add(Material.REDSTONE_TORCH_ON.getId());
attachable.add(Material.WALL_SIGN.getId());
attachable.add(Material.TORCH.getId());
attachable.add(Material.TRAP_DOOR.getId());
attachable.add(Material.TRIPWIRE_HOOK.getId());
attachable.add(Material.VINE.getId());
attachable.add(Material.WOODEN_DOOR.getId());
attachable.add(Material.IRON_DOOR.getId());
attachable.add(Material.RED_MUSHROOM.getId());
attachable.add(Material.BROWN_MUSHROOM.getId());
attachable.add(Material.PORTAL.getId());
// Painting list, useful to check if painting exsits or nor
paintingList.put("Kebab", Art.KEBAB);
paintingList.put("Aztec", Art.AZTEC);
paintingList.put("Alban", Art.ALBAN);
paintingList.put("Aztec2", Art.AZTEC2);
paintingList.put("Bomb", Art.BOMB);
paintingList.put("Plant", Art.PLANT);
paintingList.put("Wasteland", Art.WASTELAND);
paintingList.put("Wanderer", Art.WANDERER);
paintingList.put("Graham", Art.GRAHAM);
paintingList.put("Pool", Art.POOL);
paintingList.put("Courbet", Art.COURBET);
paintingList.put("Sunset", Art.SUNSET);
paintingList.put("Sea", Art.SEA);
paintingList.put("Creebet", Art.CREEBET);
paintingList.put("Match", Art.MATCH);
paintingList.put("Bust", Art.BUST);
paintingList.put("Stage", Art.STAGE);
paintingList.put("Void", Art.VOID);
paintingList.put("SkullAndRoses", Art.SKULL_AND_ROSES);
paintingList.put("Wither", Art.WITHER);
paintingList.put("Fighters", Art.FIGHTERS);
paintingList.put("Skeleton", Art.SKELETON);
paintingList.put("DonkeyKong", Art.DONKEYKONG);
paintingList.put("Pointer", Art.POINTER);
paintingList.put("Pigscene", Art.PIGSCENE);
paintingList.put("BurningSkull", Art.BURNINGSKULL);
facingList.put((byte) 0, BlockFace.SOUTH);
facingList.put((byte) 1, BlockFace.WEST);
facingList.put((byte) 2, BlockFace.NORTH);
facingList.put((byte) 3, BlockFace.EAST);
rotationList.put((byte) 0, Rotation.NONE);
rotationList.put((byte) 2, Rotation.CLOCKWISE);
rotationList.put((byte) 4, Rotation.FLIPPED);
rotationList.put((byte) 6, Rotation.COUNTER_CLOCKWISE);
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
rotationList.put((byte) 1, Rotation.CLOCKWISE_45);
rotationList.put((byte) 3, Rotation.CLOCKWISE_135);
rotationList.put((byte) 5, Rotation.FLIPPED_45);
rotationList.put((byte) 7, Rotation.COUNTER_CLOCKWISE_45);
}
try {
nms = Util.checkVersion();
} catch (Exception e) {
e.printStackTrace();
}
// Establish the World Edit to Material look up
// V1.8 items
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
attachable.add(Material.IRON_TRAPDOOR.getId());
attachable.add(Material.WALL_BANNER.getId());
attachable.add(Material.ACACIA_DOOR.getId());
attachable.add(Material.BIRCH_DOOR.getId());
attachable.add(Material.SPRUCE_DOOR.getId());
attachable.add(Material.DARK_OAK_DOOR.getId());
attachable.add(Material.JUNGLE_DOOR.getId());
}
// Entities
/*
WEtoME.put("LAVASLIME", EntityType.MAGMA_CUBE);
WEtoME.put("ENTITYHORSE", EntityType.HORSE);
WEtoME.put("OZELOT", EntityType.OCELOT);
WEtoME.put("MUSHROOMCOW", EntityType.MUSHROOM_COW);
WEtoME.put("PIGZOMBIE", EntityType.PIG_ZOMBIE);
*/
this.file = file;
// Try to load the file
try {
FileInputStream stream = new FileInputStream(file);
// InputStream is = new DataInputStream(new
// GZIPInputStream(stream));
NBTInputStream nbtStream = new NBTInputStream(stream);
CompoundTag schematicTag = (CompoundTag) nbtStream.readTag();
nbtStream.close();
stream.close();
if (!schematicTag.getName().equals("Schematic")) {
throw new IllegalArgumentException("Tag \"Schematic\" does not exist or is not first");
}
Map<String, Tag> schematic = schematicTag.getValue();
Vector origin = null;
try {
int originX = getChildTag(schematic, "WEOriginX", IntTag.class).getValue();
int originY = getChildTag(schematic, "WEOriginY", IntTag.class).getValue();
int originZ = getChildTag(schematic, "WEOriginZ", IntTag.class).getValue();
Vector min = new Vector(originX, originY, originZ);
//int offsetX = getChildTag(schematic, "WEOffsetX", IntTag.class).getValue();
//int offsetY = getChildTag(schematic, "WEOffsetY", IntTag.class).getValue();
//int offsetZ = getChildTag(schematic, "WEOffsetZ", IntTag.class).getValue();
//Vector offset = new Vector(offsetX, offsetY, offsetZ);
//origin = min.subtract(offset);
origin = min.clone();
} catch (Exception ignored) {}
//Bukkit.getLogger().info("Origin = " + origin);
if (!schematic.containsKey("Blocks")) {
throw new IllegalArgumentException("Schematic file is missing a \"Blocks\" tag");
}
width = getChildTag(schematic, "Width", ShortTag.class).getValue();
length = getChildTag(schematic, "Length", ShortTag.class).getValue();
height = getChildTag(schematic, "Height", ShortTag.class).getValue();
String materials = getChildTag(schematic, "Materials", StringTag.class).getValue();
if (!materials.equals("Alpha")) {
throw new IllegalArgumentException("Schematic file is not an Alpha schematic");
}
byte[] blockId = getChildTag(schematic, "Blocks", ByteArrayTag.class).getValue();
data = getChildTag(schematic, "Data", ByteArrayTag.class).getValue();
byte[] addId = new byte[0];
blocks = new short[blockId.length]; // Have to later combine IDs
// We support 4096 block IDs using the same method as vanilla
// Minecraft, where
// the highest 4 bits are stored in a separate byte array.
if (schematic.containsKey("AddBlocks")) {
addId = getChildTag(schematic, "AddBlocks", ByteArrayTag.class).getValue();
}
// Combine the AddBlocks data with the first 8-bit block ID
for (int index = 0; index < blockId.length; index++) {
if ((index >> 1) >= addId.length) { // No corresponding
// AddBlocks index
blocks[index] = (short) (blockId[index] & 0xFF);
} else {
if ((index & 1) == 0) {
blocks[index] = (short) (((addId[index >> 1] & 0x0F) << 8) + (blockId[index] & 0xFF));
} else {
blocks[index] = (short) (((addId[index >> 1] & 0xF0) << 4) + (blockId[index] & 0xFF));
}
}
}
// Entities
List<Tag> entities = getChildTag(schematic, "Entities", ListTag.class).getValue();
for (Tag tag : entities) {
if (!(tag instanceof CompoundTag))
continue;
CompoundTag t = (CompoundTag) tag;
//Bukkit.getLogger().info("**************************************");
EntityObject ent = new EntityObject();
for (Map.Entry<String, Tag> entry : t.getValue().entrySet()) {
//Bukkit.getLogger().info("DEBUG " + entry.getKey() + ">>>>" + entry.getValue());
//Bukkit.getLogger().info("++++++++++++++++++++++++++++++++++++++++++++++++++");
if (entry.getKey().equals("id")) {
String id = ((StringTag)entry.getValue()).getValue().toUpperCase();
//Bukkit.getLogger().info("DEBUG: ID is '" + id + "'");
// The mob type might be prefixed with "Minecraft:"
if (id.startsWith("MINECRAFT:")) {
id = id.substring(10);
}
if (IslandBlock.WEtoME.containsKey(id)) {
//Bukkit.getLogger().info("DEBUG: id found");
ent.setType(IslandBlock.WEtoME.get(id));
} else if (!id.equalsIgnoreCase("ITEM")){
for (EntityType type : EntityType.values()) {
if (type.toString().equals(id)) {
ent.setType(type);
break;
}
}
}
}
if (entry.getKey().equals("Pos")) {
//Bukkit.getLogger().info("DEBUG Pos fond");
if (entry.getValue() instanceof ListTag) {
//Bukkit.getLogger().info("DEBUG coord found");
List<Tag> pos = new ArrayList<Tag>();
pos = ((ListTag) entry.getValue()).getValue();
//Bukkit.getLogger().info("DEBUG pos: " + pos);
double x = (double)pos.get(0).getValue() - origin.getX();
double y = (double)pos.get(1).getValue() - origin.getY();
double z = (double)pos.get(2).getValue() - origin.getZ();
ent.setLocation(new BlockVector(x,y,z));
}
} else if (entry.getKey().equals("Motion")) {
//Bukkit.getLogger().info("DEBUG Pos fond");
if (entry.getValue() instanceof ListTag) {
//Bukkit.getLogger().info("DEBUG coord found");
List<Tag> pos = new ArrayList<Tag>();
pos = ((ListTag) entry.getValue()).getValue();
//Bukkit.getLogger().info("DEBUG pos: " + pos);
ent.setMotion(new Vector((double)pos.get(0).getValue(), (double)pos.get(1).getValue()
,(double)pos.get(2).getValue()));
}
} else if (entry.getKey().equals("Rotation")) {
//Bukkit.getLogger().info("DEBUG Pos fond");
if (entry.getValue() instanceof ListTag) {
//Bukkit.getLogger().info("DEBUG coord found");
List<Tag> pos = new ArrayList<Tag>();
pos = ((ListTag) entry.getValue()).getValue();
//Bukkit.getLogger().info("DEBUG pos: " + pos);
ent.setYaw((float)pos.get(0).getValue());
ent.setPitch((float)pos.get(1).getValue());
}
} else if (entry.getKey().equals("Color")) {
if (entry.getValue() instanceof ByteTag) {
ent.setColor(((ByteTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("Sheared")) {
if (entry.getValue() instanceof ByteTag) {
if (((ByteTag) entry.getValue()).getValue() != (byte)0) {
ent.setSheared(true);
} else {
ent.setSheared(false);
}
}
} else if (entry.getKey().equals("RabbitType")) {
if (entry.getValue() instanceof IntTag) {
ent.setRabbitType(((IntTag)entry.getValue()).getValue());
}
} else if (entry.getKey().equals("Profession")) {
if (entry.getValue() instanceof IntTag) {
ent.setProfession(((IntTag)entry.getValue()).getValue());
}
} else if (entry.getKey().equals("CarryingChest")) {
if (entry.getValue() instanceof ByteTag) {
ent.setCarryingChest(((ByteTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("OwnerUUID")) {
ent.setOwned(true);
} else if (entry.getKey().equals("CollarColor")) {
if (entry.getValue() instanceof ByteTag) {
ent.setCollarColor(((ByteTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("Facing")) {
if (entry.getValue() instanceof ByteTag) {
ent.setFacing(((ByteTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("Motive")) {
if (entry.getValue() instanceof StringTag) {
ent.setMotive(((StringTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("ItemDropChance")) {
if (entry.getValue() instanceof FloatTag) {
ent.setItemDropChance(((FloatTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("ItemRotation")) {
if (entry.getValue() instanceof ByteTag){
ent.setItemRotation(((ByteTag) entry.getValue()).getValue());
}
} else if (entry.getKey().equals("Item")) {
if (entry.getValue() instanceof CompoundTag) {
CompoundTag itemTag = (CompoundTag) entry.getValue();
for (Map.Entry<String, Tag> itemEntry : itemTag.getValue().entrySet()) {
if (itemEntry.getKey().equals("Count")){
if (itemEntry.getValue() instanceof ByteTag){
ent.setCount(((ByteTag) itemEntry.getValue()).getValue());
}
} else if (itemEntry.getKey().equals("Damage")){
if (itemEntry.getValue() instanceof ShortTag){
ent.setDamage(((ShortTag) itemEntry.getValue()).getValue());
}
} else if (itemEntry.getKey().equals("id")){
if (itemEntry.getValue() instanceof StringTag){
ent.setId(((StringTag) itemEntry.getValue()).getValue());
}
}
}
}
} else if (entry.getKey().equals("TileX")){
if (entry.getValue() instanceof IntTag){
ent.setTileX((double)((IntTag)entry.getValue()).getValue() - origin.getX());
}
} else if (entry.getKey().equals("TileY")){
if (entry.getValue() instanceof IntTag){
ent.setTileY((double)((IntTag)entry.getValue()).getValue() - origin.getY());
}
} else if (entry.getKey().equals("TileZ")){
if (entry.getValue() instanceof IntTag){
ent.setTileZ((double)((IntTag)entry.getValue()).getValue() - origin.getZ());
}
}
}
if (ent.getType() != null) {
//Bukkit.getLogger().info("DEBUG: adding " + ent.getType().toString() + " at " + ent.getLocation().toString());
//entitiesMap.put(new BlockVector(x,y,z), mobType);
entitiesList.add(ent);
}
}
//Bukkit.getLogger().info("DEBUG: size of entities = " + entities.size());
// Tile entities
List<Tag> tileEntities = getChildTag(schematic, "TileEntities", ListTag.class).getValue();
// Map<BlockVector, Map<String, Tag>> tileEntitiesMap = new
// HashMap<BlockVector, Map<String, Tag>>();
for (Tag tag : tileEntities) {
if (!(tag instanceof CompoundTag))
continue;
CompoundTag t = (CompoundTag) tag;
int x = 0;
int y = 0;
int z = 0;
Map<String, Tag> values = new HashMap<String, Tag>();
for (Map.Entry<String, Tag> entry : t.getValue().entrySet()) {
if (entry.getKey().equals("x")) {
if (entry.getValue() instanceof IntTag) {
x = ((IntTag) entry.getValue()).getValue();
}
} else if (entry.getKey().equals("y")) {
if (entry.getValue() instanceof IntTag) {
y = ((IntTag) entry.getValue()).getValue();
}
} else if (entry.getKey().equals("z")) {
if (entry.getValue() instanceof IntTag) {
z = ((IntTag) entry.getValue()).getValue();
}
}
values.put(entry.getKey(), entry.getValue());
}
BlockVector vec = new BlockVector(x, y, z);
tileEntitiesMap.put(vec, values);
}
} catch (IOException e) {
Bukkit.getLogger().severe("Could not load island schematic! Error in file.");
e.printStackTrace();
throw new IOException();
}
// Check for key blocks
// Find top most bedrock - this is the key stone
// Find top most chest
// Find top most grass
List<Vector> grassBlocks = new ArrayList<Vector>();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
for (int z = 0; z < length; ++z) {
int index = y * width * length + z * width + x;
// Bukkit.getLogger().info("DEBUG " + index +
// " changing to ID:"+blocks[index] + " data = " +
// blockData[index]);
if (blocks[index] == 7) {
// Last bedrock
if (bedrock == null || bedrock.getY() < y) {
bedrock = new Vector(x, y, z);
//Bukkit.getLogger().info("DEBUG higher bedrock found:" + bedrock.toString());
}
} else if (blocks[index] == 54) {
// Last chest
if (chest == null || chest.getY() < y) {
chest = new Vector(x, y, z);
// Bukkit.getLogger().info("Island loc:" +
// loc.toString());
// Bukkit.getLogger().info("Chest relative location is "
// + chest.toString());
}
} else if (blocks[index] == 63) {
// Sign
if (welcomeSign == null || welcomeSign.getY() < y) {
welcomeSign = new Vector(x, y, z);
// Bukkit.getLogger().info("DEBUG higher sign found:"
// + welcomeSign.toString());
}
} else if (blocks[index] == 2) {
// Grass
grassBlocks.add(new Vector(x,y,z));
}
}
}
}
if (bedrock == null) {
Bukkit.getLogger().severe("Schematic must have at least one bedrock in it!");
throw new IOException();
}
// Find other key blocks
if (!grassBlocks.isEmpty()) {
// Sort by height
List<Vector> sorted = new ArrayList<Vector>();
for (Vector v : grassBlocks) {
//if (GridManager.isSafeLocation(v.toLocation(world))) {
// Add to sorted list
boolean inserted = false;
for (int i = 0; i < sorted.size(); i++) {
if (v.getBlockY() > sorted.get(i).getBlockY()) {
sorted.add(i, v);
inserted = true;
break;
}
}
if (!inserted) {
// just add to the end of the list
sorted.add(v);
}
}
topGrass = sorted.get(0);
} else {
topGrass = null;
}
// Preload the blocks
prePasteSchematic(blocks, data);
}
/**
* @return the biome
*/
public Biome getBiome() {
return biome;
}
/**
* @return the description
*/
public String getDescription() {
return description;
}
/**
* @return the file
*/
public File getFile() {
return file;
}
/**
* @return the heading
*/
public String getHeading() {
return heading;
}
/**
* @return the height
*/
public short getHeight() {
return height;
}
/**
* @return the icon
*/
public Material getIcon() {
return icon;
}
/**
* @return the durability of the icon
*/
public int getDurability() {
return durability;
}
/**
* @return the length
*/
public short getLength() {
return length;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the perm
*/
public String getPerm() {
return perm;
}
/**
* @return the rating
*/
public int getRating() {
return rating;
}
/**
* @return the tileEntitiesMap
*/
public Map<BlockVector, Map<String, Tag>> getTileEntitiesMap() {
return tileEntitiesMap;
}
/**
* @return the width
*/
public short getWidth() {
return width;
}
/**
* @return the useDefaultChest
*/
public boolean isUseDefaultChest() {
return useDefaultChest;
}
/**
* @return the usePhysics
*/
public boolean isUsePhysics() {
return usePhysics;
}
/*
* This function pastes using World Edit - problem is that because it reads a file, it's slow.
@SuppressWarnings("deprecation")
*/
/*
*
public void pasteSchematic(final Location loc, final Player player, boolean teleport) {
plugin.getLogger().info("WE Pasting");
com.sk89q.worldedit.Vector WEorigin = new com.sk89q.worldedit.Vector(loc.getBlockX(),loc.getBlockY(),loc.getBlockZ());
EditSession es = new EditSession(new BukkitWorld(loc.getWorld()), 999999999);
try {
CuboidClipboard cc = CuboidClipboard.loadSchematic(file);
cc.paste(es, WEorigin, false);
cc.pasteEntities(WEorigin);
} catch (Exception e) {
e.printStackTrace();
}
if (teleport) {
World world = loc.getWorld();
player.teleport(world.getSpawnLocation());
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
plugin.getGrid().homeTeleport(player);
}}, 10L);
}
}
*/
/**
* This method pastes a schematic.
* @param loc
* @param player
*/
public void pasteSchematic(final Location loc, final Player player, boolean teleport) {
// If this is not a file schematic, paste the default island
if (this.file == null) {
if (Settings.GAMETYPE == GameType.ACIDISLAND) {
generateIslandBlocks(loc,player);
} else {
loc.getBlock().setType(Material.BEDROCK);
ASkyBlock.getPlugin().getLogger().severe("Missing schematic - using bedrock block only");
}
return;
}
World world = loc.getWorld();
Location blockLoc = new Location(world, loc.getX(), loc.getY(), loc.getZ());
//Location blockLoc = new Location(world, loc.getX(), Settings.island_level, loc.getZ());
blockLoc.subtract(bedrock);
//plugin.getLogger().info("DEBUG: blockloc = " + blockLoc);
// Paste the island blocks
//plugin.getLogger().info("DEBUG: islandBlock size (paste) = " + islandBlocks.size());
for (IslandBlock b : islandBlocks) {
b.paste(nms, blockLoc, this.usePhysics, biome);
}
// PASTE ENTS
//Bukkit.getLogger().info("Block loc = " + blockLoc);
if (pasteEntities) {
for (EntityObject ent : entitiesList) {
// If TileX/Y/Z id defined, we have to use it (for Item Frame & Painting)
if(ent.getTileX() != null && ent.getTileY() != null && ent.getTileZ() != null){
ent.setLocation(new BlockVector(ent.getTileX(),ent.getTileY(),ent.getTileZ()));
}
Location entitySpot = ent.getLocation().toLocation(blockLoc.getWorld()).add(blockLoc.toVector());
entitySpot.setPitch(ent.getPitch());
entitySpot.setYaw(ent.getYaw());
//Bukkit.getLogger().info("DEBUG: Entity type = " + ent.getType());
if(ent.getType() == EntityType.PAINTING){
//Bukkit.getLogger().info("DEBUG: painting = " + ent.getMotive() + "; facing = " + ent.getFacing());
//Bukkit.getLogger().info("DEBUG: spawning " + ent.getType().toString() + " at " + entitySpot);
try {
Painting painting = blockLoc.getWorld().spawn(entitySpot, Painting.class);
if (painting != null) {
if(paintingList.containsKey(ent.getMotive())){
//painting.setArt(Art.GRAHAM);
painting.setArt(paintingList.get(ent.getMotive()), true);
} else {
// Set default
painting.setArt(Art.ALBAN, true);
}
// http://minecraft.gamepedia.com/Painting#Data_values
if(facingList.containsKey(ent.getFacing())){
painting.setFacingDirection(facingList.get(ent.getFacing()), true);
} else {
//set default direction
painting.setFacingDirection(BlockFace.NORTH, true);
}
//Bukkit.getLogger().info("DEBUG: Painting setFacingDirection: " + painting.getLocation().toString() + "; facing: " + painting.getFacing() + "; ent facing: " + ent.getFacing());
//Bukkit.getLogger().info("DEBUG: Painting setArt: " + painting.getLocation().toString() + "; art: " + painting.getArt() + "; ent motive: " + ent.getMotive());
}
} catch (IllegalArgumentException e) {
//plugin.getLogger().warning("Cannot paste painting from schematic");
}
} else if(ent.getType() == EntityType.ITEM_FRAME) {
//Bukkit.getLogger().info("DEBUG: spawning itemframe at" + entitySpot.toString());
//Bukkit.getLogger().info("DEBUG: tileX: " + ent.getTileX() + ", tileY: " + ent.getTileY() + ", tileZ: " + ent.getTileZ());
ItemFrame itemFrame = (ItemFrame) blockLoc.getWorld().spawnEntity(entitySpot, EntityType.ITEM_FRAME);
if (itemFrame != null) {
// Need to improve this shity fix ...
Material material = Material.matchMaterial(ent.getId().substring(10).toUpperCase());;
if(material == null && IslandBlock.WEtoM.containsKey(ent.getId().substring(10).toUpperCase())){
material = IslandBlock.WEtoM.get(ent.getId().substring(10).toUpperCase());
}
ItemStack item;
if(material != null){
//Bukkit.getLogger().info("DEBUG: id: " + ent.getId() + ", material match: " + material.toString());
if(ent.getCount() != null){
if(ent.getDamage() != null){
item = new ItemStack(material, ent.getCount(), ent.getDamage());
} else {
item = new ItemStack(material, ent.getCount(), (short) 0);
}
} else {
if(ent.getDamage() != null){
item = new ItemStack(material, 1, ent.getDamage());
} else {
item = new ItemStack(material, 1, (short) 0);
}
}
} else {
//Bukkit.getLogger().info("DEBUG: material can't be found for: " + ent.getId() + " (" + ent.getId().substring(10).toUpperCase() + ")");
// Set to default content
item = new ItemStack(Material.STONE, 0, (short) 4);
}
ItemMeta itemMeta = item.getItemMeta();
// TODO: Implement methods to get enchantement, names, lore etc.
item.setItemMeta(itemMeta);
itemFrame.setItem(item);
if(facingList.containsKey(ent.getFacing())){
itemFrame.setFacingDirection(facingList.get(ent.getFacing()), true);
} else {
//set default direction
itemFrame.setFacingDirection(BlockFace.NORTH, true);
}
// TODO: Implements code to handle the rotation of the item in the itemframe
if(rotationList.containsKey(ent.getItemRotation())){
itemFrame.setRotation(rotationList.get(ent.getItemRotation()));
} else {
// Set default direction
itemFrame.setRotation(Rotation.NONE);
}
}
} else {
//Bukkit.getLogger().info("Spawning " + ent.getType().toString() + " at " + entitySpot);
Entity spawned = blockLoc.getWorld().spawnEntity(entitySpot, ent.getType());
if (spawned != null) {
spawned.setVelocity(ent.getMotion());
if (ent.getType() == EntityType.SHEEP) {
Sheep sheep = (Sheep)spawned;
if (ent.isSheared()) {
sheep.setSheared(true);
}
DyeColor[] set = DyeColor.values();
sheep.setColor(set[ent.getColor()]);
sheep.setAge(ent.getAge());
} else if (ent.getType() == EntityType.HORSE) {
Horse horse = (Horse)spawned;
Horse.Color[] set = Horse.Color.values();
horse.setColor(set[ent.getColor()]);
horse.setAge(ent.getAge());
horse.setCarryingChest(ent.isCarryingChest());
} else if (ent.getType() == EntityType.VILLAGER) {
Villager villager = (Villager)spawned;
villager.setAge(ent.getAge());
Profession[] proffs = Profession.values();
villager.setProfession(proffs[ent.getProfession()]);
} else if (!Bukkit.getServer().getVersion().contains("(MC: 1.7") && ent.getType() == EntityType.RABBIT) {
Rabbit rabbit = (Rabbit)spawned;
Rabbit.Type[] set = Rabbit.Type.values();
rabbit.setRabbitType(set[ent.getRabbitType()]);
rabbit.setAge(ent.getAge());
} else if (ent.getType() == EntityType.OCELOT) {
Ocelot cat = (Ocelot)spawned;
if (ent.isOwned()) {
cat.setTamed(true);
cat.setOwner(player);
}
Ocelot.Type[] set = Ocelot.Type.values();
cat.setCatType(set[ent.getCatType()]);
cat.setAge(ent.getAge());
cat.setSitting(ent.isSitting());
} else if (ent.getType() == EntityType.WOLF) {
Wolf wolf = (Wolf)spawned;
if (ent.isOwned()) {
wolf.setTamed(true);
wolf.setOwner(player);
}
wolf.setAge(ent.getAge());
wolf.setSitting(ent.isSitting());
DyeColor[] color = DyeColor.values();
wolf.setCollarColor(color[ent.getCollarColor()]);
}
}
}
}
}
// Find the grass spot
final Location grass;
if (topGrass != null) {
Location gr = topGrass.clone().toLocation(loc.getWorld()).subtract(bedrock);
gr.add(loc.toVector());
gr.add(new Vector(0.5D,1.1D,0.5D)); // Center of block and a bit up so the animal drops a bit
grass = gr;
} else {
grass = null;
}
//Bukkit.getLogger().info("DEBUG cow location " + grass);
Block blockToChange = null;
// world.spawnEntity(grass, EntityType.COW);
// Place a helpful sign in front of player
if (welcomeSign != null) {
// Bukkit.getLogger().info("DEBUG welcome sign schematic relative is:"
// + welcomeSign.toString());
Vector ws = welcomeSign.clone().subtract(bedrock);
// Bukkit.getLogger().info("DEBUG welcome sign relative to bedrock is:"
// + welcomeSign.toString());
ws.add(loc.toVector());
// Bukkit.getLogger().info("DEBUG welcome sign actual position is:"
// + welcomeSign.toString());
blockToChange = ws.toLocation(world).getBlock();
BlockState signState = blockToChange.getState();
if (signState instanceof Sign) {
Sign sign = (Sign) signState;
if (sign.getLine(0).isEmpty()) {
sign.setLine(0, plugin.myLocale(player.getUniqueId()).signLine1.replace("[player]", player.getName()));
}
if (sign.getLine(1).isEmpty()) {
sign.setLine(1, plugin.myLocale(player.getUniqueId()).signLine2.replace("[player]", player.getName()));
}
if (sign.getLine(2).isEmpty()) {
sign.setLine(2, plugin.myLocale(player.getUniqueId()).signLine3.replace("[player]", player.getName()));
}
if (sign.getLine(3).isEmpty()) {
sign.setLine(3, plugin.myLocale(player.getUniqueId()).signLine4.replace("[player]", player.getName()));
}
// BlockFace direction = ((org.bukkit.material.Sign)
// sign.getData()).getFacing();
//((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH);
sign.update();
}
}
if (chest != null) {
Vector ch = chest.clone().subtract(bedrock);
ch.add(loc.toVector());
// Place the chest - no need to use the safe spawn function because we
// know what this island looks like
blockToChange = ch.toLocation(world).getBlock();
// Bukkit.getLogger().info("Chest block = " + blockToChange);
// blockToChange.setType(Material.CHEST);
// Bukkit.getLogger().info("Chest item settings = " +
// Settings.chestItems[0]);
// Bukkit.getLogger().info("Chest item settings length = " +
// Settings.chestItems.length);
if (useDefaultChest) {
// Fill the chest
if (blockToChange.getType() == Material.CHEST) {
final Chest islandChest = (Chest) blockToChange.getState();
DoubleChest doubleChest = null;
InventoryHolder iH = islandChest.getInventory().getHolder();
if (iH instanceof DoubleChest) {
//Bukkit.getLogger().info("DEBUG: double chest");
doubleChest = (DoubleChest) iH;
}
if (doubleChest != null) {
Inventory inventory = doubleChest.getInventory();
inventory.clear();
inventory.setContents(defaultChestItems);
} else {
Inventory inventory = islandChest.getInventory();
inventory.clear();
inventory.setContents(defaultChestItems);
}
}
}
}
if (teleport) {
plugin.getPlayers().setInTeleport(player.getUniqueId(), true);
//player.setInvulnerable(true);
// Check distance. If it's too close, warp to spawn to try to clear the client's cache
//plugin.getLogger().info("DEBUG: view dist = " + plugin.getServer().getViewDistance());
if (player.getWorld().equals(world)) {
//plugin.getLogger().info("DEBUG: same world");
int distSq = (int)((player.getLocation().distanceSquared(loc) - (Settings.islandDistance * Settings.islandDistance)/16));
//plugin.getLogger().info("DEBUG: distsq = " + distSq);
if (plugin.getServer().getViewDistance() * plugin.getServer().getViewDistance() < distSq) {
//plugin.getLogger().info("DEBUG: teleporting");
player.teleport(world.getSpawnLocation());
}
}
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
plugin.getGrid().homeTeleport(player);
plugin.getPlayers().setInTeleport(player.getUniqueId(), false);
// Reset any inventory, etc. This is done AFTER the teleport because other plugins may switch out inventory based on world
plugin.resetPlayer(player);
// Reset money if required
if (Settings.resetMoney) {
resetMoney(player);
}
// Show fancy titles!
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
if (!plugin.myLocale(player.getUniqueId()).islandSubTitle.isEmpty()) {
//plugin.getLogger().info("DEBUG: title " + player.getName() + " subtitle {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitle + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitleColor + "\"}");
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
"minecraft:title " + player.getName() + " subtitle {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitle.replace("[player]", player.getName()) + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitleColor + "\"}");
}
if (!plugin.myLocale(player.getUniqueId()).islandTitle.isEmpty()) {
//plugin.getLogger().info("DEBUG: title " + player.getName() + " title {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandTitle + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandTitleColor + "\"}");
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
"minecraft:title " + player.getName() + " title {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandTitle.replace("[player]", player.getName()) + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandTitleColor + "\"}");
}
if (!plugin.myLocale(player.getUniqueId()).islandDonate.isEmpty() && !plugin.myLocale(player.getUniqueId()).islandURL.isEmpty()) {
//plugin.getLogger().info("DEBUG: tellraw " + player.getName() + " {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandDonate + "\",\"color\":\"" + plugin.myLocale(player.getUniqueId()).islandDonateColor + "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\""
// + plugin.myLocale(player.getUniqueId()).islandURL + "\"}}");
plugin.getServer().dispatchCommand(
plugin.getServer().getConsoleSender(),
"minecraft:tellraw " + player.getName() + " {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandDonate.replace("[player]", player.getName()) + "\",\"color\":\"" + plugin.myLocale(player.getUniqueId()).islandDonateColor + "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\""
+ plugin.myLocale(player.getUniqueId()).islandURL + "\"}}");
}
}
if (!plugin.getPlayers().hasIsland(player.getUniqueId())) {
// Run any commands that need to be run at the start
//plugin.getLogger().info("DEBUG: First time");
if (!player.hasPermission(Settings.PERMPREFIX + "command.newislandexempt")) {
//plugin.getLogger().info("DEBUG: Executing new island commands");
IslandCmd.runCommands(Settings.startCommands, player);
}
}
}}, 10L);
}
if (!islandCompanion.isEmpty() && grass != null) {
Bukkit.getServer().getScheduler().runTaskLater(ASkyBlock.getPlugin(), new Runnable() {
@Override
public void run() {
spawnCompanion(player, grass);
}
}, 40L);
}
// Set the bedrock block meta data to the original spawn location
// Doesn't survive a server restart. TODO: change to add this info elsewhere.
/*
if (playerSpawn != null) {
blockToChange = loc.getBlock();
if (blockToChange.getType().equals(Material.BEDROCK)) {
String spawnLoc = Util.getStringLocation(loc.clone().add(playerSpawn).add(new Vector(0.5D,0D,0.5D)));
blockToChange.setMetadata("playerSpawn", new FixedMetadataValue(plugin, spawnLoc));
}
}
*/
}
/**
* This method prepares to pastes a schematic.
* @param blocks
* @param data
*/
@SuppressWarnings("deprecation")
public void prePasteSchematic(short[] blocks, byte[] data) {
//plugin.getLogger().info("DEBUG: prepaste ");
islandBlocks = new ArrayList<IslandBlock>();
Map<BlockVector, Map<String, Tag>> tileEntitiesMap = this.getTileEntitiesMap();
// Start with non-attached blocks
//plugin.getLogger().info("DEBUG: attachable size = " + attachable.size());
//plugin.getLogger().info("DEBUG: torch = " + Material.TORCH.getId());
//plugin.getLogger().info("DEBUG: non attachable");
//plugin.getLogger().info("DEBUG: bedrock y = " + bedrock.getBlockY());
//int count = 0;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
for (int z = 0; z < length; ++z) {
int index = y * width * length + z * width + x;
// Only bother if this block is above ground zero and
// only bother with air if it is below sea level
// TODO: need to check max world height too?
int h = Settings.islandHeight + y - bedrock.getBlockY();
if (h >= 0 && h < 255 && (blocks[index] != 0 || h < Settings.seaHeight)){
// Only bother if the schematic blocks are within the range that y can be
//plugin.getLogger().info("DEBUG: height " + (count++) + ":" +h);
IslandBlock block = new IslandBlock(x, y, z);
if (!attachable.contains((int)blocks[index]) || blocks[index] == 179) {
if (Bukkit.getServer().getVersion().contains("(MC: 1.7") && blocks[index] == 179) {
// Red sandstone - use red sand instead
block.setBlock(12, (byte)1);
} else {
block.setBlock(blocks[index], data[index]);
}
// Tile Entities
if (tileEntitiesMap.containsKey(new BlockVector(x, y, z))) {
if (plugin.isOnePointEight()) {
if (block.getTypeId() == Material.STANDING_BANNER.getId()) {
block.setBanner(tileEntitiesMap.get(new BlockVector(x, y, z)));
}
else if (block.getTypeId() == Material.SKULL.getId()) {
block.setSkull(tileEntitiesMap.get(new BlockVector(x, y, z)), block.getData());
}
else if (block.getTypeId() == Material.FLOWER_POT.getId()) {
block.setFlowerPot(tileEntitiesMap.get(new BlockVector(x, y, z)));
}
}
// Monster spawner blocks
if (block.getTypeId() == Material.MOB_SPAWNER.getId()) {
block.setSpawnerType(tileEntitiesMap.get(new BlockVector(x, y, z)));
} else if ((block.getTypeId() == Material.SIGN_POST.getId())) {
block.setSign(tileEntitiesMap.get(new BlockVector(x, y, z)));
} else if (block.getTypeId() == Material.CHEST.getId()) {
block.setChest(nms, tileEntitiesMap.get(new BlockVector(x, y, z)));
}
}
islandBlocks.add(block);
}
}
}
}
}
//plugin.getLogger().info("Attachable blocks");
// Second pass - just paste attachables and deal with chests etc.
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
for (int z = 0; z < length; ++z) {
int h = Settings.islandHeight + y - bedrock.getBlockY();
if (h >= 0 && h < 255){
int index = y * width * length + z * width + x;
IslandBlock block = new IslandBlock(x, y, z);
if (attachable.contains((int)blocks[index])) {
block.setBlock(blocks[index], data[index]);
// Tile Entities
if (tileEntitiesMap.containsKey(new BlockVector(x, y, z))) {
if (plugin.isOnePointEight()) {
if (block.getTypeId() == Material.WALL_BANNER.getId()) {
block.setBanner(tileEntitiesMap.get(new BlockVector(x, y, z)));
}
}
// Wall Sign
if (block.getTypeId() == Material.WALL_SIGN.getId()) {
block.setSign(tileEntitiesMap.get(new BlockVector(x, y, z)));
}
}
islandBlocks.add(block);
}
}
}
}
}
//plugin.getLogger().info("DEBUG: islandBlocks size = " + islandBlocks.size());
}
/**
* @param biome the biome to set
*/
public void setBiome(Biome biome) {
this.biome = biome;
}
/**
* @param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
/**
* @param heading the heading to set
*/
public void setHeading(String heading) {
this.heading = heading;
}
public void setIcon(Material icon, int damage) {
this.icon = icon;
this.durability = damage;
}
/**
* @param icon the icon to set
*/
public void setIcon(Material icon) {
this.icon = icon;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @param perm the perm to set
*/
public void setPerm(String perm) {
this.perm = perm;
}
/**
* @param rating the rating to set
*/
public void setRating(int rating) {
this.rating = rating;
}
/**
* @param useDefaultChest the useDefaultChest to set
*/
public void setUseDefaultChest(boolean useDefaultChest) {
this.useDefaultChest = useDefaultChest;
}
/**
* @param usePhysics the usePhysics to set
*/
public void setUsePhysics(boolean usePhysics) {
this.usePhysics = usePhysics;
}
/**
* Removes all the air blocks if they are not to be pasted.
* @param pasteAir the pasteAir to set
*/
public void setPasteAir(boolean pasteAir) {
if (!pasteAir) {
Iterator<IslandBlock> it = islandBlocks.iterator();
while (it.hasNext()) {
if (it.next().getTypeId() == 0) {
it.remove();
}
}
}
//plugin.getLogger().info("DEBUG: islandBlocks after removing air blocks = " + islandBlocks.size());
}
/**
* Creates the AcidIsland default island block by block
* @param islandLoc
* @param player
*/
@SuppressWarnings("deprecation")
public void generateIslandBlocks(final Location islandLoc, final Player player) {
// AcidIsland
// Build island layer by layer
// Start from the base
// half sandstone; half sand
int x = islandLoc.getBlockX();
int z = islandLoc.getBlockZ();
World world = islandLoc.getWorld();
int y = 0;
for (int x_space = x - 4; x_space <= x + 4; x_space++) {
for (int z_space = z - 4; z_space <= z + 4; z_space++) {
final Block b = world.getBlockAt(x_space, y, z_space);
b.setType(Material.BEDROCK);
b.setBiome(biome);
}
}
for (y = 1; y < Settings.islandHeight + 5; y++) {
for (int x_space = x - 4; x_space <= x + 4; x_space++) {
for (int z_space = z - 4; z_space <= z + 4; z_space++) {
final Block b = world.getBlockAt(x_space, y, z_space);
if (y < (Settings.islandHeight / 2)) {
b.setType(Material.SANDSTONE);
} else {
b.setType(Material.SAND);
b.setData((byte) 0);
}
}
}
}
// Then cut off the corners to make it round-ish
for (y = 0; y < Settings.islandHeight + 5; y++) {
for (int x_space = x - 4; x_space <= x + 4; x_space += 8) {
for (int z_space = z - 4; z_space <= z + 4; z_space += 8) {
final Block b = world.getBlockAt(x_space, y, z_space);
b.setType(Material.STATIONARY_WATER);
}
}
}
// Add some grass
for (y = Settings.islandHeight + 4; y < Settings.islandHeight + 5; y++) {
for (int x_space = x - 2; x_space <= x + 2; x_space++) {
for (int z_space = z - 2; z_space <= z + 2; z_space++) {
final Block blockToChange = world.getBlockAt(x_space, y, z_space);
blockToChange.setType(Material.GRASS);
}
}
}
// Place bedrock - MUST be there (ensures island are not
// overwritten
Block b = world.getBlockAt(x, Settings.islandHeight, z);
b.setType(Material.BEDROCK);
// Then add some more dirt in the classic shape
y = Settings.islandHeight + 3;
for (int x_space = x - 2; x_space <= x + 2; x_space++) {
for (int z_space = z - 2; z_space <= z + 2; z_space++) {
b = world.getBlockAt(x_space, y, z_space);
b.setType(Material.DIRT);
}
}
b = world.getBlockAt(x - 3, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x + 3, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z - 3);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z + 3);
b.setType(Material.DIRT);
y = Settings.islandHeight + 2;
for (int x_space = x - 1; x_space <= x + 1; x_space++) {
for (int z_space = z - 1; z_space <= z + 1; z_space++) {
b = world.getBlockAt(x_space, y, z_space);
b.setType(Material.DIRT);
}
}
b = world.getBlockAt(x - 2, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x + 2, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z - 2);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z + 2);
b.setType(Material.DIRT);
y = Settings.islandHeight + 1;
b = world.getBlockAt(x - 1, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x + 1, y, z);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z - 1);
b.setType(Material.DIRT);
b = world.getBlockAt(x, y, z + 1);
b.setType(Material.DIRT);
// Add island items
y = Settings.islandHeight;
// Add tree (natural)
final Location treeLoc = new Location(world, x, y + 5D, z);
world.generateTree(treeLoc, TreeType.ACACIA);
// Place the cow
final Location location = new Location(world, x, (Settings.islandHeight + 5), z - 2);
// Place a helpful sign in front of player
Block blockToChange = world.getBlockAt(x, Settings.islandHeight + 5, z + 3);
blockToChange.setType(Material.SIGN_POST);
Sign sign = (Sign) blockToChange.getState();
sign.setLine(0, ASkyBlock.getPlugin().myLocale(player.getUniqueId()).signLine1.replace("[player]", player.getName()));
sign.setLine(1, ASkyBlock.getPlugin().myLocale(player.getUniqueId()).signLine2.replace("[player]", player.getName()));
sign.setLine(2, ASkyBlock.getPlugin().myLocale(player.getUniqueId()).signLine3.replace("[player]", player.getName()));
sign.setLine(3, ASkyBlock.getPlugin().myLocale(player.getUniqueId()).signLine4.replace("[player]", player.getName()));
((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH);
sign.update();
// Place the chest - no need to use the safe spawn function
// because we
// know what this island looks like
blockToChange = world.getBlockAt(x, Settings.islandHeight + 5, z + 1);
blockToChange.setType(Material.CHEST);
// Only set if the config has items in it
if (Settings.chestItems.length > 0) {
final Chest chest = (Chest) blockToChange.getState();
final Inventory inventory = chest.getInventory();
inventory.clear();
inventory.setContents(Settings.chestItems);
chest.update();
}
// Fill the chest and orient it correctly (1.8 faces it north!
DirectionalContainer dc = (DirectionalContainer) blockToChange.getState().getData();
dc.setFacingDirection(BlockFace.SOUTH);
blockToChange.setData(dc.getData(), true);
// Teleport player
plugin.getGrid().homeTeleport(player);
// Reset any inventory, etc. This is done AFTER the teleport because other plugins may switch out inventory based on world
plugin.resetPlayer(player);
// Reset money if required
if (Settings.resetMoney) {
resetMoney(player);
}
// Show fancy titles!
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
if (!plugin.myLocale(player.getUniqueId()).islandSubTitle.isEmpty()) {
//plugin.getLogger().info("DEBUG: title " + player.getName() + " subtitle {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitle + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitleColor + "\"}");
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
"minecraft:title " + player.getName() + " subtitle {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitle.replace("[player]", player.getName()) + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandSubTitleColor + "\"}");
}
if (!plugin.myLocale(player.getUniqueId()).islandTitle.isEmpty()) {
//plugin.getLogger().info("DEBUG: title " + player.getName() + " title {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandTitle + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandTitleColor + "\"}");
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
"minecraft:title " + player.getName() + " title {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandTitle.replace("[player]", player.getName()) + "\", \"color\":\"" + plugin.myLocale(player.getUniqueId()).islandTitleColor + "\"}");
}
if (!plugin.myLocale(player.getUniqueId()).islandDonate.isEmpty() && !plugin.myLocale(player.getUniqueId()).islandURL.isEmpty()) {
//plugin.getLogger().info("DEBUG: tellraw " + player.getName() + " {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandDonate + "\",\"color\":\"" + plugin.myLocale(player.getUniqueId()).islandDonateColor + "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\""
// + plugin.myLocale(player.getUniqueId()).islandURL + "\"}}");
plugin.getServer().dispatchCommand(
plugin.getServer().getConsoleSender(),
"minecraft:tellraw " + player.getName() + " {\"text\":\"" + plugin.myLocale(player.getUniqueId()).islandDonate.replace("[player]", player.getName()) + "\",\"color\":\"" + plugin.myLocale(player.getUniqueId()).islandDonateColor + "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\""
+ plugin.myLocale(player.getUniqueId()).islandURL + "\"}}");
}
}
if (!plugin.getPlayers().hasIsland(player.getUniqueId())) {
// Run any commands that need to be run at the start
//plugin.getLogger().info("DEBUG: First time");
if (!player.hasPermission(Settings.PERMPREFIX + "command.newislandexempt")) {
//plugin.getLogger().info("DEBUG: Executing new island commands");
IslandCmd.runCommands(Settings.startCommands, player);
}
}
if (!islandCompanion.isEmpty()) {
Bukkit.getServer().getScheduler().runTaskLater(ASkyBlock.getPlugin(), new Runnable() {
@Override
public void run() {
spawnCompanion(player, location);
}
}, 40L);
}
}
/**
* Get child tag of a NBT structure.
*
* @param items
* The parent tag map
* @param key
* The name of the tag to get
* @param expected
* The expected type of the tag
* @return child tag casted to the expected type
*/
private static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) throws IllegalArgumentException {
if (!items.containsKey(key)) {
throw new IllegalArgumentException("Schematic file is missing a \"" + key + "\" tag");
}
Tag tag = items.get(key);
if (!expected.isInstance(tag)) {
throw new IllegalArgumentException(key + " tag is not of tag type " + expected.getName());
}
return expected.cast(tag);
}
/**
* Spawns a random companion for the player with a random name at the location given
* @param player
* @param location
*/
protected void spawnCompanion(Player player, Location location) {
// Older versions of the server require custom names to only apply to Living Entities
//Bukkit.getLogger().info("DEBUG: spawning compantion at " + location);
if (!islandCompanion.isEmpty() && location != null) {
Random rand = new Random();
int randomNum = rand.nextInt(islandCompanion.size());
EntityType type = islandCompanion.get(randomNum);
if (type != null) {
LivingEntity companion = (LivingEntity) location.getWorld().spawnEntity(location, type);
if (!companionNames.isEmpty()) {
randomNum = rand.nextInt(companionNames.size());
String name = companionNames.get(randomNum).replace("[player]", player.getName());
//plugin.getLogger().info("DEBUG: name is " + name);
companion.setCustomName(name);
companion.setCustomNameVisible(true);
}
}
}
}
/**
* @param islandCompanion the islandCompanion to set
*/
public void setIslandCompanion(List<EntityType> islandCompanion) {
this.islandCompanion = islandCompanion;
}
/**
* @param companionNames the companionNames to set
*/
public void setCompanionNames(List<String> companionNames) {
this.companionNames = companionNames;
}
/**
* @param defaultChestItems the defaultChestItems to set
*/
public void setDefaultChestItems(ItemStack[] defaultChestItems) {
this.defaultChestItems = defaultChestItems;
}
/**
* @return if Biome is HELL, this is true
*/
public boolean isInNether() {
if (biome == Biome.HELL) {
return true;
}
return false;
}
/**
* @return the partnerName
*/
public String getPartnerName() {
return partnerName;
}
/**
* @param partnerName the partnerName to set
*/
public void setPartnerName(String partnerName) {
this.partnerName = partnerName;
}
/**
* @return the pasteEntities
*/
public boolean isPasteEntities() {
return pasteEntities;
}
/**
* @param pasteEntities the pasteEntities to set
*/
public void setPasteEntities(boolean pasteEntities) {
this.pasteEntities = pasteEntities;
}
/**
* Whether the schematic is visible or not
* @return the visible
*/
public boolean isVisible() {
return visible;
}
/**
* Sets if the schematic can be seen in the schematics GUI or not by the player
* @param visible the visible to set
*/
public void setVisible(boolean visible) {
this.visible = visible;
}
/**
* @return the order
*/
public int getOrder() {
return order;
}
/**
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
/**
* @return true if player spawn exists in this schematic
*/
public boolean isPlayerSpawn() {
if (playerSpawn == null) {
return false;
}
return true;
}
/**
* @return the playerSpawn Location given a paste location
*/
public Location getPlayerSpawn(Location pasteLocation) {
return pasteLocation.clone().add(playerSpawn);
}
/**
* @param playerSpawnBlock the playerSpawnBlock to set
* @return true if block is found otherwise false
*/
@SuppressWarnings("deprecation")
public boolean setPlayerSpawnBlock(Material playerSpawnBlock) {
if (bedrock == null) {
return false;
}
playerSpawn = null;
// Run through the schematic and try and find the spawnBlock
for (IslandBlock islandBlock : islandBlocks) {
if (islandBlock.getTypeId() == playerSpawnBlock.getId()) {
playerSpawn = islandBlock.getVector().subtract(bedrock).add(new Vector(0.5D,0D,0.5D));
// Set the block to air
islandBlock.setTypeId((short)0);
return true;
}
}
return false;
}
/**
* @return the levelHandicap
*/
public int getLevelHandicap() {
return levelHandicap;
}
/**
* @param levelHandicap the levelHandicap to set
*/
public void setLevelHandicap(int levelHandicap) {
this.levelHandicap = levelHandicap;
}
/**
* Set the cost
* @param cost
*/
public void setCost(double cost) {
this.cost = cost;
}
/**
* @return the cost
*/
public double getCost() {
return cost;
}
private void resetMoney(Player player) {
if (!Settings.useEconomy) {
return;
}
// Set player's balance in acid island to the starting balance
try {
// plugin.getLogger().info("DEBUG: " + player.getName() + " " +
// Settings.general_worldName);
if (VaultHelper.econ == null) {
// plugin.getLogger().warning("DEBUG: econ is null!");
VaultHelper.setupEconomy();
}
Double playerBalance = VaultHelper.econ.getBalance(player, Settings.worldName);
// plugin.getLogger().info("DEBUG: playerbalance = " +
// playerBalance);
// Round the balance to 2 decimal places and slightly down to
// avoid issues when withdrawing the amount later
BigDecimal bd = new BigDecimal(playerBalance);
bd = bd.setScale(2, RoundingMode.HALF_DOWN);
playerBalance = bd.doubleValue();
// plugin.getLogger().info("DEBUG: playerbalance after rounding = "
// + playerBalance);
if (playerBalance != Settings.startingMoney) {
if (playerBalance > Settings.startingMoney) {
Double difference = playerBalance - Settings.startingMoney;
EconomyResponse response = VaultHelper.econ.withdrawPlayer(player, Settings.worldName, difference);
// plugin.getLogger().info("DEBUG: withdrawn");
if (response.transactionSuccess()) {
plugin.getLogger().info(
"FYI:" + player.getName() + " had " + VaultHelper.econ.format(playerBalance) + " when they typed /island and it was set to "
+ Settings.startingMoney);
} else {
plugin.getLogger().warning(
"Problem trying to withdraw " + playerBalance + " from " + player.getName() + "'s account when they typed /island!");
plugin.getLogger().warning("Error from economy was: " + response.errorMessage);
}
} else {
Double difference = Settings.startingMoney - playerBalance;
EconomyResponse response = VaultHelper.econ.depositPlayer(player, Settings.worldName, difference);
if (response.transactionSuccess()) {
plugin.getLogger().info(
"FYI:" + player.getName() + " had " + VaultHelper.econ.format(playerBalance) + " when they typed /island and it was set to "
+ Settings.startingMoney);
} else {
plugin.getLogger().warning(
"Problem trying to deposit " + playerBalance + " from " + player.getName() + "'s account when they typed /island!");
plugin.getLogger().warning("Error from economy was: " + response.errorMessage);
}
}
}
} catch (final Exception e) {
plugin.getLogger().severe("Error trying to zero " + player.getName() + "'s account when they typed /island!");
plugin.getLogger().severe(e.getMessage());
}
}
}