Added a new preliminary mapping + metadata framework.

The eventual goal is to add:

1. Support for mapping block, etc. names (minecraft:stone, etc.)
2. Proper support for entities in WorldEdit
3. Support for querying for metadata about a block, entity, etc.
4. Extent support to biomes, structures, and so on
This commit is contained in:
sk89q 2014-04-26 21:57:45 -07:00
parent 19c43a2834
commit 354d819872
16 changed files with 777 additions and 188 deletions

View File

@ -0,0 +1,61 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.Vectors;
import com.sk89q.worldedit.world.World;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/
final class BukkitAdapter {
private BukkitAdapter() {
}
/**
* Create a WorldEdit world from a Bukkit world.
*
* @param world the Bukkit world
* @return a WorldEdit world
*/
public static World adapt(org.bukkit.World world) {
checkNotNull(world);
return new BukkitWorld(world);
}
/**
* Create a WorldEdit location from a Bukkit location.
*
* @param location the Bukkit location
* @return a WorldEdit location
*/
public static Location adapt(org.bukkit.Location location) {
checkNotNull(location);
Vector position = BukkitUtil.toVector(location);
Vector direction = Vectors.fromEulerDeg(location.getYaw(), location.getPitch());
return new com.sk89q.worldedit.util.Location(adapt(location.getWorld()), position, direction);
}
}

View File

@ -0,0 +1,60 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.Tameable;
import com.sk89q.worldedit.internal.util.AbstractAdapter;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
/**
* An adapter to adapt a Bukkit entity into a WorldEdit one.
*/
class BukkitEntity extends AbstractAdapter<org.bukkit.entity.Entity> implements Entity {
/**
* Create a new instance.
*
* @param entity the entity
*/
BukkitEntity(org.bukkit.entity.Entity entity) {
super(entity);
}
@SuppressWarnings("unchecked")
<T> T getMetaData(Class<T> metaDataClass) {
if (metaDataClass == Tameable.class && getHandle() instanceof org.bukkit.entity.Tameable) {
return (T) new TameableAdapter((org.bukkit.entity.Tameable) getHandle());
} else {
return null;
}
}
@Override
public World getWorld() {
return BukkitAdapter.adapt(getHandle().getWorld());
}
@Override
public Location getLocation() {
return BukkitAdapter.adapt(getHandle().getLocation());
}
}

View File

@ -26,8 +26,11 @@ import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.blocks.ContainerBlock; import com.sk89q.worldedit.blocks.ContainerBlock;
import com.sk89q.worldedit.blocks.NoteBlock; import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.bukkit.entity.BukkitEntity; import com.sk89q.worldedit.bukkit.entity.BukkitEntity;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.mapping.NullResolver;
import com.sk89q.worldedit.world.mapping.Resolver;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.*; import org.bukkit.block.*;
@ -38,6 +41,7 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import javax.annotation.Nullable;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
@ -1248,4 +1252,37 @@ public class BukkitWorld extends LocalWorld {
return super.setBlock(pt, block, notifyAdjacent); return super.setBlock(pt, block, notifyAdjacent);
} }
@Override
public Resolver<BaseBlock> getBlockMapping() {
return new NullResolver<BaseBlock>();
}
@Override
public Resolver<BaseEntity> getEntityMapping() {
return new NullResolver<BaseEntity>();
}
@Nullable
@Override
public <T> T getMetaData(BaseBlock block, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(com.sk89q.worldedit.entity.Entity entity, Class<T> metaDataClass) {
if (entity instanceof com.sk89q.worldedit.bukkit.BukkitEntity) {
return ((com.sk89q.worldedit.bukkit.BukkitEntity) entity).getMetaData(metaDataClass);
}
return null;
}
@Nullable
@Override
public <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass) {
return null;
}
} }

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.entity.metadata.Tameable;
import com.sk89q.worldedit.internal.util.AbstractAdapter;
/**
* Adapts a Bukkit {@link org.bukkit.entity.Tameable} into a WorldEdit
* equivalent.
*/
public class TameableAdapter extends AbstractAdapter<org.bukkit.entity.Tameable> implements Tameable {
TameableAdapter(org.bukkit.entity.Tameable entity) {
super(entity);
}
@Override
public boolean isTamed() {
return getHandle().isTamed();
}
}

