package com.sijobe.spc.worldedit; import com.sijobe.spc.wrapper.Coordinate; import com.sijobe.spc.wrapper.World; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EntityType; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.regions.Region; // q3 code ;) import java.util.List; import net.minecraft.server.MinecraftServer; import net.minecraft.src.AxisAlignedBB; import net.minecraft.src.DamageSource; import net.minecraft.src.Entity; import net.minecraft.src.EntityAnimal; import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityMob; import net.minecraft.src.EntityPig; import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayerMP; import net.minecraft.src.EntityTameable; import net.minecraft.src.EntityVillager; import net.minecraft.src.BiomeGenBase; import net.minecraft.src.Chunk; /** * Implements the WorldEdit local world class that provides necessary methods * required to edit the world. * * TODO: (can this still happen?) * java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) at java.util.AbstractList$Itr.next(AbstractList.java:343) at net.minecraft.src.PlayerManager.func_72693_b(PlayerManager.java:49) at net.minecraft.src.WorldServer.tick(WorldServer.java:123) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:613) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:555) at net.minecraft.src.IntegratedServer.tick(IntegratedServer.java:121) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:464) at net.minecraft.src.ThreadServerApplication.run(ThreadServerApplication.java:17) * * @author simo_415 * @version 1.2 */ public class LocalWorld extends com.sk89q.worldedit.LocalWorld { /** * The world instance that the editing is carried out on */ private World world; /** * Default constructor allows the world to be specified * * @param world - The world that the editing should be done on */ public LocalWorld(World world) { this.world = world; } @Override public boolean clearContainerBlockContents(Vector pos) { return world.emptyContainer(getCoordinate(pos)); } @Override public boolean copyFromWorld(Vector pos, BaseBlock type) { // TODO Auto-generated method stub return false; } @Override public boolean copyToWorld(Vector pos, BaseBlock type) { // TODO Auto-generated method stub return false; } @Override public void dropItem(Vector pos, BaseItemStack item) { // TODO Auto-generated method stub } @Override public boolean equals(Object world) { if (world instanceof LocalWorld) { return ((LocalWorld)world).getName().equals(getName()); } return false; } @Override public BiomeType getBiome(Vector2D arg0) { BiomeGenBase biome = this.world.getMinecraftWorld().getBiomeGenForCoords(arg0.getBlockX(), arg0.getBlockZ()); // world.getWorldChunkManager().getBiomeGenAt try { return MinecraftBiomeType.valueOf(biome.biomeName.toUpperCase(java.util.Locale.ENGLISH)); // name } catch(IllegalArgumentException e) { // e.printStackTrace(); return BiomeType.UNKNOWN; } } /** * TODO: Implements a custom block tile entity if required * @see https://github.com/sk89q/worldedit/blob/master/src/main/java/com/sk89q/worldedit/bukkit/NmsBlock.java * @see https://github.com/sk89q/worldedit/blob/master/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java#L962 * * @see com.sk89q.worldedit.LocalWorld#getBlock(com.sk89q.worldedit.Vector) */ @Override public BaseBlock getBlock(Vector pos) { try { return new BaseBlock(getBlockType(pos), getBlockData(pos)); } catch (Exception e) { return null; } } @Override public boolean isValidBlockType(int type) { if (type == 0) { return true; } return world.isValidBlockType(type); } @Override public int getBlockData(Vector pos) { return world.getBlockData(getCoordinate(pos)); } @Override public int getBlockLightLevel(Vector pos) { return world.getBlockLightLevel(getCoordinate(pos)); } @Override public int getBlockType(Vector pos) { return world.getBlockId(getCoordinate(pos)); } @Override public String getName() { return world.getName(); } @Override public int hashCode() { return world.getName().hashCode(); } @Override public boolean regenerate(Region arg0, EditSession arg1) { // TODO Auto-generated method stub return false; } @Override public int removeEntities(EntityType entity, Vector pos, int area) { // TODO Auto-generated method stub return 0; } @Override public void setBiome(Vector2D arg0, BiomeType arg1) { if(arg1 instanceof MinecraftBiomeType) { int biomeId = ((MinecraftBiomeType) arg1).getBiomeID(); int x = arg0.getBlockX(); int z = arg0.getBlockZ(); if(this.world.getMinecraftWorld().blockExists(x, 0, z)) { // blockExists Chunk chunk = this.world.getMinecraftWorld().getChunkFromBlockCoords(x, z); // Chunk, getChunkFromBlockCoords if(chunk != null) { byte[] biomevals = chunk.getBiomeArray(); // getBiomeArray biomevals[((z & 0xF) << 4 | x & 0xF)] = (byte)biomeId; // work around for biome data not being updated on client com.sijobe.spc.wrapper.Minecraft.getMinecraft().thePlayer.worldObj.getChunkFromBlockCoords(x, z).setBiomeArray(biomevals); } else { System.err.println("Can't set biome for null chunk."); } } else { System.err.println("Not setting biome."); } } } @Override @Deprecated public void setBlockData(Vector pos, int block) { world.setBlockData(getCoordinate(pos), block); } @Override @Deprecated public void setBlockDataFast(Vector pos, int block) { world.setBlockData(getCoordinate(pos), block); } @Override @Deprecated public boolean setBlockType(Vector pos, int block) { return world.setBlock(getCoordinate(pos), block); } @Override @Deprecated public boolean generateBigTree(EditSession session, Vector pos) { return world.generateBigTree(getCoordinate(pos)); } @Override @Deprecated public boolean generateTree(EditSession session, Vector pos) { return world.generateTree(getCoordinate(pos)); } @Override @Deprecated public boolean generateTallRedwoodTree(EditSession session, Vector pos) { return world.generateTallRedwoodTree(getCoordinate(pos)); } @Override @Deprecated public boolean generateRedwoodTree(EditSession session, Vector pos) { return world.generateRedwoodTree(getCoordinate(pos)); } @Override @Deprecated public boolean generateBirchTree(EditSession session, Vector pos) { return world.generateBirchTree(getCoordinate(pos)); } @SuppressWarnings("unchecked") public int killMobsDo(Vector pos, double radius, boolean withLightning, boolean killAnimals, boolean killNPCs, boolean killPets) { List<Entity> entities = this.world.getMinecraftWorld().getEntitiesWithinAABBExcludingEntity(null, AxisAlignedBB.getBoundingBox(pos.getX() - (double)radius, pos.getY() - (double)radius, pos.getZ() - (double)radius, pos.getX() + (double)radius, pos.getY() + (double)radius, pos.getZ() + (double)radius)); int count = 0; EntityPlayerMP owner; try { String firstPlayer = MinecraftServer.getServer().getServerOwner(); owner = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(firstPlayer); } catch (Exception e) { owner = null; e.printStackTrace(); } for(Entity entity : entities) { if(entity instanceof EntityLiving) { if(entity instanceof EntityPlayer) { continue; // don't 'kill' players (it causes issues..) } if(!killAnimals && entity instanceof EntityAnimal) { continue; } if(!killNPCs && entity instanceof EntityVillager) { continue; } if(!killPets && entity instanceof EntityTameable) { continue; } boolean isPig = entity instanceof EntityPig; Coordinate entityPos = new Coordinate(entity.posX, entity.posY, entity.posZ); if(withLightning && !isPig) { world.useLightning(entityPos); } ((EntityLiving)entity).setEntityHealth(0); if(owner != null) { owner.destroyedItemsNetCache.add(entity.entityId); } count++; } } return count; } @Override public int killMobs(Vector origin, double radius, int flags) { boolean killPets = (flags & 0x1) != 0; boolean killNPCs = (flags & 0x2) != 0; boolean killAnimals = (flags & 0x4) != 0; boolean withLightning = (flags & 0x100000) != 0; return killMobsDo(origin, radius, withLightning, killAnimals, killNPCs, killPets); } /** * Gets the coordinate object that the specified Vector object represents * * @param pos - The position of the coordinate * @return The matching coordinate object */ private Coordinate getCoordinate(Vector pos) { return new Coordinate(pos.getX(), pos.getY(), pos.getZ()); } }