From f09fff949194636bae9b1089c5441aa544613b30 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 5 Feb 2016 19:30:11 -0500 Subject: [PATCH] Fixed setting blocks, entities, and implemented entity rotation --- .../worldedit/sponge/SpongeConfiguration.java | 2 +- .../worldedit/sponge/SpongeForgeWorld.java | 67 +++++++---------- .../worldedit/sponge/SpongePlatform.java | 8 +-- .../sk89q/worldedit/sponge/SpongePlayer.java | 18 +++-- .../sk89q/worldedit/sponge/SpongeWorld.java | 71 ++++++++++++++++--- .../worldedit/sponge/SpongeWorldEdit.java | 14 +++- 6 files changed, 121 insertions(+), 59 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java index 13c755fd4..ee8470d77 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java @@ -40,6 +40,6 @@ public class SpongeConfiguration extends PropertiesConfiguration { @Override public File getWorkingDirectory() { - return SpongeWorldEdit.inst.getWorkingDir(); + return SpongeWorldEdit.inst().getWorkingDir(); } } \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java index 00c12c60a..09d0264bc 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java @@ -19,8 +19,6 @@ 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.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; @@ -36,6 +34,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; 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.gen.ChunkProviderServer; 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.entity.EntitySnapshot; -import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.entity.Entity; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; -import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; -import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder; import javax.annotation.Nullable; import java.util.Set; import java.util.logging.Level; -public class SpongeForgeWorld extends SpongeWorld { +import static com.google.common.base.Preconditions.checkNotNull; - private final SpongeBlockSnapshotBuilder blockBuilder = new SpongeBlockSnapshotBuilder(); - private final SpongeEntitySnapshotBuilder entityBuilder = new SpongeEntitySnapshotBuilder(); +public class SpongeForgeWorld extends SpongeWorld { 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)); @@ -76,44 +69,38 @@ public class SpongeForgeWorld extends SpongeWorld { } @Override - protected BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block) { - this.blockBuilder.reset(); + protected BlockState getBlockState(BaseBlock block) { + return (BlockState) Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); + } - Location location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); - IBlockState baseState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); + private NBTTagCompound updateForSet(NBTTagCompound tag, Vector position) { + checkNotNull(tag); + checkNotNull(position); - this.blockBuilder.blockState((BlockState) baseState); - this.blockBuilder.worldId(getWorld().getUniqueId()); - this.blockBuilder.position(location.getBlockPosition()); + tag.setTag("x", new NBTTagInt(position.getBlockX())); + tag.setTag("y", new NBTTagInt(position.getBlockY())); + tag.setTag("z", new NBTTagInt(position.getBlockZ())); - if (block.hasNbtData()) { - NBTTagCompound tag = NBTConverter.toNative(block.getNbtData()); - tag.setString("id", block.getNbtId()); - - this.blockBuilder.unsafeNbt(tag); - } - - return this.blockBuilder.build(); + return tag; } @Override - protected EntitySnapshot createEntitySnapshot(com.sk89q.worldedit.util.Location location, BaseEntity entity) { - this.entityBuilder.reset(); + protected void applyTileEntityData(org.spongepowered.api.block.tileentity.TileEntity entity, BaseBlock block) { + NBTTagCompound tag = NBTConverter.toNative(block.getNbtData()); - this.entityBuilder.worldId(getWorld().getUniqueId()); - 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); - } + Location loc = entity.getLocation(); - 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 diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index c8cb19f5e..f390138f7 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -75,7 +75,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { @Override 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 } @@ -122,19 +122,19 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { CommandAdapter adapter = new CommandAdapter(command) { @Override 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); return weEvent.isCancelled() ? CommandResult.success() : CommandResult.empty(); } @Override public List 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); return weEvent.getSuggestions(); } }; - Sponge.getCommandManager().register(SpongeWorldEdit.inst, adapter, command.getAllAliases()); + Sponge.getCommandManager().register(SpongeWorldEdit.inst(), adapter, command.getAllAliases()); } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 3a11c8bb8..2b9af46d7 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -144,12 +144,22 @@ public class SpongePlayer extends AbstractPlayerActor { @Override public void setPosition(Vector pos, float pitch, float yaw) { - org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location( + org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location<>( this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() ); - // TODO Rotation code - this.player.setLocation(loc); + double yawR = Math.toRadians(yaw); + 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 @@ -164,7 +174,7 @@ public class SpongePlayer extends AbstractPlayerActor { @Override public boolean hasPermission(String perm) { - return SpongeWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm); + return SpongeWorldEdit.inst().getPermissionsProvider().hasPermission(player, perm); } @Nullable diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index f615b5239..eaf265718 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3i; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; 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.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; 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.BlockState; +import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.property.block.GroundLuminanceProperty; import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntitySnapshot; +import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.util.PositionOutOfBoundsException; import org.spongepowered.api.world.World; import javax.annotation.Nullable; @@ -109,14 +121,37 @@ public abstract class SpongeWorld extends AbstractWorld { 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 public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { checkNotNull(position); 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 optTile = world.getTileEntity(pos); + if (optTile.isPresent()) { + applyTileEntityData(optTile.get(), block); + } + } + + return true; } @Override @@ -169,7 +204,7 @@ public abstract class SpongeWorld extends AbstractWorld { if (optItem.isPresent()) { org.spongepowered.api.entity.Entity entity = optItem.get(); 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; } - protected abstract EntitySnapshot createEntitySnapshot(Location location, BaseEntity entity); + protected abstract void applyEntityData(org.spongepowered.api.entity.Entity entity, BaseEntity data); @Nullable @Override public Entity createEntity(Location location, BaseEntity entity) { - EntitySnapshot snapshot = createEntitySnapshot(location, entity); - if (snapshot != null) { - Optional restoredEnt = snapshot.restore(); - if (restoredEnt.isPresent()) { - return new SpongeEntity(restoredEnt.get()); + World world = getWorld(); + + EntityType entityType = Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get(); + Vector3d pos = new Vector3d(location.getX(), location.getY(), location.getZ()); + + Optional 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; } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 64072acfb..8e8c7668a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -41,6 +41,7 @@ import org.spongepowered.api.event.cause.NamedCause; import org.spongepowered.api.event.game.state.*; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.plugin.Plugin; +import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; @@ -66,7 +67,18 @@ public class SpongeWorldEdit { 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 SpongeConfiguration config;