View File

@ -24,9 +24,12 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.mapping.NullResolver;
import com.sk89q.worldedit.world.mapping.Resolver;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityHanging; import net.minecraft.entity.EntityHanging;
@ -48,6 +51,7 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.ChunkProviderServer;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List; import java.util.List;
@ -469,6 +473,34 @@ public class ForgeWorld extends AbstractWorld {
} }
} }
@Override
public Resolver<BaseBlock> getBlockMapping() {
return new NullResolver<BaseBlock>();
}
@Override
public Resolver<BaseEntity> getEntityMapping() {
return new NullResolver<BaseEntity>();
}
@Nullable
@Override
public <T> T getMetaData(BaseBlock block, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(com.sk89q.worldedit.entity.Entity entity, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass) {
return null;
}
/** /**
* Thrown when the reference to the world is lost. * Thrown when the reference to the world is lost.
*/ */

View File

@ -19,10 +19,6 @@
package com.sk89q.worldedit.entity; package com.sk89q.worldedit.entity;
import com.sk89q.worldedit.PlayerDirection;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.WorldVectorFace;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -39,137 +35,6 @@ import com.sk89q.worldedit.world.World;
*/ */
public interface Entity { public interface Entity {
/**
* Find a position for the actor to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The actor will be teleported to
* that free position.
*
* @param searchPos search position
*/
void findFreePosition(WorldVector searchPos);
/**
* Set the actor on the ground.
*
* @param searchPos The location to start searching from
*/
void setOnGround(WorldVector searchPos);
/**
* Find a position for the player to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The player will be teleported to
* that free position.
*/
void findFreePosition();
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
boolean ascendLevel();
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
boolean descendLevel();
/**
* Ascend to the ceiling above.
*
* @param clearance How many blocks to leave above the player's head
* @return whether the player was moved
*/
boolean ascendToCeiling(int clearance);
/**
* Ascend to the ceiling above.
*
* @param clearance How many blocks to leave above the player's head
* @param alwaysGlass Always put glass under the player
* @return whether the player was moved
*/
boolean ascendToCeiling(int clearance, boolean alwaysGlass);
/**
* Just go up.
*
* @param distance How far up to teleport
* @return whether the player was moved
*/
boolean ascendUpwards(int distance);
/**
* Just go up.
*
* @param distance How far up to teleport
* @param alwaysGlass Always put glass under the player
* @return whether the player was moved
*/
boolean ascendUpwards(int distance, boolean alwaysGlass);
/**
* Make the player float in the given blocks.
*
* @param x The X coordinate of the block to float in
* @param y The Y coordinate of the block to float in
* @param z The Z coordinate of the block to float in
*/
void floatAt(int x, int y, int z, boolean alwaysGlass);
/**
* Get the point of the block that is being stood in.
*
* @return point
*/
WorldVector getBlockIn();
/**
* Get the point of the block that is being stood upon.
*
* @return point
*/
WorldVector getBlockOn();
/**
* Get the point of the block being looked at. May return null.
* Will return the farthest away air block if useLastBlock is true and no other block is found.
*
* @param range How far to checks for blocks
* @param useLastBlock Try to return the last valid air block found.
* @return point
*/
WorldVector getBlockTrace(int range, boolean useLastBlock);
WorldVectorFace getBlockTraceFace(int range, boolean useLastBlock);
/**
* Get the point of the block being looked at. May return null.
*
* @param range How far to checks for blocks
* @return point
*/
WorldVector getBlockTrace(int range);
/**
* Get the point of the block being looked at. May return null.
*
* @param range How far to checks for blocks
* @return point
*/
WorldVector getSolidBlockTrace(int range);
/**
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
*
* @return the direction
*/
PlayerDirection getCardinalDirection();
/** /**
* Get the location of this entity. * Get the location of this entity.
* *
@ -177,53 +42,6 @@ public interface Entity {
*/ */
Location getLocation(); Location getLocation();
/**
* Get the actor's position.
* </p>
* If the actor has no permission, then return a dummy location.
*
* @return the actor's position
*/
WorldVector getPosition();
/**
* Get the player's view pitch.
*
* @return pitch
*/
double getPitch();
/**
* Get the player's view yaw.
*
* @return yaw
*/
double getYaw();
/**
* Pass through the wall that you are looking at.
*
* @param range How far to checks for blocks
* @return whether the player was pass through
*/
boolean passThroughForwardWall(int range);
/**
* Move the player.
*
* @param pos Where to move them
* @param pitch The pitch (up/down) of the player's view
* @param yaw The yaw (left/right) of the player's view
*/
void setPosition(Vector pos, float pitch, float yaw);
/**
* Move the player.
*
* @param pos Where to move them
*/
void setPosition(Vector pos);
/** /**
* Get the world that this entity is on. * Get the world that this entity is on.
* *

View File

@ -19,8 +19,7 @@
package com.sk89q.worldedit.entity; package com.sk89q.worldedit.entity;
import com.sk89q.worldedit.PlayerDirection; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
@ -80,4 +79,182 @@ public interface Player extends Entity {
*/ */
boolean hasCreativeMode(); boolean hasCreativeMode();
/**
* Find a position for the actor to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The actor will be teleported to
* that free position.
*
* @param searchPos search position
*/
void findFreePosition(WorldVector searchPos);
/**
* Set the actor on the ground.
*
* @param searchPos The location to start searching from
*/
void setOnGround(WorldVector searchPos);
/**
* Find a position for the player to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The player will be teleported to
* that free position.
*/
void findFreePosition();
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
boolean ascendLevel();
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
boolean descendLevel();
/**
* Ascend to the ceiling above.
*
* @param clearance How many blocks to leave above the player's head
* @return whether the player was moved
*/
boolean ascendToCeiling(int clearance);
/**
* Ascend to the ceiling above.
*
* @param clearance How many blocks to leave above the player's head
* @param alwaysGlass Always put glass under the player
* @return whether the player was moved
*/
boolean ascendToCeiling(int clearance, boolean alwaysGlass);
/**
* Just go up.
*
* @param distance How far up to teleport
* @return whether the player was moved
*/
boolean ascendUpwards(int distance);
/**
* Just go up.
*
* @param distance How far up to teleport
* @param alwaysGlass Always put glass under the player
* @return whether the player was moved
*/
boolean ascendUpwards(int distance, boolean alwaysGlass);
/**
* Make the player float in the given blocks.
*
* @param x The X coordinate of the block to float in
* @param y The Y coordinate of the block to float in
* @param z The Z coordinate of the block to float in
*/
void floatAt(int x, int y, int z, boolean alwaysGlass);
/**
* Get the point of the block that is being stood in.
*
* @return point
*/
WorldVector getBlockIn();
/**
* Get the point of the block that is being stood upon.
*
* @return point
*/
WorldVector getBlockOn();
/**
* Get the point of the block being looked at. May return null.
* Will return the farthest away air block if useLastBlock is true and no other block is found.
*
* @param range How far to checks for blocks
* @param useLastBlock Try to return the last valid air block found.
* @return point
*/
WorldVector getBlockTrace(int range, boolean useLastBlock);
WorldVectorFace getBlockTraceFace(int range, boolean useLastBlock);
/**
* Get the point of the block being looked at. May return null.
*
* @param range How far to checks for blocks
* @return point
*/
WorldVector getBlockTrace(int range);
/**
* Get the point of the block being looked at. May return null.
*
* @param range How far to checks for blocks
* @return point
*/
WorldVector getSolidBlockTrace(int range);
/**
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
*
* @return the direction
*/
PlayerDirection getCardinalDirection();
/**
* Get the actor's position.
* </p>
* If the actor has no permission, then return a dummy location.
*
* @return the actor's position
*/
WorldVector getPosition();
/**
* Get the player's view pitch.
*
* @return pitch
*/
double getPitch();
/**
* Get the player's view yaw.
*
* @return yaw
*/
double getYaw();
/**
* Pass through the wall that you are looking at.
*
* @param range How far to checks for blocks
* @return whether the player was pass through
*/
boolean passThroughForwardWall(int range);
/**
* Move the player.
*
* @param pos Where to move them
* @param pitch The pitch (up/down) of the player's view
* @param yaw The yaw (left/right) of the player's view
*/
void setPosition(Vector pos, float pitch, float yaw);
/**
* Move the player.
*
* @param pos Where to move them
*/
void setPosition(Vector pos);
} }

View File

@ -0,0 +1,34 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.entity.metadata;
/**
* Indicates a creature that can be tamed.
*/
public interface Tameable {
/**
* Returns whether the creature is tamed.
*
* @return true if the creature is tamed
*/
boolean isTamed();
}

View File

@ -22,11 +22,14 @@ package com.sk89q.worldedit.internal;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.mapping.Resolver;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -308,6 +311,33 @@ public class LocalWorldAdapter extends LocalWorld {
public Operation commit() { public Operation commit() {
return world.commit(); return world.commit();
} }
@Override
public Resolver<BaseBlock> getBlockMapping() {
return world.getBlockMapping();
}
@Override
public Resolver<BaseEntity> getEntityMapping() {
return world.getEntityMapping();
}
@Override
@Nullable
public <T> T getMetaData(BaseBlock block, Class<T> metaDataClass) {
return world.getMetaData(block, metaDataClass);
}
@Override
@Nullable
public <T> T getMetaData(Entity entity, Class<T> metaDataClass) {
return world.getMetaData(entity, metaDataClass);
}
@Override
@Nullable
public <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass) {
return world.getMetaData(entity, metaDataClass);
}
public static LocalWorldAdapter wrap(World world) { public static LocalWorldAdapter wrap(World world) {
return new LocalWorldAdapter(world); return new LocalWorldAdapter(world);

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.util;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstract class for adapters.
*
* @param <E> class of adapted objects
*/
public abstract class AbstractAdapter<E> {
private final E object;
/**
* Create a new instance.
*
* @param object the object to adapt
*/
public AbstractAdapter(E object) {
checkNotNull(object);
this.object = object;
}
/**
* Get the object.
*
* @return the object
*/
public E getHandle() {
return object;
}
}

View File

@ -22,7 +22,7 @@ package com.sk89q.worldedit.util;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.LocalWorldAdapter;
/** /**
@ -62,7 +62,7 @@ public class TargetBlock {
* @param checkDistance how often to check for blocks, the smaller the more precise * @param checkDistance how often to check for blocks, the smaller the more precise
*/ */
public TargetBlock(LocalPlayer player, int maxDistance, double checkDistance) { public TargetBlock(LocalPlayer player, int maxDistance, double checkDistance) {
this((Entity) player, maxDistance, checkDistance); this((Player) player, maxDistance, checkDistance);
} }
/** /**
@ -72,7 +72,7 @@ public class TargetBlock {
* @param maxDistance how far it checks for blocks * @param maxDistance how far it checks for blocks
* @param checkDistance how often to check for blocks, the smaller the more precise * @param checkDistance how often to check for blocks, the smaller the more precise
*/ */
public TargetBlock(Entity player, int maxDistance, double checkDistance) { public TargetBlock(Player player, int maxDistance, double checkDistance) {
this.world = LocalWorldAdapter.wrap(player.getWorld()); this.world = LocalWorldAdapter.wrap(player.getWorld());
this.setValues(player.getPosition(), player.getYaw(), player.getPitch(), this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
maxDistance, 1.65, checkDistance); maxDistance, 1.65, checkDistance);

View File

@ -23,8 +23,14 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.mapping.NullResolver;
import com.sk89q.worldedit.world.mapping.Resolver;
import javax.annotation.Nullable;
/** /**
* A null implementation of {@link World} that drops all changes and * A null implementation of {@link World} that drops all changes and
@ -95,4 +101,31 @@ public class NullWorld extends AbstractWorld {
return new BaseBlock(BlockID.AIR); return new BaseBlock(BlockID.AIR);
} }
@Override
public Resolver<BaseBlock> getBlockMapping() {
return new NullResolver<BaseBlock>();
}
@Override
public Resolver<BaseEntity> getEntityMapping() {
return new NullResolver<BaseEntity>();
}
@Nullable
@Override
public <T> T getMetaData(BaseBlock block, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(Entity entity, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass) {
return null;
}
} }

View File

@ -27,11 +27,12 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.mapping.Mapping;
/** /**
* Represents a world (dimension). * Represents a world (dimension).
*/ */
public interface World extends Extent { public interface World extends Extent, Mapping {
/** /**
* Get the name of the world. * Get the name of the world.

View File

@ -0,0 +1,114 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.mapping;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.Tameable;
import javax.annotation.Nullable;
/**
* A mapping can create state objects (such as {@link BaseBlock})
* from implementation-independent identifiers (such as "minecraft.stone"),
* as well as perform the opposite task of retrieving
* the identifier for a given state object (whenever possible at least, because
* a mapping may not be compatible with a set of state objects that may have
* come from another implementation). In addition, a mapping may be able to
* retrieve a variety of metadata objects (such as {@link Tameable}) to
* describe a given state object.
* </p>
* However, it may be possible that a mapping be "dumb" and not be able to,
* for example, return a {@link Tameable} for a "Horse" entity, simply because
* it has not be implemented. Any code that queries a mapping must be
* aware of this and act accordingly.
*/
public interface Mapping {
/**
* Get the mapping for block identifiers.
*
* @return a block mapping
*/
Resolver<BaseBlock> getBlockMapping();
/**
* Get the mapping for entity identifiers.
*
* @return an entity mapping
*/
Resolver<BaseEntity> getEntityMapping();
/**
* Attempt to return an instance of the given class for the given block.
* For example, {@code getMetaData(block, Inventory.class)} might return
* an instance if the block happens to contain an inventory.
* </p>
* If the given block is not of the given class (i.e. a dirt block does
* not have an inventory) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the block.
*
* @param block the block
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(BaseBlock block, Class<T> metaDataClass);
/**
* Attempt to return an instance of the given class for the given entity.
* For example, {@code getMetaData(entity, Creature.class)} might return
* an instance if the entity happens to be a creature.
* </p>
* If the given entity is not of the given class (i.e. a painting is
* not a creature) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the entity.
*
* @param entity the entity
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(Entity entity, Class<T> metaDataClass);
/**
* Attempt to return an instance of the given class for the given entity.
* For example, {@code getMetaData(entity, Creature.class)} might return
* an instance if the entity happens to be a creature.
* </p>
* If the given entity is not of the given class (i.e. a painting is
* not a creature) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the entity.
*
* @param entity the entity
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass);
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.mapping;
import javax.annotation.Nullable;
/**
* An implementation of a {@link Resolver} that knows nothing and returns
* {@code null} in all cases.
*
* @param <E> the object to resolve
*/
public class NullResolver<E> implements Resolver<E> {
@Nullable
@Override
public E create(String id) {
return null;
}
@Nullable
@Override
public String getId(E object) {
return null;
}
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.mapping;
import com.sk89q.worldedit.blocks.BaseBlock;
import javax.annotation.Nullable;
/**
* A resolver can create state objects (such as {@link BaseBlock}) from
* universal identifiers, but also get the universal identifier for
* a given state object (at least when it is known).
* </p>
* Identifiers may be case-sensitive. Routines that work with IDs should
* not make changes to the casing of the IDs or perform case-insensitive
* comparisons. Implementations may normalize the casing of IDs if it
* is appropriate.
*
* @param <E> the type of state object
*/
public interface Resolver<E> {
/**
* Create an instance of the state object from the given ID.
*
* @param id the ID
* @return an instance, otherwise null if an instance cannot be created
*/
@Nullable E create(String id);
/**
* Get the ID for the given object.
*
* @param object the object
* @return the ID, otherwise null if it is not known
*/
@Nullable String getId(E object);
}