Updated for SpoutAPI changes

Make SpoutAPI not horribly slow
This commit is contained in:
zml2008 2012-10-17 07:50:49 -07:00
parent b4ac721a16
commit a690d5782f
8 changed files with 184 additions and 106 deletions

View File

@ -108,7 +108,7 @@
<dependency>
<groupId>org.spout</groupId>
<artifactId>vanilla</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.2-SNAPSHOT</version>
<optional>true</optional>
</dependency>
</dependencies>

View File

@ -24,7 +24,7 @@ import com.sk89q.worldedit.util.YAMLConfiguration;
import java.io.File;
/**
* @author zml2008
* Subclass of {@link YAMLConfiguration} with spout-specific data folder
*/
public class SpoutConfiguration extends YAMLConfiguration {
private final WorldEditPlugin plugin;

View File

@ -18,24 +18,33 @@
package com.sk89q.worldedit.spout;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.LocalEntity;
import com.sk89q.worldedit.Location;
import org.spout.api.entity.Controller;
import org.spout.api.component.Component;
import org.spout.api.datatable.ManagedHashMap;
import org.spout.api.entity.Entity;
import org.spout.api.entity.controller.type.ControllerType;
import org.spout.api.geo.LoadOption;
import org.spout.api.geo.World;
import org.spout.api.geo.discrete.Point;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
/**
* @author zml2008
*/
public class SpoutEntity extends LocalEntity {
private final ControllerType type;
private final byte[] datatableBytes;
private final List<Class<? extends Component>> components;
private final int entityId;
public SpoutEntity(Location position, int id, Controller controller) {
public SpoutEntity(Location position, int id, Collection<Class<? extends Component>> components, ManagedHashMap datatable) {
super(position);
type = controller.getType();
this.components = Lists.newArrayList(components);
this.datatableBytes = datatable.serialize();
this.entityId = id;
}
@ -47,16 +56,26 @@ public class SpoutEntity extends LocalEntity {
public boolean spawn(Location loc) {
World world = ((SpoutWorld) loc.getWorld()).getWorld();
Point pos = SpoutUtil.toPoint(world, loc.getPosition());
Controller controller = type.createController();
if (controller == null) {
Class<? extends Component> mainComponent = null;
if (components.size() > 0) {
mainComponent = components.get(0);
}
if (mainComponent == null) {
return false;
}
Entity e = world.createAndSpawnEntity(pos, controller);
Entity e = world.createAndSpawnEntity(pos, mainComponent, LoadOption.LOAD_ONLY); // Blocks should already be pasted by time entitieos are brought in
if (e != null) {
e.setPitch(loc.getPitch());
e.setYaw(loc.getYaw());
// TODO: Copy datatable info
e.getTransform().setPitch(loc.getPitch());
e.getTransform().setYaw(loc.getYaw());
for (Class<? extends Component> clazz : Iterables.skip(components, 1)) {
e.add(clazz);
}
try {
e.getData().deserialize(datatableBytes, true);
} catch (IOException e1) {
return false;
}
return true;
}
return false;

View File

@ -31,13 +31,15 @@ import com.sk89q.worldedit.cui.CUIEvent;
import org.spout.api.Client;
import org.spout.api.chat.style.ChatStyle;
import org.spout.api.entity.Controller;
import org.spout.api.component.components.TransformComponent;
import org.spout.api.geo.discrete.Point;
import org.spout.api.inventory.Inventory;
import org.spout.api.inventory.ItemStack;
import org.spout.api.entity.Player;
import org.spout.vanilla.component.inventory.window.Window;
import org.spout.vanilla.component.living.Human;
import org.spout.vanilla.material.VanillaMaterial;
import org.spout.vanilla.material.VanillaMaterials;
import org.spout.vanilla.entity.VanillaPlayerController;
public class SpoutPlayer extends LocalPlayer {
private Player player;
@ -52,10 +54,9 @@ public class SpoutPlayer extends LocalPlayer {
@Override
public int getItemInHand() {
Controller controller = player.getController();
if (controller instanceof VanillaPlayerController) {
ItemStack itemStack = ((VanillaPlayerController) controller).getInventory().getQuickbar().getCurrentItem();
return itemStack != null ? ((VanillaMaterial) itemStack.getMaterial()).getMinecraftId() : 0;
if (player.has(Human.class)) {
return ((VanillaMaterial) player.get(Human.class).getInventory().getQuickbar()
.getCurrentItem().getMaterial()).getMinecraftId();
} else {
return 0;
}
@ -68,27 +69,25 @@ public class SpoutPlayer extends LocalPlayer {
@Override
public WorldVector getPosition() {
Point loc = player.getPosition();
Point loc = player.getTransform().getPosition();
return new WorldVector(SpoutUtil.getLocalWorld(loc.getWorld()),
loc.getX(), loc.getY(), loc.getZ());
}
@Override
public double getPitch() {
return player.getPitch();
return player.getTransform().getPitch();
}
@Override
public double getYaw() {
return player.getYaw();
return player.getTransform().getYaw();
}
@Override
public void giveItem(int type, int amt) {
Controller controller = player.getController();
if (controller instanceof VanillaPlayerController) {
((VanillaPlayerController) controller).getInventory()
.addItem(new ItemStack(VanillaMaterials.getMaterial((short) type), amt));
if (player.has(Human.class)) {
player.get(Human.class).getInventory().add(new ItemStack(VanillaMaterials.getMaterial((short) type), amt));
}
}
@ -122,10 +121,10 @@ public class SpoutPlayer extends LocalPlayer {
@Override
public void setPosition(Vector pos, float pitch, float yaw) {
player.setPosition(SpoutUtil.toPoint(player.getWorld(), pos));
player.setPitch(pitch);
player.setYaw(yaw);
player.getNetworkSynchronizer().setPositionDirty();
TransformComponent component = player.getTransform();
player.teleport(SpoutUtil.toPoint(player.getWorld(), pos));
component.setPitch(pitch);
component.setYaw(yaw);
}
@Override

View File

@ -29,10 +29,12 @@ import com.sk89q.worldedit.bags.OutOfSpaceException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockID;
import org.spout.api.inventory.InventoryBase;
import org.spout.api.inventory.Inventory;
import org.spout.api.inventory.ItemStack;
import org.spout.api.material.Material;
import org.spout.api.entity.Player;
import org.spout.vanilla.component.inventory.PlayerInventory;
import org.spout.vanilla.component.living.Human;
import org.spout.vanilla.material.VanillaMaterials;
import org.spout.vanilla.util.VanillaPlayerUtil;
@ -44,7 +46,17 @@ public class SpoutPlayerBlockBag extends BlockBag {
/**
* The player's inventory;
*/
private ItemStack[] items;
private ItemInfo items;
private static class ItemInfo {
ItemStack[] inventory;
boolean includesFullInventory;
public ItemInfo(ItemStack[] inventory, boolean full) {
this.inventory = inventory;
this.includesFullInventory = full;
}
}
/**
* Construct the object.
@ -60,10 +72,34 @@ public class SpoutPlayerBlockBag extends BlockBag {
*/
private void loadInventory() {
if (items == null) {
items = VanillaPlayerUtil.getInventory(player).getContents();
items = getViewableItems(player);
}
}
private ItemInfo getViewableItems(Player player) {
boolean includesFullInventory = true;
ItemStack[] items;
Human human = player.get(Human.class);
PlayerInventory inv = human.getInventory();
if (human.isCreative()) {
includesFullInventory = false;
items = new ItemStack[inv.getQuickbar().size()];
} else {
items = new ItemStack[inv.getQuickbar().size() + inv.getMain().size()];
}
int index = 0;
for (; index < inv.getQuickbar().size(); ++index) {
items[index] = inv.getQuickbar().get(index);
}
if (!human.isCreative()) {
for (int i = 0; i < inv.getMain().size() && index < items.length; ++i) {
items[index++] = inv.getMain().get(i);
}
}
return new ItemInfo(items, includesFullInventory);
}
/**
* Get the player.
*
@ -84,12 +120,9 @@ public class SpoutPlayerBlockBag extends BlockBag {
final short damage = item.getData();
int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
assert(amount == 1);
Material mat = VanillaMaterials.getMaterial(id);
if (mat.hasSubMaterials()) {
mat = mat.getSubMaterial(damage);
}
Material mat = VanillaMaterials.getMaterial(id, damage);
if (id == BlockID.AIR) {
if (mat == VanillaMaterials.AIR) {
throw new IllegalArgumentException("Can't fetch air block");
}
@ -97,8 +130,8 @@ public class SpoutPlayerBlockBag extends BlockBag {
boolean found = false;
for (int slot = 0; slot < items.length; ++slot) {
ItemStack spoutItem = items[slot];
for (int slot = 0; slot < items.inventory.length; ++slot) {
ItemStack spoutItem = items.inventory[slot];
if (spoutItem == null) {
continue;
@ -119,7 +152,7 @@ public class SpoutPlayerBlockBag extends BlockBag {
spoutItem.setAmount(currentAmount - 1);
found = true;
} else {
items[slot] = null;
items.inventory[slot] = null;
found = true;
}
@ -140,14 +173,11 @@ public class SpoutPlayerBlockBag extends BlockBag {
public void storeItem(BaseItem item) throws BlockBagException {
final short id = (short) item.getType();
final short damage = item.getData();
Material mat = VanillaMaterials.getMaterial(id);
if (mat.hasSubMaterials()) {
mat = mat.getSubMaterial(damage);
}
Material mat = VanillaMaterials.getMaterial(id, damage);
int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
assert(amount <= mat.getMaxStackSize());
if (id == BlockID.AIR) {
if (mat == VanillaMaterials.AIR) {
throw new IllegalArgumentException("Can't store air block");
}
@ -155,8 +185,8 @@ public class SpoutPlayerBlockBag extends BlockBag {
int freeSlot = -1;
for (int slot = 0; slot < items.length; ++slot) {
ItemStack spoutItem = items[slot];
for (int slot = 0; slot < items.inventory.length; ++slot) {
ItemStack spoutItem = items.inventory[slot];
if (spoutItem == null) {
// Delay using up a free slot until we know there are no stacks
@ -194,7 +224,7 @@ public class SpoutPlayerBlockBag extends BlockBag {
}
if (freeSlot > -1) {
items[freeSlot] = new ItemStack(mat, amount);
items.inventory[freeSlot] = new ItemStack(mat, amount);
return;
}
@ -207,9 +237,13 @@ public class SpoutPlayerBlockBag extends BlockBag {
@Override
public void flushChanges() {
if (items != null) {
InventoryBase inv = VanillaPlayerUtil.getInventory(player);
for (int i = 0; i < items.length && i < inv.getSize(); ++i) {
inv.setItem(i, items[i]);
PlayerInventory inv = player.get(Human.class).getInventory();
for (int i = 0; i < inv.getQuickbar().size(); i++) {
inv.getQuickbar().set(i, items.inventory[i]);
}
for (int i = 0; i < inv.getMain().size(); ++i) {
inv.getMain().set(i, items.inventory[inv.getQuickbar().size() + i]);
}
items = null;
}
@ -217,7 +251,7 @@ public class SpoutPlayerBlockBag extends BlockBag {
/**
* Adds a position to be used a source.
*
* (TODO: Figure out what this does)
* @param pos
*/
@Override
@ -226,7 +260,7 @@ public class SpoutPlayerBlockBag extends BlockBag {
/**
* Adds a position to be used a source.
*
* (TODO: Figure out what this does)
* @param pos
*/
@Override

View File

@ -110,6 +110,6 @@ public class SpoutUtil {
}
public static Location toLocation(Entity ent) {
return new Location(getLocalWorld(ent.getWorld()), toVector(ent.getPosition()), ent.getYaw(), ent.getPitch());
return new Location(getLocalWorld(ent.getWorld()), toVector(ent.getTransform().getPosition()), ent.getTransform().getYaw(), ent.getTransform().getPitch());
}
}

View File

@ -21,6 +21,10 @@
package com.sk89q.worldedit.spout;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.BiomeType;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.EditSession;
@ -35,6 +39,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import org.spout.api.component.Component;
import org.spout.api.entity.Entity;
import org.spout.api.generator.biome.BiomeGenerator;
import org.spout.api.geo.LoadOption;
@ -44,17 +49,21 @@ import org.spout.api.inventory.ItemStack;
import org.spout.api.material.BlockMaterial;
import org.spout.api.material.Material;
import org.spout.api.math.Vector3;
import org.spout.vanilla.entity.object.moving.Item;
import org.spout.vanilla.entity.object.moving.PrimedTnt;
import org.spout.vanilla.entity.object.projectile.Arrow;
import org.spout.vanilla.entity.object.vehicle.Boat;
import org.spout.vanilla.entity.object.vehicle.Minecart;
import org.spout.vanilla.component.substance.Item;
import org.spout.vanilla.component.substance.Painting;
import org.spout.vanilla.component.substance.XPOrb;
import org.spout.vanilla.component.substance.object.Tnt;
import org.spout.vanilla.component.substance.object.projectile.Arrow;
import org.spout.vanilla.component.substance.object.vehicle.Boat;
import org.spout.vanilla.component.substance.object.vehicle.Minecart;
import org.spout.vanilla.material.VanillaMaterial;
import org.spout.vanilla.material.VanillaMaterials;
import org.spout.vanilla.world.generator.normal.object.tree.TreeObject;
import org.spout.vanilla.world.generator.normal.object.tree.SmallTreeObject;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class SpoutWorld extends LocalWorld {
@ -98,7 +107,10 @@ public class SpoutWorld extends LocalWorld {
public boolean setBlockType(Vector pt, int type) {
Material mat = VanillaMaterials.getMaterial((short) type);
if (mat != null && mat instanceof BlockMaterial) {
return world.setBlockMaterial(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), (BlockMaterial) mat, (short)0, WorldEditPlugin.getInstance());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
return world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).setBlockMaterial(x, y, z, (BlockMaterial) mat, (short) 0, WorldEditPlugin.getInstance());
}
return false;
}
@ -124,9 +136,12 @@ public class SpoutWorld extends LocalWorld {
*/
@Override
public boolean setTypeIdAndData(Vector pt, int type, int data) {
Material mat = VanillaMaterials.getMaterial((short) type);
Material mat = VanillaMaterials.getMaterial((short) type, (short) data);
if (mat != null && mat instanceof BlockMaterial) {
return world.setBlockMaterial(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), (BlockMaterial) mat, (short)data, WorldEditPlugin.getInstance());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
return world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).setBlockMaterial(x, y, z, (BlockMaterial) mat, (short) data, WorldEditPlugin.getInstance());
}
return false;
}
@ -152,7 +167,10 @@ public class SpoutWorld extends LocalWorld {
*/
@Override
public int getBlockType(Vector pt) {
Material mat = world.getBlockMaterial(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
Material mat = world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).getBlockMaterial(x, y, z);
return mat instanceof VanillaMaterial ? ((VanillaMaterial) mat).getMinecraftId() : 0;
}
@ -164,7 +182,10 @@ public class SpoutWorld extends LocalWorld {
*/
@Override
public void setBlockData(Vector pt, int data) {
world.setBlockData(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), (short) data, WorldEditPlugin.getInstance());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).setBlockData(x, y, z, (short) data, WorldEditPlugin.getInstance());
}
/**
@ -186,7 +207,10 @@ public class SpoutWorld extends LocalWorld {
*/
@Override
public int getBlockData(Vector pt) {
return world.getBlockData(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
return world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).getBlockData(x, y, z);
}
/**
@ -197,7 +221,10 @@ public class SpoutWorld extends LocalWorld {
*/
@Override
public int getBlockLightLevel(Vector pt) {
return world.getBlockLight(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
final int x = pt.getBlockX();
final int y = pt.getBlockY();
final int z = pt.getBlockZ();
return world.getChunkFromBlock(x, y, z, LoadOption.LOAD_GEN).getBlockLight(x, y, z);
}
/**
@ -447,7 +474,7 @@ public class SpoutWorld extends LocalWorld {
mat = mat.getSubMaterial(item.getData());
}
ItemStack spoutItem = new ItemStack(mat, item.getData(), item.getAmount());
world.createAndSpawnEntity(SpoutUtil.toPoint(world, pt), new Item(spoutItem, new Vector3(pt.getX(), pt.getY(), pt.getZ())));
world.createEntity(SpoutUtil.toPoint(world, pt), Item.class).get(Item.class).setItemStack(spoutItem);
}
/**
@ -513,46 +540,46 @@ public class SpoutWorld extends LocalWorld {
for (Entity ent : world.getAll()) {
if (radius != -1
&& origin.distanceSq(SpoutUtil.toVector(ent.getPosition())) > radiusSq) {
&& origin.distanceSq(SpoutUtil.toVector(ent.getTransform().getPosition())) > radiusSq) {
continue;
}
if (type == EntityType.ARROWS) {
if (ent.getController() instanceof Arrow) {
ent.kill();
if (ent.has(Arrow.class)) {
ent.remove();
++num;
}
} else if (type == EntityType.BOATS) {
if (ent.getController() instanceof Boat) {
ent.kill();
if (ent.has(Boat.class)) {
ent.remove();
++num;
}
} else if (type == EntityType.ITEMS) {
if (ent.getController() instanceof Item) {
ent.kill();
if (ent.has(Item.class)) {
ent.remove();
++num;
}
} else if (type == EntityType.MINECARTS) {
if (ent.getController() instanceof Minecart) {
ent.kill();
if (ent.has(Minecart.class)) {
ent.remove();
++num;
}
} /*else if (type == EntityType.PAINTINGS) {
if (ent.getController() instanceof Painting) {
ent.kill();
} else if (type == EntityType.PAINTINGS) {
if (ent.has(Painting.class)) {
ent.remove();
++num;
}
}*/ else if (type == EntityType.TNT) {
if (ent.getController() instanceof PrimedTnt) {
ent.kill();
} else if (type == EntityType.TNT) {
if (ent.has(Tnt.class)) {
ent.remove();
++num;
}
} /*else if (type == EntityType.XP_ORBS) {
if (ent instanceof ExperienceOrb) {
ent.kill();
} else if (type == EntityType.XP_ORBS) {
if (ent.has(XPOrb.class)) {
ent.remove();
++num;
}
}*/
}
}
return num;
@ -699,7 +726,6 @@ public class SpoutWorld extends LocalWorld {
@Override
public void checkLoadedChunk(Vector pt) {
world.getChunk(pt.getBlockX() << Chunk.BLOCKS.BITS, pt.getBlockY() << Chunk.BLOCKS.BITS, pt.getBlockZ() << Chunk.BLOCKS.BITS);
}
@Override
@ -753,13 +779,19 @@ public class SpoutWorld extends LocalWorld {
public SpoutEntity[] getEntities(Region region) {
List<SpoutEntity> entities = new ArrayList<SpoutEntity>();
for (Vector pt : region.getChunkCubes()) {
Chunk chunk = world.getChunk(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), LoadOption.NO_LOAD);
Chunk chunk = world.getChunkFromBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), LoadOption.LOAD_GEN);
if (chunk == null) {
continue;
}
for (Entity ent : chunk.getEntities()) {
if (region.contains(SpoutUtil.toVector(ent.getPosition()))) {
entities.add(new SpoutEntity(SpoutUtil.toLocation(ent), ent.getId(), ent.getController()));
if (region.contains(SpoutUtil.toVector(ent.getTransform().getPosition()))) {
Collection<Class<? extends Component>> revisedComponents = Collections2.transform(ent.values(), new Function<Component, Class<? extends Component>>() {
@Override
public Class<? extends Component> apply(@Nullable Component component) {
return component == null ? null : component.getClass();
}
});
entities.add(new SpoutEntity(SpoutUtil.toLocation(ent), ent.getId(), revisedComponents, ent.getData().getBaseMap())); // TODO:; Fix entity adding
}
}
}
@ -773,7 +805,7 @@ public class SpoutWorld extends LocalWorld {
SpoutEntity entity = (SpoutEntity) weEnt;
Entity spoutEntity = world.getEntity(entity.getEntityId());
if (spoutEntity != null) {
spoutEntity.kill();
spoutEntity.remove();
++amount;
}
}

View File

@ -121,12 +121,6 @@ public class WorldEditPlugin extends CommonPlugin {
* Called on plugin disable.
*/
public void onDisable() {
for (Player player : getServer().getOnlinePlayers()) {
LocalPlayer lPlayer = wrapPlayer(player);
if (controller.getSession(lPlayer).hasCUISupport()) {
lPlayer.dispatchCUIHandshake();
}
}
controller.clearSessions();
config.unload();
getEngine().getScheduler().cancelTasks(this);