Fixed setting blocks, entities, and implemented entity rotation

This commit is contained in:
Wyatt Childers 2016-02-05 19:30:11 -05:00
parent 12a8a858b9
commit f09fff9491
6 changed files with 121 additions and 59 deletions

View File

@ -40,6 +40,6 @@ public class SpongeConfiguration extends PropertiesConfiguration {
@Override @Override
public File getWorkingDirectory() { public File getWorkingDirectory() {
return SpongeWorldEdit.inst.getWorkingDir(); return SpongeWorldEdit.inst().getWorkingDir();
} }
} }

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.sponge; package com.sk89q.worldedit.sponge;
import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
@ -36,6 +34,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.ChunkCoordIntPair;
@ -43,24 +42,18 @@ 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 net.minecraft.world.gen.feature.*; import net.minecraft.world.gen.feature.*;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.block.BlockState; import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
import org.spongepowered.common.block.SpongeBlockSnapshotBuilder;
import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
public class SpongeForgeWorld extends SpongeWorld { import static com.google.common.base.Preconditions.checkNotNull;
private final SpongeBlockSnapshotBuilder blockBuilder = new SpongeBlockSnapshotBuilder(); public class SpongeForgeWorld extends SpongeWorld {
private final SpongeEntitySnapshotBuilder entityBuilder = new SpongeEntitySnapshotBuilder();
private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
private static final IBlockState JUNGLE_LEAF = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); private static final IBlockState JUNGLE_LEAF = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
@ -76,44 +69,38 @@ public class SpongeForgeWorld extends SpongeWorld {
} }
@Override @Override
protected BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block) { protected BlockState getBlockState(BaseBlock block) {
this.blockBuilder.reset(); return (BlockState) Block.getBlockById(block.getId()).getStateFromMeta(block.getData());
}
Location<World> location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); private NBTTagCompound updateForSet(NBTTagCompound tag, Vector position) {
IBlockState baseState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); checkNotNull(tag);
checkNotNull(position);
this.blockBuilder.blockState((BlockState) baseState); tag.setTag("x", new NBTTagInt(position.getBlockX()));
this.blockBuilder.worldId(getWorld().getUniqueId()); tag.setTag("y", new NBTTagInt(position.getBlockY()));
this.blockBuilder.position(location.getBlockPosition()); tag.setTag("z", new NBTTagInt(position.getBlockZ()));
if (block.hasNbtData()) { return tag;
NBTTagCompound tag = NBTConverter.toNative(block.getNbtData());
tag.setString("id", block.getNbtId());
this.blockBuilder.unsafeNbt(tag);
}
return this.blockBuilder.build();
} }
@Override @Override
protected EntitySnapshot createEntitySnapshot(com.sk89q.worldedit.util.Location location, BaseEntity entity) { protected void applyTileEntityData(org.spongepowered.api.block.tileentity.TileEntity entity, BaseBlock block) {
this.entityBuilder.reset(); NBTTagCompound tag = NBTConverter.toNative(block.getNbtData());
this.entityBuilder.worldId(getWorld().getUniqueId()); Location<World> loc = entity.getLocation();
this.entityBuilder.position(new Vector3d(location.getX(), location.getY(), location.getZ()));
// TODO Rotation code
// this.entityBuilder.rotation()
this.entityBuilder.type(Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get());
if (entity.hasNbtData()) {
NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData());
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.removeTag(name);
}
this.entityBuilder.unsafeCompound(tag); updateForSet(tag, new Vector(loc.getX(), loc.getY(), loc.getZ()));
((TileEntity) entity).readFromNBT(tag);
}
@Override
protected void applyEntityData(Entity entity, BaseEntity data) {
NBTTagCompound tag = NBTConverter.toNative(data.getNbtData());
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.removeTag(name);
} }
return this.entityBuilder.build(); ((net.minecraft.entity.Entity) entity).readFromNBT(tag);
} }
@Override @Override

View File

@ -75,7 +75,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform {
@Override @Override
public int schedule(long delay, long period, Runnable task) { public int schedule(long delay, long period, Runnable task) {
Task.builder().delayTicks(delay).intervalTicks(period).execute(task).submit(SpongeWorldEdit.inst); Task.builder().delayTicks(delay).intervalTicks(period).execute(task).submit(SpongeWorldEdit.inst());
return 0; // TODO This isn't right, but we only check for -1 values return 0; // TODO This isn't right, but we only check for -1 values
} }
@ -122,19 +122,19 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform {
CommandAdapter adapter = new CommandAdapter(command) { CommandAdapter adapter = new CommandAdapter(command) {
@Override @Override
public CommandResult process(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { public CommandResult process(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException {
CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst().wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments);
WorldEdit.getInstance().getEventBus().post(weEvent); WorldEdit.getInstance().getEventBus().post(weEvent);
return weEvent.isCancelled() ? CommandResult.success() : CommandResult.empty(); return weEvent.isCancelled() ? CommandResult.success() : CommandResult.empty();
} }
@Override @Override
public List<String> getSuggestions(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { public List<String> getSuggestions(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException {
CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst().wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments);
WorldEdit.getInstance().getEventBus().post(weEvent); WorldEdit.getInstance().getEventBus().post(weEvent);
return weEvent.getSuggestions(); return weEvent.getSuggestions();
} }
}; };
Sponge.getCommandManager().register(SpongeWorldEdit.inst, adapter, command.getAllAliases()); Sponge.getCommandManager().register(SpongeWorldEdit.inst(), adapter, command.getAllAliases());
} }
} }

View File

