mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
Additional work towards 1.16 compatibility
- Very basic implementation of the SideEffects system. Will definitely need fine tuning for it to be functional, but is not considered a priority in my opinion. - Minor changes to the World interface and World implementations related to the SideEffects system. Shouldn't be the cause of any new bugs but be on the lookout. - Included debug in BukkitImplLoader.java to assist contributors in understanding what needs to be implemented for the adapter to load properly. Still very WIP but we're a few steps closer. So far, this is coming along better than I anticipated. Hopefully we can keep the momentum.
This commit is contained in:
parent
68679e007e
commit
4604aa5920
@ -68,6 +68,6 @@
|
||||
</module>
|
||||
<!-- Validate that command annotations are formatted correctly -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="^( +)@(Arg|Switch|Command)\(.*?\n\1 {5,}"/>
|
||||
<property name="format" value="^( +)@(Arg|Switch|Command)\(.*?\r?\n\1 {5,}"/>
|
||||
</module>
|
||||
</module>
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.bukkit;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.bukkit.util.CommandInfo;
|
||||
import com.sk89q.bukkit.util.CommandRegistration;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
@ -30,6 +31,7 @@ import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
@ -44,8 +46,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -218,6 +220,18 @@ public class BukkitServerInterface implements MultiUserPlatform {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||
SideEffect.NEIGHBORS
|
||||
);
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
if (plugin.getBukkitImplAdapter() != null) {
|
||||
return plugin.getBukkitImplAdapter().getSupportedSideEffects();
|
||||
}
|
||||
return SUPPORTED_SIDE_EFFECTS;
|
||||
}
|
||||
|
||||
public void unregisterCommands() {
|
||||
dynamicCommands.unregisterCommands();
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -38,6 +39,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -48,12 +51,7 @@ import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.TreeType;
|
||||
@ -466,11 +464,11 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
if (adapter != null) {
|
||||
try {
|
||||
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
|
||||
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, sideEffects);
|
||||
} catch (Exception e) {
|
||||
if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
|
||||
logger.warn("Tried to set a corrupt tile entity at " + position.toString());
|
||||
@ -478,12 +476,12 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
e.printStackTrace();
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), notifyAndLight);
|
||||
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), false);
|
||||
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -499,14 +497,20 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyAndLightBlock(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType) throws WorldEditException {
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.notifyAndLightBlock(BukkitAdapter.adapt(getWorld(), position), previousType);
|
||||
return true;
|
||||
adapter.applySideEffects(BukkitAdapter.adapt(getWorld(), position), previousType, sideEffectSet);
|
||||
return Sets.intersection(
|
||||
adapter.getSupportedSideEffects(),
|
||||
sideEffectSet.getSideEffectsToApply()
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
return Sets.intersection(
|
||||
WorldEditPlugin.getInstance().getInternalPlatform().getSupportedSideEffects(),
|
||||
sideEffectSet.getSideEffectsToApply()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,6 +34,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -43,6 +45,7 @@ import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@ -99,19 +102,19 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
||||
*
|
||||
* @param location the location
|
||||
* @param state the block
|
||||
* @param notifyAndLight notify and light if set
|
||||
* @param sideEffectSet side effects to apply
|
||||
* @return true if a block was likely changed
|
||||
*/
|
||||
<B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight);
|
||||
boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet);
|
||||
|
||||
/**
|
||||
* Notifies the simulation that the block at the given location has
|
||||
* been changed and it must be re-lighted (and issue other events).
|
||||
* Applies side effects on the given block.
|
||||
*
|
||||
* @param position position of the block
|
||||
* @param previousType the type of the previous block that was there
|
||||
* @param sideEffectSet side effects to apply
|
||||
*/
|
||||
void notifyAndLightBlock(Location position, BlockState previousType);
|
||||
void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet);
|
||||
|
||||
/**
|
||||
* Get the state for the given entity.
|
||||
@ -186,6 +189,13 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
||||
*/
|
||||
BaseItemStack adapt(ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Get the {@link SideEffect}s that this adapter supports.
|
||||
*
|
||||
* @return The side effects that are supported
|
||||
*/
|
||||
Set<SideEffect> getSupportedSideEffects();
|
||||
|
||||
default OptionalInt getInternalBlockStateId(BlockData data) {
|
||||
// return OptionalInt.empty();
|
||||
return getInternalBlockStateId(BukkitAdapter.adapt(data));
|
||||
|
@ -155,11 +155,20 @@ public class BukkitImplLoader {
|
||||
*/
|
||||
public BukkitImplAdapter loadAdapter() throws AdapterLoadException {
|
||||
for (String className : adapterCandidates) {
|
||||
System.out.println("Candidate: " + className);
|
||||
try {
|
||||
Class<?> cls = Class.forName(className);
|
||||
if (cls.isSynthetic()) continue;
|
||||
if (cls.isSynthetic()){
|
||||
System.out.println(className + " is synthetic, continuing");
|
||||
continue;
|
||||
}else{
|
||||
System.out.println(className + " is not synthetic");
|
||||
}
|
||||
if (BukkitImplAdapter.class.isAssignableFrom(cls)) {
|
||||
System.out.println(className + " is assignable from BukkitImplAdapter, returning");
|
||||
return (BukkitImplAdapter) cls.newInstance();
|
||||
}else{
|
||||
System.out.println(className + " is NOT assignable from BukkitImplAdapter, returning");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.warn("Failed to load the Bukkit adapter class '" + className +
|
||||
@ -170,6 +179,8 @@ public class BukkitImplLoader {
|
||||
} catch (Throwable e) {
|
||||
if (className.equals(customCandidate)) {
|
||||
log.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
|
||||
}else{
|
||||
log.warn(className + " is not custom candidate.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -66,12 +67,7 @@ public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
|
||||
}
|
||||
|
||||
default <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
|
||||
return getParent().setBlock(location, state, notifyAndLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||
getParent().notifyAndLightBlock(position, previousType);
|
||||
return getParent().setBlock(location, state, SideEffectSet.none());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,6 +45,8 @@ import com.sk89q.worldedit.entity.LazyBaseEntity;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -71,6 +73,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
@ -148,6 +151,21 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
|
||||
return; //TODO: properly implement SideEffects into FAWE
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
|
||||
@ -292,11 +310,6 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I
|
||||
return material.getCraftBlockData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
|
||||
}
|
||||
|
||||
private MapChunkUtil_1_14 mapUtil = new MapChunkUtil_1_14();
|
||||
|
||||
@Override
|
||||
|
@ -47,6 +47,8 @@ import com.sk89q.worldedit.entity.LazyBaseEntity;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -73,6 +75,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
@ -157,12 +160,27 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
|
||||
return; //TODO: properly implement SideEffects into FAWE
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
|
||||
}
|
||||
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, B state, boolean update) {
|
||||
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
||||
Chunk nmsChunk = craftChunk.getHandle();
|
||||
World nmsWorld = nmsChunk.getWorld();
|
||||
@ -301,11 +319,6 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
|
||||
return material.getCraftBlockData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
|
||||
}
|
||||
|
||||
private MapChunkUtil_1_15_2 mapUtil = new MapChunkUtil_1_15_2();
|
||||
|
||||
@Override
|
||||
|
@ -47,6 +47,8 @@ import com.sk89q.worldedit.entity.LazyBaseEntity;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.*;
|
||||
@ -72,6 +74,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
@ -156,12 +159,27 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Location location, BlockStateHolder<?> state, SideEffectSet sideEffectSet) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySideEffects(Location position, BlockState previousType, SideEffectSet sideEffectSet) {
|
||||
return; //TODO: properly implement SideEffects into FAWE
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(Location location, B state, boolean notifyAndLight) {
|
||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
|
||||
}
|
||||
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, B state, boolean update) {
|
||||
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
||||
Chunk nmsChunk = craftChunk.getHandle();
|
||||
World nmsWorld = nmsChunk.getWorld();
|
||||
@ -300,11 +318,6 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
|
||||
return material.getCraftBlockData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
|
||||
}
|
||||
|
||||
private MapChunkUtil_1_16_1 mapUtil = new MapChunkUtil_1_16_1();
|
||||
|
||||
@Override
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.cli;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
@ -33,6 +35,7 @@ import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@ -153,6 +156,11 @@ class CLIPlatform extends AbstractPlatform {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
public void addWorld(World world) {
|
||||
worlds.add(world);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.cli.schematic;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -34,6 +35,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -46,6 +49,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -74,15 +78,14 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight)
|
||||
throws WorldEditException {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
dirty = true;
|
||||
return clipboard.setBlock(position, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
|
||||
return false;
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,12 +13,16 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
@ -35,6 +39,11 @@ public class MCAWorld extends AbstractWorld {
|
||||
return path.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
@ -46,6 +55,11 @@ public class MCAWorld extends AbstractWorld {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
return SideEffectSet.none().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearContainerBlockContents(BlockVector3 position) {
|
||||
return false;
|
||||
|
@ -29,10 +29,7 @@ import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.image.Drawable;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
@ -48,9 +45,7 @@ import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Identifiable;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.*;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
@ -68,6 +63,7 @@ import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Supplier;
|
||||
@ -750,12 +746,24 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
return BlockVector3.at(getWidth() - 1, 255, getLength() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet)
|
||||
throws WorldEditException{
|
||||
return SideEffectSet.none().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block)
|
||||
throws WorldEditException {
|
||||
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects)
|
||||
throws WorldEditException {
|
||||
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
||||
}
|
||||
|
||||
private boolean setBlock(int x, int y, int z, char combined) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= getArea()) {
|
||||
|
@ -24,9 +24,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.*;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -38,6 +36,7 @@ import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class WorldWrapper extends AbstractWorld {
|
||||
|
||||
@ -88,6 +87,12 @@ public class WorldWrapper extends AbstractWorld {
|
||||
return parent.useItem(position, item, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet)
|
||||
throws WorldEditException{
|
||||
return parent.applySideEffects(position, previousType, sideEffectSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
return parent.setBlock(position, block, notifyAndLight);
|
||||
@ -99,6 +104,11 @@ public class WorldWrapper extends AbstractWorld {
|
||||
return parent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
return parent.setBlock(position, block, sideEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return parent.setTile(x, y, z, tile);
|
||||
|
@ -117,6 +117,7 @@ import com.sk89q.worldedit.regions.shape.RegionShape;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.eventbus.EventBus;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
@ -572,6 +573,20 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
disableHistory(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which block updates should occur.
|
||||
*
|
||||
* @param sideEffectSet side effects to enable
|
||||
*/
|
||||
public void setSideEffectApplier(SideEffectSet sideEffectSet) {
|
||||
//Do nothing; TODO: SideEffects currently not fully implemented in FAWE.
|
||||
}
|
||||
|
||||
public SideEffectSet getSideEffectApplier() {
|
||||
//Do nothing; TODO: SideEffects currently not fully implemented in FAWE.
|
||||
return SideEffectSet.defaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable history (or re-enable)
|
||||
*
|
||||
|
@ -72,6 +72,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.HandSide;
|
||||
import com.sk89q.worldedit.util.Identifiable;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -145,7 +146,7 @@ public class LocalSession implements TextureHolder {
|
||||
private transient Snapshot snapshotExperimental;
|
||||
private transient boolean hasCUISupport = false;
|
||||
private transient int cuiVersion = -1;
|
||||
private transient boolean fastMode = false;
|
||||
private transient SideEffectSet sideEffectSet = SideEffectSet.defaults();
|
||||
private transient Mask mask;
|
||||
private transient Mask sourceMask;
|
||||
private transient TextureUtil texture;
|
||||
@ -1494,7 +1495,7 @@ public class LocalSession implements TextureHolder {
|
||||
builder.blockBag(blockBag);
|
||||
}
|
||||
builder.command(command);
|
||||
builder.fastmode(fastMode);
|
||||
builder.fastmode(!this.sideEffectSet.doesApplyAny());
|
||||
|
||||
editSession = builder.build();
|
||||
|
||||
@ -1513,7 +1514,7 @@ public class LocalSession implements TextureHolder {
|
||||
}
|
||||
|
||||
private void prepareEditingExtents(EditSession editSession, Actor actor) {
|
||||
editSession.setFastMode(fastMode);
|
||||
editSession.setSideEffectApplier(sideEffectSet);
|
||||
editSession.setReorderMode(reorderMode);
|
||||
if (editSession.getSurvivalExtent() != null) {
|
||||
editSession.getSurvivalExtent().setStripNbt(!actor.hasPermission("worldedit.setnbt"));
|
||||
@ -1521,13 +1522,32 @@ public class LocalSession implements TextureHolder {
|
||||
editSession.setTickingWatchdog(tickingWatchdog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the side effect applier of this session.
|
||||
*
|
||||
* @return the side effect applier
|
||||
*/
|
||||
public SideEffectSet getSideEffectSet() {
|
||||
return this.sideEffectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the side effect applier for this session
|
||||
*
|
||||
* @param sideEffectSet the side effect applier
|
||||
*/
|
||||
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||
this.sideEffectSet = sideEffectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the session has fast mode enabled.
|
||||
*
|
||||
* @return true if fast mode is enabled
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean hasFastMode() {
|
||||
return fastMode;
|
||||
return !this.sideEffectSet.doesApplyAny();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1535,8 +1555,9 @@ public class LocalSession implements TextureHolder {
|
||||
*
|
||||
* @param fastMode true if fast mode is enabled
|
||||
*/
|
||||
@Deprecated
|
||||
public void setFastMode(boolean fastMode) {
|
||||
this.fastMode = fastMode;
|
||||
this.sideEffectSet = fastMode ? SideEffectSet.none() : SideEffectSet.defaults();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,10 +49,13 @@ import java.util.ArrayList;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||
import com.sk89q.worldedit.util.formatting.component.SideEffectBox;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -142,24 +145,62 @@ public class GeneralCommands {
|
||||
|
||||
@Command(
|
||||
name = "/fast",
|
||||
desc = "Toggle fast mode"
|
||||
desc = "Toggle fast mode side effects"
|
||||
)
|
||||
@CommandPermissions("worldedit.fast")
|
||||
public void fast(Actor actor, LocalSession session,
|
||||
@Arg(desc = "The new fast mode state", def = "")
|
||||
Boolean fastMode) {
|
||||
boolean hasFastMode = session.hasFastMode();
|
||||
if (fastMode != null && fastMode == hasFastMode) {
|
||||
actor.printError(TranslatableComponent.of(fastMode ? "worldedit.fast.enabled.already" : "worldedit.fast.disabled.already"));
|
||||
return;
|
||||
@Arg(desc = "The side effect", def = "")
|
||||
SideEffect sideEffect,
|
||||
@Arg(desc = "The new side effect state", def = "")
|
||||
SideEffect.State newState,
|
||||
@Switch(name = 'h', desc = "Show the info box")
|
||||
boolean showInfoBox) throws WorldEditException {
|
||||
if (sideEffect != null) {
|
||||
SideEffect.State currentState = session.getSideEffectSet().getState(sideEffect);
|
||||
if (newState != null && newState == currentState) {
|
||||
if (!showInfoBox) {
|
||||
actor.printError(TranslatableComponent.of(
|
||||
"worldedit.fast.sideeffect.already-set",
|
||||
TranslatableComponent.of(sideEffect.getDisplayName()),
|
||||
TranslatableComponent.of(newState.getDisplayName())
|
||||
));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (newState != null) {
|
||||
session.setSideEffectSet(session.getSideEffectSet().with(sideEffect, newState));
|
||||
if (!showInfoBox) {
|
||||
actor.printInfo(TranslatableComponent.of(
|
||||
"worldedit.fast.sideeffect.set",
|
||||
TranslatableComponent.of(sideEffect.getDisplayName()),
|
||||
TranslatableComponent.of(newState.getDisplayName())
|
||||
));
|
||||
}
|
||||
} else {
|
||||
actor.printInfo(TranslatableComponent.of(
|
||||
"worldedit.fast.sideeffect.get",
|
||||
TranslatableComponent.of(sideEffect.getDisplayName()),
|
||||
TranslatableComponent.of(currentState.getDisplayName())
|
||||
));
|
||||
}
|
||||
} else if (newState != null) {
|
||||
SideEffectSet applier = session.getSideEffectSet();
|
||||
for (SideEffect sideEffectEntry : SideEffect.values()) {
|
||||
applier = applier.with(sideEffectEntry, newState);
|
||||
}
|
||||
session.setSideEffectSet(applier);
|
||||
if (!showInfoBox) {
|
||||
actor.printInfo(TranslatableComponent.of(
|
||||
"worldedit.fast.sideeffect.set-all",
|
||||
TranslatableComponent.of(newState.getDisplayName())
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFastMode) {
|
||||
session.setFastMode(false);
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.fast.disabled"));
|
||||
} else {
|
||||
session.setFastMode(true);
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.fast.enabled"));
|
||||
if (sideEffect == null || showInfoBox) {
|
||||
SideEffectBox sideEffectBox = new SideEffectBox(session.getSideEffectSet());
|
||||
actor.print(sideEffectBox.create(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import com.boydti.fawe.object.brush.scroll.Scroll;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.command.util.HookMode;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
import org.enginehub.piston.converter.ArgumentConverter;
|
||||
@ -30,6 +31,7 @@ import org.enginehub.piston.converter.MultiKeyConverter;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@ -48,6 +50,11 @@ public final class EnumConverter {
|
||||
full(EditSession.ReorderMode.class,
|
||||
r -> ImmutableSet.of(r.getDisplayName()),
|
||||
null));
|
||||
commandManager.registerConverter(Key.of(SideEffect.State.class),
|
||||
MultiKeyConverter.from(
|
||||
EnumSet.of(SideEffect.State.OFF, SideEffect.State.ON),
|
||||
r -> ImmutableSet.of(r.name().toLowerCase(Locale.US)),
|
||||
null));
|
||||
commandManager.registerConverter(Key.of(HookMode.class),
|
||||
basic(HookMode.class));
|
||||
commandManager.registerConverter(Key.of(Scroll.Action.class),
|
||||
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.command.argument;
|
||||
|
||||
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.EntityRemover;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
import org.enginehub.piston.converter.ArgumentConverter;
|
||||
import org.enginehub.piston.converter.ConversionResult;
|
||||
import org.enginehub.piston.converter.FailedConversion;
|
||||
import org.enginehub.piston.converter.SuccessfulConversion;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class SideEffectConverter implements ArgumentConverter<SideEffect> {
|
||||
|
||||
public static void register(CommandManager commandManager) {
|
||||
commandManager.registerConverter(Key.of(SideEffect.class), new SideEffectConverter());
|
||||
}
|
||||
|
||||
private final TextComponent choices = TextComponent.of("any side effect");
|
||||
|
||||
private SideEffectConverter() {
|
||||
}
|
||||
|
||||
private Collection<SideEffect> getSideEffects() {
|
||||
return WorldEdit.getInstance().getPlatformManager().getSupportedSideEffects();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component describeAcceptableArguments() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(String input, InjectedValueAccess context) {
|
||||
return limitByPrefix(getSideEffects().stream().map(sideEffect -> sideEffect.name().toLowerCase(Locale.US)), input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversionResult<SideEffect> convert(String argument, InjectedValueAccess context) {
|
||||
try {
|
||||
return SuccessfulConversion.fromSingle(SideEffect.valueOf(argument.toUpperCase(Locale.US)));
|
||||
} catch (Exception e) {
|
||||
return FailedConversion.from(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,14 +21,17 @@ package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a platform that WorldEdit has been implemented for.
|
||||
@ -174,4 +177,5 @@ public interface Platform {
|
||||
*/
|
||||
Map<Capability, Preference> getCapabilities();
|
||||
|
||||
Set<SideEffect> getSupportedSideEffects();
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ import com.sk89q.worldedit.command.argument.ExpressionConverter;
|
||||
import com.sk89q.worldedit.command.argument.FactoryConverter;
|
||||
import com.sk89q.worldedit.command.argument.RegionFactoryConverter;
|
||||
import com.sk89q.worldedit.command.argument.RegistryConverter;
|
||||
import com.sk89q.worldedit.command.argument.SideEffectConverter;
|
||||
import com.sk89q.worldedit.command.argument.VectorConverter;
|
||||
import com.sk89q.worldedit.command.argument.WorldConverter;
|
||||
import com.sk89q.worldedit.command.argument.ZonedDateTimeConverter;
|
||||
@ -255,6 +256,7 @@ public final class PlatformCommandManager {
|
||||
RegionFactoryConverter.register(commandManager);
|
||||
WorldConverter.register(commandManager);
|
||||
ExpressionConverter.register(commandManager);
|
||||
SideEffectConverter.register(commandManager);
|
||||
|
||||
registerBindings(new ConsumeBindings(worldEdit, this));
|
||||
registerBindings(new PrimitiveBindings(worldEdit));
|
||||
|
@ -48,9 +48,11 @@ import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -304,6 +306,10 @@ public class PlatformManager {
|
||||
return queryCapability(Capability.CONFIGURATION).getConfiguration();
|
||||
}
|
||||
|
||||
public Collection<SideEffect> getSupportedSideEffects() {
|
||||
return queryCapability(Capability.WORLD_EDITING).getSupportedSideEffects();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handlePlatformReady(PlatformReadyEvent event) {
|
||||
choosePreferred();
|
||||
|
@ -21,17 +21,16 @@ package com.sk89q.worldedit.extent.buffer;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.collection.BlockMap;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Buffers changes to an {@link Extent} and allows retrieval of the changed blocks,
|
||||
@ -39,7 +38,7 @@ import java.util.Optional;
|
||||
*/
|
||||
public class ExtentBuffer extends AbstractBufferingExtent {
|
||||
|
||||
private final Map<BlockVector3, BaseBlock> buffer = Maps.newHashMap();
|
||||
private final Map<BlockVector3, BaseBlock> buffer = BlockMap.create();
|
||||
private final Mask mask;
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
@ -27,67 +27,38 @@ import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.collection.BlockMap;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Implements "fast mode" which may skip physics, lighting, etc.
|
||||
* An extent that sets blocks in the world, with a {@link SideEffectSet}.
|
||||
*/
|
||||
public class FastModeExtent extends AbstractDelegateExtent {
|
||||
public class SideEffectExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final World world;
|
||||
private final Set<BlockVector3> positions = new HashSet<>();
|
||||
private final Map<BlockVector3, BlockState> positions = BlockMap.create();
|
||||
private final Set<BlockVector2> dirtyChunks = new HashSet<>();
|
||||
private boolean enabled = true;
|
||||
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
|
||||
private boolean postEditSimulation;
|
||||
|
||||
/**
|
||||
* Create a new instance with fast mode enabled.
|
||||
*
|
||||
* @param world the world
|
||||
*/
|
||||
public FastModeExtent(World world) {
|
||||
this(world, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param world the world
|
||||
* @param enabled true to enable fast mode
|
||||
*/
|
||||
public FastModeExtent(World world, boolean enabled) {
|
||||
public SideEffectExtent(World world) {
|
||||
super(world);
|
||||
checkNotNull(world);
|
||||
this.world = world;
|
||||
this.enabled = enabled;
|
||||
if (enabled) {
|
||||
this.postEditSimulation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether fast mode is enabled.
|
||||
*
|
||||
* @return true if fast mode is enabled
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fast mode enable status.
|
||||
*
|
||||
* @param enabled true to enable fast mode
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isPostEditSimulationEnabled() {
|
||||
@ -98,26 +69,28 @@ public class FastModeExtent extends AbstractDelegateExtent {
|
||||
this.postEditSimulation = enabled;
|
||||
}
|
||||
|
||||
public SideEffectSet getSideEffectSet() {
|
||||
return this.sideEffectSet;
|
||||
}
|
||||
|
||||
public void setSideEffectSet(SideEffectSet sideEffectSet) {
|
||||
this.sideEffectSet = sideEffectSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
if (enabled || postEditSimulation) {
|
||||
if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.DELAYED) {
|
||||
dirtyChunks.add(BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4));
|
||||
|
||||
if (world.setBlock(location, block, false)) {
|
||||
if (!enabled && postEditSimulation) {
|
||||
positions.add(location);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return world.setBlock(location, block, true);
|
||||
}
|
||||
if (postEditSimulation) {
|
||||
positions.put(location, world.getBlock(location));
|
||||
}
|
||||
|
||||
return world.setBlock(location, block, postEditSimulation ? SideEffectSet.none() : sideEffectSet);
|
||||
}
|
||||
|
||||
public boolean commitRequired() {
|
||||
return enabled || postEditSimulation;
|
||||
return postEditSimulation || !dirtyChunks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -132,11 +105,11 @@ public class FastModeExtent extends AbstractDelegateExtent {
|
||||
world.fixAfterFastMode(dirtyChunks);
|
||||
}
|
||||
|
||||
if (!enabled && postEditSimulation) {
|
||||
Iterator<BlockVector3> positionIterator = positions.iterator();
|
||||
if (postEditSimulation) {
|
||||
Iterator<Map.Entry<BlockVector3, BlockState>> positionIterator = positions.entrySet().iterator();
|
||||
while (run.shouldContinue() && positionIterator.hasNext()) {
|
||||
BlockVector3 position = positionIterator.next();
|
||||
world.notifyAndLightBlock(position, BlockTypes.AIR.getDefaultState());
|
||||
Map.Entry<BlockVector3, BlockState> position = positionIterator.next();
|
||||
world.applySideEffects(position.getKey(), position.getValue(), sideEffectSet);
|
||||
positionIterator.remove();
|
||||
}
|
||||
|
||||
@ -151,5 +124,4 @@ public class FastModeExtent extends AbstractDelegateExtent {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public enum SideEffect {
|
||||
LIGHTING(State.ON),
|
||||
NEIGHBORS(State.ON),
|
||||
CONNECTIONS(State.ON),
|
||||
ENTITY_AI(State.OFF),
|
||||
PLUGIN_EVENTS(State.OFF);
|
||||
|
||||
private final String displayName;
|
||||
private final String description;
|
||||
private final State defaultValue;
|
||||
|
||||
SideEffect(State defaultValue) {
|
||||
this.displayName = "worldedit.sideeffect." + this.name().toLowerCase(Locale.US);
|
||||
this.description = "worldedit.sideeffect." + this.name().toLowerCase(Locale.US) + ".description";
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public State getDefaultValue() {
|
||||
return this.defaultValue;
|
||||
}
|
||||
|
||||
public enum State {
|
||||
OFF,
|
||||
ON,
|
||||
DELAYED;
|
||||
|
||||
private final String displayName;
|
||||
|
||||
State() {
|
||||
this.displayName = "worldedit.sideeffect.state." + this.name().toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SideEffectSet {
|
||||
private static final SideEffectSet DEFAULT = new SideEffectSet(
|
||||
Arrays.stream(SideEffect.values()).collect(Collectors.toMap(Function.identity(), SideEffect::getDefaultValue))
|
||||
);
|
||||
private static final SideEffectSet NONE = new SideEffectSet();
|
||||
|
||||
private final Map<SideEffect, SideEffect.State> sideEffects;
|
||||
private final Set<SideEffect> appliedSideEffects;
|
||||
private final boolean appliesAny;
|
||||
|
||||
private SideEffectSet() {
|
||||
this(ImmutableMap.of());
|
||||
}
|
||||
|
||||
public SideEffectSet(Map<SideEffect, SideEffect.State> sideEffects) {
|
||||
this.sideEffects = Maps.immutableEnumMap(sideEffects);
|
||||
|
||||
appliedSideEffects = sideEffects.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue() != SideEffect.State.OFF)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
appliesAny = !appliedSideEffects.isEmpty();
|
||||
}
|
||||
|
||||
public SideEffectSet with(SideEffect sideEffect, SideEffect.State state) {
|
||||
Map<SideEffect, SideEffect.State> entries = this.sideEffects.isEmpty() ? Maps.newEnumMap(SideEffect.class) : new EnumMap<>(this.sideEffects);
|
||||
entries.put(sideEffect, state);
|
||||
return new SideEffectSet(entries);
|
||||
}
|
||||
|
||||
public boolean doesApplyAny() {
|
||||
return this.appliesAny;
|
||||
}
|
||||
|
||||
public SideEffect.State getState(SideEffect effect) {
|
||||
return sideEffects.getOrDefault(effect, effect.getDefaultValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this side effect is not off.
|
||||
*
|
||||
* This returns whether it is either delayed or on.
|
||||
*
|
||||
* @param effect The side effect
|
||||
* @return Whether it should apply
|
||||
*/
|
||||
public boolean shouldApply(SideEffect effect) {
|
||||
return getState(effect) != SideEffect.State.OFF;
|
||||
}
|
||||
|
||||
public Set<SideEffect> getSideEffectsToApply() {
|
||||
return this.appliedSideEffects;
|
||||
}
|
||||
|
||||
public static SideEffectSet defaults() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
public static SideEffectSet none() {
|
||||
return NONE;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.util.formatting.component;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SideEffectBox extends PaginationBox {
|
||||
|
||||
private static List<SideEffect> sideEffects;
|
||||
|
||||
private SideEffectSet sideEffectSet;
|
||||
|
||||
private static List<SideEffect> getSideEffects() {
|
||||
if (sideEffects == null) {
|
||||
sideEffects = WorldEdit.getInstance().getPlatformManager().getSupportedSideEffects()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(Enum::name))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return sideEffects;
|
||||
}
|
||||
|
||||
public SideEffectBox(SideEffectSet sideEffectSet) {
|
||||
super("Side Effects");
|
||||
|
||||
this.sideEffectSet = sideEffectSet;
|
||||
}
|
||||
|
||||
private static final SideEffect.State[] SHOWN_VALUES = {SideEffect.State.OFF, SideEffect.State.ON};
|
||||
|
||||
@Override
|
||||
public Component getComponent(int number) {
|
||||
SideEffect effect = getSideEffects().get(number);
|
||||
SideEffect.State state = this.sideEffectSet.getState(effect);
|
||||
|
||||
TextComponent.Builder builder = TextComponent.builder();
|
||||
builder = builder.append(TranslatableComponent.of(effect.getDisplayName(), TextColor.YELLOW)
|
||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of(effect.getDescription()))));
|
||||
for (SideEffect.State uiState : SHOWN_VALUES) {
|
||||
builder = builder.append(TextComponent.space());
|
||||
builder = builder.append(TranslatableComponent.of(uiState.getDisplayName(), uiState == state ? TextColor.WHITE : TextColor.GRAY)
|
||||
.clickEvent(ClickEvent.runCommand("//fast -h " + effect.name().toLowerCase(Locale.US) + " " + uiState.name().toLowerCase(Locale.US)))
|
||||
.hoverEvent(HoverEvent.showText(uiState == state
|
||||
? TranslatableComponent.of("worldedit.sideeffect.box.current")
|
||||
: TranslatableComponent.of("worldedit.sideeffect.box.change-to", TranslatableComponent.of(uiState.getDisplayName()))
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComponentsSize() {
|
||||
return getSideEffects().size();
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -57,7 +58,7 @@ public abstract class AbstractWorld implements World {
|
||||
|
||||
@Override
|
||||
public final <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 pt, B block) throws WorldEditException {
|
||||
return setBlock(pt, block, true);
|
||||
return setBlock(pt, block, SideEffectSet.defaults());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,7 @@ import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||
import com.boydti.fawe.beta.implementation.blocks.NullChunkGet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -35,6 +36,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
@ -48,6 +51,7 @@ import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A null implementation of {@link World} that drops all changes and
|
||||
@ -71,13 +75,14 @@ public class NullWorld extends AbstractWorld {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
|
||||
return false;
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet)
|
||||
throws WorldEditException {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,15 +37,19 @@ import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.Keyed;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a world (dimension).
|
||||
@ -112,10 +116,28 @@ public interface World extends Extent, Keyed, IChunkCache<IChunkGet> {
|
||||
* @param notifyAndLight true to to notify and light
|
||||
* @return true if the block was successfully set (return value may not be accurate)
|
||||
*/
|
||||
@Deprecated
|
||||
default <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
return setBlock(position, block);
|
||||
return setBlock(position, block, notifyAndLight ? SideEffectSet.defaults() : SideEffectSet.none());
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link Extent#setBlock(BlockVector3, BlockStateHolder)} but a
|
||||
* {@code sideEffects} parameter indicates which side effects should be applied
|
||||
* to the block. This includes block updates, lighting, and others. See {@link SideEffect}
|
||||
* for a full list.
|
||||
*
|
||||
* <p>Not all implementations support all side effects. Use
|
||||
* {@link Platform#getSupportedSideEffects()} for a list of supported side effects.
|
||||
* Non-supported side effects will be ignored.</p>
|
||||
*
|
||||
* @param position position of the block
|
||||
* @param block block to set
|
||||
* @param sideEffects which side effects to perform
|
||||
* @return true if the block was successfully set (return value may not be accurate)
|
||||
*/
|
||||
<B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException;
|
||||
|
||||
/**
|
||||
* Notifies the simulation that the block at the given location has
|
||||
* been changed and it must be re-lighted (and issue other events).
|
||||
@ -124,7 +146,20 @@ public interface World extends Extent, Keyed, IChunkCache<IChunkGet> {
|
||||
* @param previousType the type of the previous block that was there
|
||||
* @return true if the block was successfully notified
|
||||
*/
|
||||
boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException;
|
||||
@Deprecated
|
||||
default boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
|
||||
return !applySideEffects(position, previousType, SideEffectSet.defaults()).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a set of side effects on the given block.
|
||||
*
|
||||
* @param position position of the block
|
||||
* @param previousType the type of the previous block that was there
|
||||
* @param sideEffectSet which side effects to perform
|
||||
* @return a set of side effects that were applied
|
||||
*/
|
||||
Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException;
|
||||
|
||||
/**
|
||||
* Get the light level at the given block.
|
||||
|
@ -210,6 +210,10 @@
|
||||
"worldedit.fast.enabled": "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.",
|
||||
"worldedit.fast.disabled.already": "Fast mode already disabled.",
|
||||
"worldedit.fast.enabled.already": "Fast mode already enabled.",
|
||||
"worldedit.fast.sideeffect.set": "Side effect \"{0}\" set to {1}",
|
||||
"worldedit.fast.sideeffect.get": "Side effect \"{0}\" is set to {1}",
|
||||
"worldedit.fast.sideeffect.already-set": "Side effect \"{0}\" is already {1}",
|
||||
"worldedit.fast.sideeffect.set-all": "All side effects set to {0}",
|
||||
"worldedit.reorder.current": "The reorder mode is {0}",
|
||||
"worldedit.reorder.set": "The reorder mode is now {0}",
|
||||
"worldedit.gmask.disabled": "Global mask disabled.",
|
||||
@ -494,6 +498,22 @@
|
||||
"worldedit.selection.sphere.explain.secondary": "Radius set to {0}.",
|
||||
"worldedit.selection.sphere.explain.secondary-defined": "Radius set to {0} ({1}).",
|
||||
|
||||
"worldedit.sideeffect.lighting": "Lighting",
|
||||
"worldedit.sideeffect.lighting.description": "Updates block lighting",
|
||||
"worldedit.sideeffect.neighbors": "Neighbors",
|
||||
"worldedit.sideeffect.neighbors.description": "Notifies nearby blocks of changes",
|
||||
"worldedit.sideeffect.connections": "Connections",
|
||||
"worldedit.sideeffect.connections.description": "Updates connections for blocks like fences",
|
||||
"worldedit.sideeffect.entity_ai": "Entity AI",
|
||||
"worldedit.sideeffect.entity_ai.description": "Updates Entity AI paths for the block changes",
|
||||
"worldedit.sideeffect.plugin_events": "Plugin Events",
|
||||
"worldedit.sideeffect.plugin_events.description": "Tells other plugins/mods about these changes when applicable",
|
||||
"worldedit.sideeffect.state.on": "On",
|
||||
"worldedit.sideeffect.state.delayed": "Delayed",
|
||||
"worldedit.sideeffect.state.off": "Off",
|
||||
"worldedit.sideeffect.box.current": "Current",
|
||||
"worldedit.sideeffect.box.change-to": "Click to set to {0}",
|
||||
|
||||
"worldedit.help.command-not-found": "The command '{0}' could not be found.",
|
||||
"worldedit.help.no-subcommands": "'{0}' has no sub-commands. (Maybe '{1}' is for a parameter?)",
|
||||
"worldedit.help.subcommand-not-found": "The sub-command '{0}' under '{1}' could not be found.",
|
||||
|
@ -61,16 +61,12 @@ tasks.named<Copy>("processResources") {
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
addJarManifest(includeClasspath = true)
|
||||
=======
|
||||
tasks.named<Jar>("jar") {
|
||||
manifest {
|
||||
attributes("Class-Path" to CLASSPATH,
|
||||
"WorldEdit-Version" to project.version)
|
||||
}
|
||||
}
|
||||
>>>>>>> 18a55bc14... Add new experimental snapshot API (#524)
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist-dev")
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.fabric;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.command.util.PermissionCondition;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
|
||||
@ -27,13 +28,13 @@ import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
@ -200,6 +201,18 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||
SideEffect.CONNECTIONS,
|
||||
SideEffect.ENTITY_AI,
|
||||
SideEffect.LIGHTING,
|
||||
SideEffect.NEIGHBORS
|
||||
);
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return SUPPORTED_SIDE_EFFECTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Actor> getConnectedUsers() {
|
||||
List<Actor> users = new ArrayList<>();
|
||||
|
@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.Files;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
@ -42,6 +43,8 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -61,6 +64,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUsageContext;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.WorldGenerationProgressListener;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
@ -71,6 +75,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldSaveHandler;
|
||||
import net.minecraft.world.biome.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkManager;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
@ -104,6 +109,7 @@ import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
@ -185,8 +191,44 @@ public class FabricWorld extends AbstractWorld {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void markAndNotifyBlock(World world, BlockPos pos, @Nullable WorldChunk worldChunk, net.minecraft.block.BlockState blockState,
|
||||
net.minecraft.block.BlockState state, SideEffectSet sideEffectSet) {
|
||||
Block block = state.getBlock();
|
||||
net.minecraft.block.BlockState blockState2 = world.getBlockState(pos);
|
||||
if (blockState2 == state) {
|
||||
if (blockState != blockState2) {
|
||||
world.checkBlockRerender(pos, blockState, blockState2);
|
||||
}
|
||||
|
||||
if (world.isClient || worldChunk.getLevelType() != null && worldChunk.getLevelType().isAfter(ChunkHolder.LevelType.TICKING)) {
|
||||
if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) {
|
||||
world.updateListeners(pos, blockState, state, UPDATE | NOTIFY);
|
||||
} else {
|
||||
// If we want to skip entity AI, just call the chunk dirty flag.
|
||||
((ServerChunkManager) world.getChunkManager()).markForUpdate(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isClient && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
|
||||
world.updateNeighbors(pos, blockState.getBlock());
|
||||
if (state.hasComparatorOutput()) {
|
||||
world.updateHorizontalAdjacent(pos, block);
|
||||
}
|
||||
}
|
||||
|
||||
if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) {
|
||||
blockState.method_11637(world, pos, 2);
|
||||
state.updateNeighborStates(world, pos, 2);
|
||||
state.method_11637(world, pos, 2);
|
||||
}
|
||||
|
||||
// This is disabled for other platforms, but keep it for mods.
|
||||
world.onBlockChanged(pos, blockState, blockState2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
checkNotNull(position);
|
||||
checkNotNull(block);
|
||||
|
||||
@ -196,7 +238,7 @@ public class FabricWorld extends AbstractWorld {
|
||||
int z = position.getBlockZ();
|
||||
|
||||
// First set the block
|
||||
Chunk chunk = world.getChunk(x >> 4, z >> 4);
|
||||
WorldChunk chunk = world.getChunk(x >> 4, z >> 4);
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
net.minecraft.block.BlockState old = chunk.getBlockState(pos);
|
||||
OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState());
|
||||
@ -221,26 +263,27 @@ public class FabricWorld extends AbstractWorld {
|
||||
}
|
||||
}
|
||||
|
||||
if (successful && notifyAndLight) {
|
||||
world.getChunkManager().getLightingProvider().enqueueLightUpdate(pos);
|
||||
world.scheduleBlockRender(pos, old, newState);
|
||||
world.updateListeners(pos, old, newState, UPDATE | NOTIFY);
|
||||
world.updateNeighbors(pos, newState.getBlock());
|
||||
if (old.hasComparatorOutput()) {
|
||||
world.updateHorizontalAdjacent(pos, newState.getBlock());
|
||||
if (successful) {
|
||||
if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
world.getChunkManager().getLightingProvider().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects);
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ());
|
||||
net.minecraft.block.BlockState state = getWorld().getBlockState(pos);
|
||||
getWorld().updateListeners(pos, FabricAdapter.adapt(previousType), state, 1 | 2);
|
||||
getWorld().updateNeighbors(pos, state.getBlock());
|
||||
return true;
|
||||
net.minecraft.block.BlockState oldData = FabricAdapter.adapt(previousType);
|
||||
net.minecraft.block.BlockState newData = getWorld().getBlockState(pos);
|
||||
|
||||
if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
getWorld().getChunkManager().getLightingProvider().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update
|
||||
return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,7 +77,12 @@ tasks.named<Copy>("processResources") {
|
||||
}
|
||||
}
|
||||
|
||||
addJarManifest(includeClasspath = false)
|
||||
tasks.named<Jar>("jar") {
|
||||
manifest {
|
||||
attributes("Class-Path" to CLASSPATH,
|
||||
"WorldEdit-Version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
dependencies {
|
||||
|
@ -27,6 +27,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
@ -206,6 +207,18 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||
SideEffect.CONNECTIONS,
|
||||
SideEffect.ENTITY_AI,
|
||||
SideEffect.LIGHTING,
|
||||
SideEffect.NEIGHBORS
|
||||
);
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return SUPPORTED_SIDE_EFFECTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Actor> getConnectedUsers() {
|
||||
List<Actor> users = new ArrayList<>();
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.forge;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
@ -96,13 +98,13 @@ import net.minecraft.world.gen.feature.SwampTreeFeature;
|
||||
import net.minecraft.world.gen.feature.TallTaigaTreeFeature;
|
||||
import net.minecraft.world.gen.feature.TreeFeature;
|
||||
|
||||
import net.minecraft.world.server.ChunkHolder;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
@ -117,7 +119,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An adapter to Minecraft worlds for WorldEdit.
|
||||
@ -192,8 +194,51 @@ public class ForgeWorld extends AbstractWorld {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a heavily modified function stripped from MC to apply worldedit-modifications.
|
||||
*
|
||||
* @see World#markAndNotifyBlock
|
||||
*/
|
||||
public void markAndNotifyBlock(World world, BlockPos pos, @Nullable Chunk chunk, net.minecraft.block.BlockState blockstate,
|
||||
net.minecraft.block.BlockState newState, SideEffectSet sideEffectSet) {
|
||||
Block block = newState.getBlock();
|
||||
net.minecraft.block.BlockState blockstate1 = world.getBlockState(pos);
|
||||
if (blockstate1 == newState) {
|
||||
if (blockstate != blockstate1) {
|
||||
world.markBlockRangeForRenderUpdate(pos, blockstate, blockstate1);
|
||||
}
|
||||
|
||||
// Remove redundant branches
|
||||
if (world.isRemote || chunk == null || chunk.getLocationType().isAtLeast(ChunkHolder.LocationType.TICKING)) {
|
||||
if (sideEffectSet.shouldApply(SideEffect.ENTITY_AI)) {
|
||||
world.notifyBlockUpdate(pos, blockstate, newState, UPDATE | NOTIFY);
|
||||
} else {
|
||||
// If we want to skip entity AI, just call the chunk dirty flag.
|
||||
((ServerChunkProvider) world.getChunkProvider()).markBlockChanged(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isRemote && sideEffectSet.shouldApply(SideEffect.NEIGHBORS)) {
|
||||
world.notifyNeighbors(pos, blockstate.getBlock());
|
||||
if (newState.hasComparatorInputOverride()) {
|
||||
world.updateComparatorOutputLevel(pos, block);
|
||||
}
|
||||
}
|
||||
|
||||
// Make connection updates optional
|
||||
if (sideEffectSet.shouldApply(SideEffect.CONNECTIONS)) {
|
||||
blockstate.updateDiagonalNeighbors(world, pos, 2);
|
||||
newState.updateNeighbors(world, pos, 2);
|
||||
newState.updateDiagonalNeighbors(world, pos, 2);
|
||||
}
|
||||
|
||||
// This is disabled for other platforms, but keep it for mods.
|
||||
world.onBlockStateChange(pos, blockstate, blockstate1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
checkNotNull(position);
|
||||
checkNotNull(block);
|
||||
|
||||
@ -224,19 +269,27 @@ public class ForgeWorld extends AbstractWorld {
|
||||
}
|
||||
}
|
||||
|
||||
if (successful && notifyAndLight) {
|
||||
world.getChunkProvider().getLightManager().checkBlock(pos);
|
||||
world.markAndNotifyBlock(pos, chunk, old, newState, UPDATE | NOTIFY);
|
||||
if (successful) {
|
||||
if (sideEffects.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
world.getChunkProvider().getLightManager().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(world, pos, chunk, old, newState, sideEffects);
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ());
|
||||
getWorld().notifyBlockUpdate(pos, ForgeAdapter.adapt(previousType), getWorld().getBlockState(pos), 1 | 2);
|
||||
return true;
|
||||
net.minecraft.block.BlockState oldData = ForgeAdapter.adapt(previousType);
|
||||
net.minecraft.block.BlockState newData = getWorld().getBlockState(pos);
|
||||
|
||||
if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.ON) {
|
||||
getWorld().getChunkProvider().getLightManager().checkBlock(pos);
|
||||
}
|
||||
markAndNotifyBlock(getWorld(), pos, null, oldData, newData, sideEffectSet); // Update
|
||||
return Sets.intersection(ForgeWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,6 +20,8 @@
|
||||
package com.sk89q.worldedit.sponge;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||
@ -31,6 +33,7 @@ import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.internal.command.CommandUtil;
|
||||
import com.sk89q.worldedit.sponge.config.SpongeConfiguration;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
import org.enginehub.piston.Command;
|
||||
@ -50,6 +53,7 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@ -192,6 +196,11 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Actor> getConnectedUsers() {
|
||||
List<Actor> users = new ArrayList<>();
|
||||
|
Loading…
Reference in New Issue
Block a user