@ -144,12 +144,22 @@ public class SpongePlayer extends AbstractPlayerActor {
@Override @Override
public void setPosition(Vector pos, float pitch, float yaw) { public void setPosition(Vector pos, float pitch, float yaw) {
org.spongepowered.api.world.Location<World> loc = new org.spongepowered.api.world.Location<World>( org.spongepowered.api.world.Location<World> loc = new org.spongepowered.api.world.Location<>(
this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ()
); );
// TODO Rotation code double yawR = Math.toRadians(yaw);
this.player.setLocation(loc); double pitchR = Math.toRadians(pitch);
double xz = Math.cos(pitch);
this.player.setLocationAndRotation(
loc,
new Vector3d(
-xz * Math.sin(yawR),
-Math.sin(pitchR),
xz * Math.cos(yawR)
)
);
} }
@Override @Override
@ -164,7 +174,7 @@ public class SpongePlayer extends AbstractPlayerActor {
@Override @Override
public boolean hasPermission(String perm) { public boolean hasPermission(String perm) {
return SpongeWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm); return SpongeWorldEdit.inst().getPermissionsProvider().hasPermission(player, perm);
} }
@Nullable @Nullable

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.sponge;
import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i; import com.flowpowered.math.vector.Vector3i;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
@ -28,19 +29,30 @@ 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.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.WorldData; import com.sk89q.worldedit.world.registry.WorldData;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityList;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.BlockPos;
import net.minecraft.world.chunk.Chunk;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.block.BlockState; import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.tileentity.TileEntity;
import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.property.block.GroundLuminanceProperty; import org.spongepowered.api.data.property.block.GroundLuminanceProperty;
import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.data.property.block.SkyLuminanceProperty;
import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntitySnapshot;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.event.cause.Cause; import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.util.PositionOutOfBoundsException;
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -109,14 +121,37 @@ public abstract class SpongeWorld extends AbstractWorld {
return getWorld().getName(); return getWorld().getName();
} }
protected abstract BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block); protected abstract BlockState getBlockState(BaseBlock block);
protected abstract void applyTileEntityData(TileEntity entity, BaseBlock block);
@Override @Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException {
checkNotNull(position); checkNotNull(position);
checkNotNull(block); checkNotNull(block);
return createBlockSnapshot(position, block).restore(true, notifyAndLight); World world = getWorldChecked();
// First set the block
Vector3i pos = new Vector3i(position.getX(), position.getY(), position.getZ());
BlockState newState = getBlockState(block);
try {
world.setBlock(pos, newState, notifyAndLight, Cause.of(SpongeWorldEdit.container()));
} catch (PositionOutOfBoundsException ex) {
return false;
}
// Create the TileEntity
if (block.hasNbtData()) {
// Kill the old TileEntity
Optional<TileEntity> optTile = world.getTileEntity(pos);
if (optTile.isPresent()) {
applyTileEntityData(optTile.get(), block);
}
}
return true;
} }
@Override @Override
@ -169,7 +204,7 @@ public abstract class SpongeWorld extends AbstractWorld {
if (optItem.isPresent()) { if (optItem.isPresent()) {
org.spongepowered.api.entity.Entity entity = optItem.get(); org.spongepowered.api.entity.Entity entity = optItem.get();
entity.offer(Keys.REPRESENTED_ITEM, SpongeWorldEdit.toSpongeItemStack(item).createSnapshot()); entity.offer(Keys.REPRESENTED_ITEM, SpongeWorldEdit.toSpongeItemStack(item).createSnapshot());
getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.inst)); getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.container()));
} }
} }
@ -225,18 +260,36 @@ public abstract class SpongeWorld extends AbstractWorld {
return entities; return entities;
} }
protected abstract EntitySnapshot createEntitySnapshot(Location location, BaseEntity entity); protected abstract void applyEntityData(org.spongepowered.api.entity.Entity entity, BaseEntity data);
@Nullable @Nullable
@Override @Override
public Entity createEntity(Location location, BaseEntity entity) { public Entity createEntity(Location location, BaseEntity entity) {
EntitySnapshot snapshot = createEntitySnapshot(location, entity); World world = getWorld();
if (snapshot != null) {
Optional<org.spongepowered.api.entity.Entity> restoredEnt = snapshot.restore(); EntityType entityType = Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get();
if (restoredEnt.isPresent()) { Vector3d pos = new Vector3d(location.getX(), location.getY(), location.getZ());
return new SpongeEntity(restoredEnt.get());
Optional<org.spongepowered.api.entity.Entity> optNewEnt = world.createEntity(entityType, pos);
if (optNewEnt.isPresent()) {
org.spongepowered.api.entity.Entity newEnt = optNewEnt.get();
if (entity.hasNbtData()) {
applyEntityData(newEnt, entity);
}
// Overwrite any data set by the NBT application
Vector dir = location.getDirection();
newEnt.setLocationAndRotation(
new org.spongepowered.api.world.Location<>(getWorld(), pos),
new Vector3d(dir.getX(), dir.getY(), dir.getZ())
);
if (world.spawnEntity(newEnt, Cause.of(SpongeWorldEdit.container()))) {
return new SpongeEntity(newEnt);
} }
} }
return null; return null;
} }

View File

@ -41,6 +41,7 @@ import org.spongepowered.api.event.cause.NamedCause;
import org.spongepowered.api.event.game.state.*; import org.spongepowered.api.event.game.state.*;
import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.plugin.Plugin; import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
@ -66,7 +67,18 @@ public class SpongeWorldEdit {
private SponePermissionsProvider provider; private SponePermissionsProvider provider;
public static SpongeWorldEdit inst; @Inject
private PluginContainer container;
private static SpongeWorldEdit inst;
public static PluginContainer container() {
return inst.container;
}
public static SpongeWorldEdit inst() {
return inst;
}
private SpongePlatform platform; private SpongePlatform platform;
private SpongeConfiguration config; private SpongeConfiguration config;