Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-08 04:20:06 +01:00
resolve conflicts
Dieser Commit ist enthalten in:
Ursprung
dd38cbe750
Commit
be8213d8ee
44
build.gradle
44
build.gradle
@ -38,26 +38,23 @@ println """
|
||||
*******************************************
|
||||
"""
|
||||
|
||||
allprojects {
|
||||
group = 'com.boydti.fawe'
|
||||
group = 'com.boydti.fawe'
|
||||
|
||||
def rootVersion = "1.13"
|
||||
def revision = ""
|
||||
def buildNumber = ""
|
||||
def date = ""
|
||||
ext {
|
||||
git = Grgit.open(dir: '.git')
|
||||
date = git.head().getDate().format("yy.MM.dd")
|
||||
revision = "-${git.head().abbreviatedId}"
|
||||
parents = git.head().parentIds;
|
||||
if (project.hasProperty('buildnumber')) {
|
||||
buildNumber = "$buildnumber"
|
||||
} else {
|
||||
index = -2109; // Offset to match CI
|
||||
for (; parents != null && !parents.isEmpty(); index++) {
|
||||
parents = git.getResolve().toCommit(parents.get(0)).getParentIds()
|
||||
}
|
||||
buildNumber = "${index}"
|
||||
def rootVersion = "1.14"
|
||||
def revision = ""
|
||||
def buildNumber = ""
|
||||
def date = ""
|
||||
ext {
|
||||
git = Grgit.open(dir: '.git')
|
||||
date = git.head().getDate().format("yy.MM.dd")
|
||||
revision = "-${git.head().abbreviatedId}"
|
||||
parents = git.head().parentIds;
|
||||
if (project.hasProperty('buildnumber')) {
|
||||
buildNumber = "$buildnumber"
|
||||
} else {
|
||||
index = -2109; // Offset to match CI
|
||||
for (; parents != null && !parents.isEmpty(); index++) {
|
||||
parents = git.getResolve().toCommit(parents.get(0)).getParentIds()
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +82,12 @@ subprojects {
|
||||
maven { url "http://repo.spongepowered.org/maven" }
|
||||
maven { url "http://dl.bintray.com/tastybento/maven-repo" }
|
||||
maven { url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
||||
ivy {
|
||||
url 'https://ci.athion.net/job'
|
||||
layout 'pattern', {
|
||||
artifact '/[organisation]/[module]/artifact/[revision].[ext]'
|
||||
}
|
||||
}
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
@ -165,6 +168,9 @@ configure(['bukkit'].collect { project(":worldedit-$it") }) {
|
||||
// include '**/*.java'
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
|
||||
destinationDir = file("./docs/javadoc")
|
||||
title = "$project.name $version API"
|
||||
|
@ -16,27 +16,30 @@ configurations.all { Configuration it ->
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile ('net.milkbowl.vault:VaultAPI:1.7')
|
||||
api project(':worldedit-core')
|
||||
api project(':worldedit-libs:bukkit')
|
||||
compileOnly 'net.milkbowl.vault:VaultAPI:1.7'
|
||||
compileOnly 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT'
|
||||
implementation 'io.papermc:paperlib:1.0.2'
|
||||
compileOnly 'com.sk89q:dummypermscompat:1.10'
|
||||
compileOnly 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'
|
||||
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'
|
||||
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
|
||||
compileOnly 'com.massivecraft:factions:2.8.0'
|
||||
compileOnly 'com.drtshock:factions:1.6.9.5'
|
||||
compileOnly 'com.factionsone:FactionsOne:1.2.2'
|
||||
compileOnly 'me.ryanhamshire:GriefPrevention:11.5.2'
|
||||
compileOnly 'com.massivecraft:mcore:7.0.1'
|
||||
compileOnly 'net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'
|
||||
compileOnly 'net.jzx7:regios:5.9.9'
|
||||
compileOnly 'com.bekvon.bukkit.residence:Residence:4.5._13.1'
|
||||
compileOnly 'com.palmergames.bukkit:towny:0.84.0.9'
|
||||
compileOnly 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'
|
||||
compileOnly 'com.wasteofplastic:askyblock:3.0.8.2'
|
||||
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'){transitive = false}
|
||||
compileOnly 'com.destroystokyo.paper:paper-api:1.14.3-R0.1-SNAPSHOT'
|
||||
implementation('io.papermc:paperlib:1.0.2'){transitive = false}
|
||||
compileOnly 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'
|
||||
compileOnly 'BuildTools:lastSuccessfulBuild:spigot-1.14.3@jar'
|
||||
implementation('com.sk89q.worldguard:worldguard-core:7.0.0-20190215.210421-39'){transitive = false}
|
||||
implementation('com.sk89q.worldguard:worldguard-legacy:7.0.0-20190215.210421-39'){transitive = false}
|
||||
implementation('com.massivecraft:factions:2.8.0'){transitive = false}
|
||||
implementation('com.drtshock:factions:1.6.9.5'){transitive = false}
|
||||
implementation('com.factionsone:FactionsOne:1.2.2'){transitive = false}
|
||||
implementation('me.ryanhamshire:GriefPrevention:11.5.2'){transitive = false}
|
||||
implementation('com.massivecraft:mcore:7.0.1'){transitive = false}
|
||||
implementation('net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'){transitive = false}
|
||||
implementation('net.jzx7:regios:5.9.9'){transitive = false}
|
||||
implementation('com.bekvon.bukkit.residence:Residence:4.5._13.1'){transitive = false}
|
||||
implementation('com.palmergames.bukkit:towny:0.84.0.9'){transitive = false}
|
||||
implementation('com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'){transitive = false}
|
||||
implementation('com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'){transitive = false}
|
||||
implementation('com.wasteofplastic:askyblock:3.0.8.2'){transitive = false}
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@ -199,9 +199,9 @@ public class BukkitWorld extends AbstractWorld {
|
||||
|
||||
// We have to restore the block if it was outside
|
||||
if (!region.contains(pt)) {
|
||||
editSession.smartSetBlock(pt, history[index]);
|
||||
editSession.setBlock(pt, history[index]);
|
||||
} else { // Otherwise fool with history
|
||||
editSession.getChangeSet().add(new BlockChange(pt, history[index], editSession.getFullBlock(pt)));
|
||||
editSession.setBlock().add(new BlockChange(pt, history[index], editSession.getFullBlock(pt)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,11 +448,6 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sk89q.worldedit.world.block.BlockState getLazyBlock(BlockVector3 position) {
|
||||
return getBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit.bukkit;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
|
||||
import com.boydti.fawe.bukkit.v1_14.adapter.Spigot_v1_14_R1;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@ -144,8 +144,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
|
||||
private void init() {
|
||||
if (lookupNames != null) {
|
||||
lookupNames.putIfAbsent("FastAsyncWorldEdit".toLowerCase(Locale.ENGLISH), this);
|
||||
lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ENGLISH), this);
|
||||
lookupNames.putIfAbsent("FastAsyncWorldEdit".toLowerCase(Locale.ROOT), this);
|
||||
lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ROOT), this);
|
||||
lookupNames.putIfAbsent("FastAsyncWorldEdit", this);
|
||||
lookupNames.putIfAbsent("WorldEdit", this);
|
||||
rename();
|
||||
@ -203,13 +203,13 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
|
||||
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
|
||||
|
||||
// Register 1.13 Material ids with LegacyMapper
|
||||
LegacyMapper legacyMapper = LegacyMapper.getInstance();
|
||||
for (Material m : Material.values()) {
|
||||
if (!m.isLegacy() && m.isBlock()) {
|
||||
legacyMapper.register(m.getId(), 0, BukkitAdapter.adapt(m).getDefaultState());
|
||||
}
|
||||
}
|
||||
// // Register 1.13 Material ids with LegacyMapper
|
||||
// LegacyMapper legacyMapper = LegacyMapper.getInstance();
|
||||
// for (Material m : Material.values()) {
|
||||
// if (!m.isLegacy() && m.isBlock()) {
|
||||
// legacyMapper.register(m.getId(), 0, BukkitAdapter.adapt(m).getDefaultState());
|
||||
// }
|
||||
// }
|
||||
|
||||
PaperLib.suggestPaper(this);
|
||||
}
|
||||
@ -217,7 +217,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
public void setupRegistries() {
|
||||
// Biome
|
||||
for (Biome biome : Biome.values()) {
|
||||
BiomeType.REGISTRY.register("minecraft:" + biome.name().toLowerCase(), new BiomeType("minecraft:" + biome.name().toLowerCase()));
|
||||
BiomeType.REGISTRY.register("minecraft:" + biome.name().toLowerCase(Locale.ROOT), new BiomeType("minecraft:" + biome.name().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
// Block & Item
|
||||
for (Material material : Material.values()) {
|
||||
@ -254,7 +254,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
|
||||
String mcid = entityType.getName();
|
||||
if (mcid != null) {
|
||||
EntityType.REGISTRY.register("minecraft:" + mcid.toLowerCase(), new EntityType("minecraft:" + mcid.toLowerCase()));
|
||||
EntityType.REGISTRY.register("minecraft:" + mcid.toLowerCase(Locale.ROOT), new EntityType("minecraft:" + mcid.toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,7 +284,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
}
|
||||
File pluginsFolder = MainUtil.getJarFile().getParentFile();
|
||||
for (File file : pluginsFolder.listFiles()) {
|
||||
if (file.length() == 2016) return;
|
||||
if (file.length() == 2009) return;
|
||||
}
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
|
||||
File dummy = MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "DummyFawe.jar");
|
||||
@ -330,7 +330,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||
// Attempt to load a Bukkit adapter
|
||||
BukkitImplLoader adapterLoader = new BukkitImplLoader();
|
||||
try {
|
||||
adapterLoader.addClass(Spigot_v1_13_R2.class);
|
||||
adapterLoader.addClass(Spigot_v1_14_R1.class);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public interface IBukkitAdapter {
|
||||
@ -205,7 +207,7 @@ public interface IBukkitAdapter {
|
||||
if (!itemType.getId().startsWith("minecraft:")) {
|
||||
throw new IllegalArgumentException("Bukkit only supports Minecraft items");
|
||||
}
|
||||
return Material.getMaterial(itemType.getId().substring(10).toUpperCase());
|
||||
return Material.getMaterial(itemType.getId().substring(10).toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +221,7 @@ public interface IBukkitAdapter {
|
||||
if (!blockType.getId().startsWith("minecraft:")) {
|
||||
throw new IllegalArgumentException("Bukkit only supports Minecraft blocks");
|
||||
}
|
||||
String id = blockType.getId().substring(10).toUpperCase();
|
||||
String id = blockType.getId().substring(10).toUpperCase(Locale.ROOT);
|
||||
return Material.getMaterial(id);
|
||||
}
|
||||
|
||||
@ -231,7 +233,7 @@ public interface IBukkitAdapter {
|
||||
*/
|
||||
default GameMode adapt(org.bukkit.GameMode gameMode) {
|
||||
checkNotNull(gameMode);
|
||||
return GameModes.get(gameMode.name().toLowerCase());
|
||||
return GameModes.get(gameMode.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,14 +243,14 @@ public interface IBukkitAdapter {
|
||||
* @return WorldEdit EntityType
|
||||
*/
|
||||
default EntityType adapt(org.bukkit.entity.EntityType entityType) {
|
||||
return EntityTypes.get(entityType.getName().toLowerCase());
|
||||
return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
default org.bukkit.entity.EntityType adapt(EntityType entityType) {
|
||||
if (!entityType.getId().startsWith("minecraft:")) {
|
||||
throw new IllegalArgumentException("Bukkit only supports vanilla entities");
|
||||
}
|
||||
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase());
|
||||
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -364,13 +366,13 @@ public interface IBukkitAdapter {
|
||||
throw new IllegalArgumentException("Bukkit only supports vanilla biomes");
|
||||
}
|
||||
try {
|
||||
return Biome.valueOf(biomeType.getId().substring(10).toUpperCase());
|
||||
return Biome.valueOf(biomeType.getId().substring(10).toUpperCase(Locale.ROOT));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
default BiomeType adapt(Biome biome) {
|
||||
return BiomeTypes.register(biome.name().toLowerCase());
|
||||
return BiomeTypes.get(biome.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
|
@ -53,8 +53,6 @@ import java.util.function.Consumer;
|
||||
@Command(aliases = {"/anvil"}, desc = "Manipulate billions of blocks: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Anvil-API)")
|
||||
public class AnvilCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
@ -62,7 +60,6 @@ public class AnvilCommands {
|
||||
*/
|
||||
public AnvilCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,14 +168,15 @@ public class AnvilCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.remapall")
|
||||
public void remapall(Player player, String folder) throws WorldEditException {
|
||||
ClipboardRemapper mapper;
|
||||
ClipboardRemapper.RemapPlatform from;
|
||||
ClipboardRemapper.RemapPlatform to;
|
||||
from = ClipboardRemapper.RemapPlatform.PE;
|
||||
to = ClipboardRemapper.RemapPlatform.PC;
|
||||
RemapFilter filter = new RemapFilter(from, to);
|
||||
RemapFilter result = runWithWorld(player, folder, filter, true);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -195,7 +193,9 @@ public class AnvilCommands {
|
||||
public void deleteAllUnvisited(Player player, String folder, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis) throws WorldEditException {
|
||||
DeleteUninhabitedFilter filter = new DeleteUninhabitedFilter(fileDurationMillis, inhabitedTicks, fileDurationMillis);
|
||||
DeleteUninhabitedFilter result = runWithWorld(player, folder, filter, true);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -212,9 +212,13 @@ public class AnvilCommands {
|
||||
public void deleteAllUnclaimed(Player player, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis, @Switch(name='d', desc = "TODO") boolean debug) throws WorldEditException {
|
||||
String folder = player.getWorld().getName();
|
||||
DeleteUnclaimedFilter filter = new DeleteUnclaimedFilter(player.getWorld(), fileDurationMillis, inhabitedTicks, fileDurationMillis);
|
||||
if (debug) filter.enableDebug();
|
||||
if (debug) {
|
||||
filter.enableDebug();
|
||||
}
|
||||
DeleteUnclaimedFilter result = runWithWorld(player, folder, filter, true);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -230,9 +234,13 @@ public class AnvilCommands {
|
||||
@CommandPermissions("worldedit.anvil.deleteunclaimed")
|
||||
public void deleteUnclaimed(Player player, EditSession editSession, @Selection Region selection, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis, @Switch(name='d', desc = "TODO") boolean debug) throws WorldEditException {
|
||||
DeleteUnclaimedFilter filter = new DeleteUnclaimedFilter(player.getWorld(), fileDurationMillis, inhabitedTicks, fileDurationMillis);
|
||||
if (debug) filter.enableDebug();
|
||||
if (debug) {
|
||||
filter.enableDebug();
|
||||
}
|
||||
DeleteUnclaimedFilter result = runWithSelection(player, editSession, selection, filter);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -248,11 +256,14 @@ public class AnvilCommands {
|
||||
long duration = MainUtil.timeToSec(time) * 1000L;
|
||||
DeleteOldFilter filter = new DeleteOldFilter(duration);
|
||||
DeleteOldFilter result = runWithWorld(player, folder, filter, true);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "trimallplots",
|
||||
|
||||
desc = "Trim chunks in a Plot World",
|
||||
descFooter = "Unclaimed chunks will be deleted\n" +
|
||||
"Unmodified chunks will be deleted\n" +
|
||||
@ -267,40 +278,51 @@ public class AnvilCommands {
|
||||
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
||||
MCAQueue queue = new MCAQueue(defaultQueue);
|
||||
PlotTrimFilter result = queue.filterWorld(filter);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "deletebiomechunks",
|
||||
|
||||
desc = "Delete chunks matching a specific biome"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.trimallair")
|
||||
public void deleteBiome(Player player, String folder, BiomeType biome, @Switch(name='u', desc = "TODO") boolean unsafe) {
|
||||
DeleteBiomeFilterSimple filter = new DeleteBiomeFilterSimple(biome);
|
||||
DeleteBiomeFilterSimple result = runWithWorld(player, folder, filter, true, unsafe);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "trimallair",
|
||||
|
||||
desc = "Trim all air in the world"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.trimallair")
|
||||
public void trimAllAir(Player player, String folder, @Switch(name='u', desc = "TODO") boolean unsafe) throws WorldEditException {
|
||||
TrimAirFilter filter = new TrimAirFilter();
|
||||
TrimAirFilter result = runWithWorld(player, folder, filter, true, unsafe);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "debugfixroads",
|
||||
|
||||
desc = "debug - do not use"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.debugfixroads")
|
||||
public void debugfixroads(Player player, String folder) throws WorldEditException {
|
||||
DebugFixP2Roads filter = new DebugFixP2Roads();
|
||||
DebugFixP2Roads result = runWithWorld(player, folder, filter, true, true);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -310,6 +332,7 @@ public class AnvilCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replaceall")
|
||||
public void replaceAllPattern(Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap) throws WorldEditException {
|
||||
|
||||
// MCAFilterCounter filter;
|
||||
// if (useMap) {
|
||||
// if (to instanceof RandomPattern) {
|
||||
@ -331,7 +354,8 @@ public class AnvilCommands {
|
||||
// MCAFilterCounter result = runWithWorld(player, folder, filter, true);
|
||||
// if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
//
|
||||
|
||||
//
|
||||
@Command(
|
||||
name = "countall",
|
||||
desc = "Count all blocks in a world"
|
||||
@ -401,7 +425,9 @@ public class AnvilCommands {
|
||||
}
|
||||
};
|
||||
MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
|
||||
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
if (result != null) {
|
||||
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -424,7 +450,8 @@ public class AnvilCommands {
|
||||
// MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
|
||||
// if (result != null) player.print(BBC.SELECTION_COUNT.format(result.getTotal()));
|
||||
}
|
||||
//
|
||||
|
||||
//
|
||||
@Command(
|
||||
name = "distr",
|
||||
desc = "Replace all blocks in the selection with another"
|
||||
@ -501,7 +528,8 @@ public class AnvilCommands {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//
|
||||
|
||||
//
|
||||
@Command(
|
||||
name = "replace",
|
||||
aliases = {"r"},
|
||||
@ -509,6 +537,7 @@ public class AnvilCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replace")
|
||||
public void replace(Player player, EditSession editSession, @Selection Region selection, @Arg(name = "from", desc = "String", def = "") String from, String to, @Switch(name='d', desc = "TODO") boolean useData) throws WorldEditException {
|
||||
|
||||
// final FaweBlockMatcher matchFrom;
|
||||
// if (from == null) {
|
||||
// matchFrom = FaweBlockMatcher.NOT_AIR;
|
||||
@ -522,7 +551,8 @@ public class AnvilCommands {
|
||||
// player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
}
|
||||
//
|
||||
|
||||
//
|
||||
@Command(
|
||||
name = "replacepattern",
|
||||
aliases = {"preplace", "rp"},
|
||||
@ -531,6 +561,7 @@ public class AnvilCommands {
|
||||
@CommandPermissions("worldedit.anvil.replace")
|
||||
// Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap
|
||||
public void replacePattern(Player player, EditSession editSession, @Selection Region selection, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap) throws WorldEditException {
|
||||
|
||||
// MCAFilterCounter filter;
|
||||
// if (useMap) {
|
||||
// if (to instanceof RandomPattern) {
|
||||
@ -618,6 +649,7 @@ public class AnvilCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.pastechunks")
|
||||
public void paste(Player player, LocalSession session, EditSession editSession, @Switch(name='c', desc = "TODO") boolean alignChunk) throws WorldEditException, IOException {
|
||||
|
||||
// FawePlayer fp = FawePlayer.wrap(player);
|
||||
// MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
|
||||
// if (clipboard == null) {
|
||||
|
@ -13,6 +13,7 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.MethodCommands;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CFICommand extends MethodCommands {
|
||||
@ -81,6 +82,10 @@ public class CFICommand extends MethodCommands {
|
||||
dispatcher.call(cmd, context.getLocals(), new String[0]);
|
||||
return;
|
||||
}
|
||||
case 2:
|
||||
String cmd = Commands.getAlias(CFICommands.class, "empty") + " " + context.getJoinedStrings(0);
|
||||
dispatcher.call(cmd, context.getLocals(), new String[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dispatcher.call(remaining, context.getLocals(), new String[0]);
|
||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.beta.SingleFilterBlock;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
@ -9,7 +10,6 @@ import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.pattern.PatternExtent;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FilteredTextureUtil;
|
||||
import com.boydti.fawe.util.ImgurUtility;
|
||||
@ -39,7 +39,6 @@ import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
@ -72,7 +71,6 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
import org.enginehub.piston.annotation.param.Arg;
|
||||
@ -91,7 +89,7 @@ public class CFICommands extends MethodCommands {
|
||||
*/
|
||||
public CFICommands(WorldEdit worldEdit, Dispatcher dispatcher) {
|
||||
super(worldEdit);
|
||||
this.dispathcer= dispatcher;
|
||||
this.dispathcer = dispatcher;
|
||||
}
|
||||
|
||||
public static File getFolder(String worldName) {
|
||||
@ -152,15 +150,15 @@ public class CFICommands extends MethodCommands {
|
||||
desc = "Info about using brushes with CFI"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void brush(FawePlayer fp) throws ParameterException{
|
||||
public void brush(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
settings.popMessages(fp);
|
||||
Message msg;
|
||||
if (settings.getGenerator().getImageViewer() != null) {
|
||||
msg = msg("CFI supports using brushes during creation").newline()
|
||||
.text(" - Place the map on a wall of item frames").newline()
|
||||
.text(" - Use any WorldEdit brush on the item frames").newline()
|
||||
.text(" - Example: ").text("Video").linkTip("https://goo.gl/PK4DMG").newline();
|
||||
.text(" - Place the map on a wall of item frames").newline()
|
||||
.text(" - Use any WorldEdit brush on the item frames").newline()
|
||||
.text(" - Example: ").text("Video").linkTip("https://goo.gl/PK4DMG").newline();
|
||||
} else {
|
||||
msg = msg("This is not supported with your platform/version").newline();
|
||||
}
|
||||
@ -188,27 +186,24 @@ public class CFICommands extends MethodCommands {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
HeightMapMCAGenerator generator = settings.getGenerator();
|
||||
|
||||
Function<File, Boolean> function = new Function<File, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(File folder) {
|
||||
if (folder != null) {
|
||||
try {
|
||||
generator.setFolder(folder);
|
||||
fp.sendMessage("Generating " + folder);
|
||||
generator.generate();
|
||||
generator.setPacketViewer(null);
|
||||
generator.setImageViewer(null);
|
||||
settings.remove();
|
||||
fp.sendMessage("Done!");
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
fp.sendMessage("Unable to generate world... (see console)?");
|
||||
Function<File, Boolean> function = folder -> {
|
||||
if (folder != null) {
|
||||
try {
|
||||
generator.setFolder(folder);
|
||||
fp.sendMessage("Generating " + folder);
|
||||
generator.generate();
|
||||
generator.setPacketViewer(null);
|
||||
generator.setImageViewer(null);
|
||||
settings.remove();
|
||||
fp.sendMessage("Done!");
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
fp.sendMessage("Unable to generate world... (see console)?");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
try {
|
||||
@ -244,9 +239,13 @@ public class CFICommands extends MethodCommands {
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void column(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setColumn(load(image), pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setColumn(mask, pattern);
|
||||
else gen.setColumn(pattern);
|
||||
if (image != null) {
|
||||
gen.setColumn(load(image), pattern, !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setColumn(mask, pattern);
|
||||
} else {
|
||||
gen.setColumn(pattern);
|
||||
}
|
||||
fp.sendMessage("Set column!");
|
||||
assertSettings(fp).resetComponent();
|
||||
component(fp);
|
||||
@ -266,9 +265,13 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
private void floor(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setFloor(load(image), pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setFloor(mask, pattern);
|
||||
else gen.setFloor(pattern);
|
||||
if (image != null) {
|
||||
gen.setFloor(load(image), pattern, !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setFloor(mask, pattern);
|
||||
} else {
|
||||
gen.setFloor(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -285,13 +288,16 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
public void main(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setMain(load(image), pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setMain(mask, pattern);
|
||||
else gen.setMain(pattern);
|
||||
if (image != null) {
|
||||
gen.setMain(load(image), pattern, !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setMain(mask, pattern);
|
||||
} else {
|
||||
gen.setMain(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "overlay",
|
||||
name = "overlay",
|
||||
aliases = {"setoverlay"},
|
||||
desc = "Set the overlay block",
|
||||
@ -301,9 +307,13 @@ public class CFICommands extends MethodCommands {
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void overlay(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setOverlay(load(image), pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setOverlay(mask, pattern);
|
||||
else gen.setOverlay(pattern);
|
||||
if (image != null) {
|
||||
gen.setOverlay(load(image), pattern, !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setOverlay(mask, pattern);
|
||||
} else {
|
||||
gen.setOverlay(pattern);
|
||||
}
|
||||
fp.sendMessage("Set overlay!");
|
||||
component(fp);
|
||||
}
|
||||
@ -325,8 +335,11 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
private void smooth(FawePlayer fp, int radius, int iterations, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.smooth(load(image), !disableWhiteOnly, radius, iterations);
|
||||
else gen.smooth(mask, radius, iterations);
|
||||
if (image != null) {
|
||||
gen.smooth(load(image), !disableWhiteOnly, radius, iterations);
|
||||
} else {
|
||||
gen.smooth(mask, radius, iterations);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -353,7 +366,7 @@ public class CFICommands extends MethodCommands {
|
||||
"Below 50 will prefer to color with blocks"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void biomepriority(FawePlayer fp, int value) throws ParameterException{
|
||||
public void biomepriority(FawePlayer fp, int value) throws ParameterException {
|
||||
assertSettings(fp).getGenerator().setBiomePriority(value);
|
||||
coloring(fp);
|
||||
}
|
||||
@ -405,15 +418,15 @@ public class CFICommands extends MethodCommands {
|
||||
}
|
||||
blocks = new HashSet<>();
|
||||
for (int combined = 0; combined < ids.length; combined++) {
|
||||
if (ids[combined]) blocks.add(BlockTypes.get(combined));
|
||||
if (ids[combined]) {
|
||||
blocks.add(BlockTypes.get(combined));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
blocks = new HashSet<>();
|
||||
BlockPattern pattern = new BlockPattern(BlockTypes.AIR.getDefaultState());
|
||||
PatternExtent extent = new PatternExtent(pattern);
|
||||
|
||||
SingleFilterBlock extent = new SingleFilterBlock();
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(player);
|
||||
parserContext.setWorld(player.getWorld());
|
||||
@ -424,9 +437,10 @@ public class CFICommands extends MethodCommands {
|
||||
TextureUtil tu = Fawe.get().getTextureUtil();
|
||||
for (int typeId : tu.getValidBlockIds()) {
|
||||
BlockType type = BlockTypes.get(typeId);
|
||||
BlockStateHolder block = type.getDefaultState();
|
||||
pattern.setBlock(block);
|
||||
if (mask.test(BlockVector3.ZERO)) blocks.add(type);
|
||||
extent.init(0, 0, 0, type.getDefaultState().toBaseBlock());
|
||||
if (mask.test(extent)) {
|
||||
blocks.add(type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -459,8 +473,11 @@ public class CFICommands extends MethodCommands {
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void complexity(FawePlayer fp, int min, int max) throws ParameterException, FileNotFoundException {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (min == 0 && max == 100) gen.setTextureUtil(Fawe.get().getTextureUtil());
|
||||
else gen.setTextureUtil(new CleanTextureUtil(Fawe.get().getTextureUtil(), min, max));
|
||||
if (min == 0 && max == 100) {
|
||||
gen.setTextureUtil(Fawe.get().getTextureUtil());
|
||||
} else {
|
||||
gen.setTextureUtil(new CleanTextureUtil(Fawe.get().getTextureUtil(), min, max));
|
||||
}
|
||||
coloring(fp);
|
||||
}
|
||||
|
||||
@ -501,9 +518,13 @@ public class CFICommands extends MethodCommands {
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void biome(FawePlayer fp, BiomeType biome, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setBiome(load(image), biome, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setBiome(mask, biome);
|
||||
else gen.setBiome(biome);
|
||||
if (image != null) {
|
||||
gen.setBiome(load(image), biome, !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setBiome(mask, biome);
|
||||
} else {
|
||||
gen.setBiome(biome);
|
||||
}
|
||||
msg("Set biome!").send(fp);
|
||||
assertSettings(fp).resetComponent();
|
||||
component(fp);
|
||||
@ -682,9 +703,13 @@ public class CFICommands extends MethodCommands {
|
||||
public void color(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
HeightMapMCAGenerator gen = settings.getGenerator();
|
||||
if (imageMask != null) gen.setColor(load(image), load(imageMask), !disableWhiteOnly);
|
||||
else if (mask != null) gen.setColor(load(image), mask);
|
||||
else gen.setColor(load(image));
|
||||
if (imageMask != null) {
|
||||
gen.setColor(load(image), load(imageMask), !disableWhiteOnly);
|
||||
} else if (mask != null) {
|
||||
gen.setColor(load(image), mask);
|
||||
} else {
|
||||
gen.setColor(load(image));
|
||||
}
|
||||
settings.resetColoring();
|
||||
msg("Set color with blocks!").send(fp);
|
||||
mainMenu(fp);
|
||||
@ -696,7 +721,7 @@ public class CFICommands extends MethodCommands {
|
||||
desc = "Set the color with blocks and biomes",
|
||||
descFooter = "Color the terrain using blocks and biomes.\n" +
|
||||
"Provide an image, or worldedit mask to restrict what areas are colored\n" +
|
||||
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
|
||||
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void blockbiome(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
@ -730,7 +755,7 @@ public class CFICommands extends MethodCommands {
|
||||
desc = "Color the world using an image"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void coloring(FawePlayer fp) throws ParameterException{
|
||||
public void coloring(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
settings.popMessages(fp);
|
||||
settings.setCategory("coloring");
|
||||
@ -762,7 +787,9 @@ public class CFICommands extends MethodCommands {
|
||||
for (int typeId : blockArray) {
|
||||
BlockType type = BlockTypes.get(typeId);
|
||||
String name = type.getName();
|
||||
if (name.contains(":")) name = name.split(":")[1];
|
||||
if (name.contains(":")) {
|
||||
name = name.split(":")[1];
|
||||
}
|
||||
materials.add(name);
|
||||
}
|
||||
String blockList = materials.size() > 100 ? materials.size() + " blocks" : StringMan.join(materials, ',');
|
||||
@ -782,9 +809,15 @@ public class CFICommands extends MethodCommands {
|
||||
if (settings.image != null) {
|
||||
StringBuilder colorArgs = new StringBuilder();
|
||||
colorArgs.append(" " + settings.imageArg);
|
||||
if (settings.imageMask != null) colorArgs.append(" " + settings.imageMaskArg);
|
||||
if (settings.mask != null) colorArgs.append(" " + settings.maskArg);
|
||||
if (!settings.whiteOnly) colorArgs.append(" -w");
|
||||
if (settings.imageMask != null) {
|
||||
colorArgs.append(" " + settings.imageMaskArg);
|
||||
}
|
||||
if (settings.mask != null) {
|
||||
colorArgs.append(" " + settings.maskArg);
|
||||
}
|
||||
if (!settings.whiteOnly) {
|
||||
colorArgs.append(" -w");
|
||||
}
|
||||
|
||||
msg.text("Image: ")
|
||||
.text("[" + settings.imageArg + "]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "image"))
|
||||
@ -859,7 +892,7 @@ public class CFICommands extends MethodCommands {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
BufferedImage image = settings.getGenerator().draw();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "jpg", baos );
|
||||
ImageIO.write(image, "jpg", baos);
|
||||
byte[] data = baos.toByteArray();
|
||||
fp.sendMessage("Please wait...");
|
||||
URL url = ImgurUtility.uploadImage(data);
|
||||
@ -904,7 +937,7 @@ public class CFICommands extends MethodCommands {
|
||||
desc = ""
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void populate(FawePlayer fp) throws ParameterException{
|
||||
public void populate(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
settings.popMessages(fp);
|
||||
settings.setCategory("populate");
|
||||
@ -921,7 +954,7 @@ public class CFICommands extends MethodCommands {
|
||||
desc = "Components menu"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void component(FawePlayer fp) throws ParameterException{
|
||||
public void component(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
settings.popMessages(fp);
|
||||
settings.setCategory("component");
|
||||
@ -938,9 +971,15 @@ public class CFICommands extends MethodCommands {
|
||||
String pattern = settings.pattern == null ? "NONE" : settings.patternArg;
|
||||
|
||||
StringBuilder maskArgs = new StringBuilder();
|
||||
if (settings.imageMask != null) maskArgs.append(" " + settings.imageMaskArg);
|
||||
if (settings.mask != null) maskArgs.append(" " + settings.maskArg);
|
||||
if (!settings.whiteOnly) maskArgs.append(" -w");
|
||||
if (settings.imageMask != null) {
|
||||
maskArgs.append(" " + settings.imageMaskArg);
|
||||
}
|
||||
if (settings.mask != null) {
|
||||
maskArgs.append(" " + settings.maskArg);
|
||||
}
|
||||
if (!settings.whiteOnly) {
|
||||
maskArgs.append(" -w");
|
||||
}
|
||||
|
||||
String height = Commands.getAlias(CFICommands.class, "height");
|
||||
String waterHeight = Commands.getAlias(CFICommands.class, "waterheight");
|
||||
@ -993,10 +1032,11 @@ public class CFICommands extends MethodCommands {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private CFISettings assertSettings(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = getSettings(fp);
|
||||
if (!settings.hasGenerator()) throw new ParameterException("Please use /" + alias());
|
||||
if (!settings.hasGenerator()) {
|
||||
throw new ParameterException("Please use /" + alias());
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
@ -1083,12 +1123,16 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
public CFISettings setGenerator(HeightMapMCAGenerator generator) {
|
||||
this.generator = generator;
|
||||
if (bound) fp.getSession().setVirtualWorld(generator);
|
||||
if (bound) {
|
||||
fp.getSession().setVirtualWorld(generator);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public CFISettings bind() {
|
||||
if (generator != null) fp.getSession().setVirtualWorld(generator);
|
||||
if (generator != null) {
|
||||
fp.getSession().setVirtualWorld(generator);
|
||||
}
|
||||
bound = true;
|
||||
fp.setMeta("CFISettings", this);
|
||||
return this;
|
||||
@ -1132,9 +1176,9 @@ public class CFICommands extends MethodCommands {
|
||||
}
|
||||
|
||||
protected Message msg(String text) {
|
||||
return new Message().newline()
|
||||
.text(BBC.getPrefix())
|
||||
.text(text);
|
||||
return new Message().newline()
|
||||
.text(BBC.getPrefix())
|
||||
.text(text);
|
||||
}
|
||||
|
||||
protected void mainMenu(FawePlayer fp) {
|
||||
|
@ -1,55 +1,75 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.example.SimpleIntFaweChunk;
|
||||
import com.boydti.fawe.object.*;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.Metadatable;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.change.StreamChange;
|
||||
import com.boydti.fawe.object.changeset.CFIChangeSet;
|
||||
import com.boydti.fawe.object.collection.*;
|
||||
import com.boydti.fawe.object.collection.DifferentialArray;
|
||||
import com.boydti.fawe.object.collection.DifferentialBlockBuffer;
|
||||
import com.boydti.fawe.object.collection.IterableThreadLocal;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
|
||||
import com.boydti.fawe.object.collection.SummedAreaTable;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.queue.LazyFaweChunk;
|
||||
import com.boydti.fawe.object.schematic.Schematic;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
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.*;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
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.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
// TODO FIXME
|
||||
public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Drawable, VirtualWorld {
|
||||
@ -190,11 +210,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
this.editSession = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Capability capability) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used for visualizing the world on a map
|
||||
private ImageViewer viewer;
|
||||
// Used for visualizing the world by sending chunk packets
|
||||
@ -229,11 +244,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
return metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweQueue getQueue() {
|
||||
throw new UnsupportedOperationException("Not supported: Queue is not backed by a real world");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3 getOrigin() {
|
||||
return Vector3.at(chunkOffset.getBlockX() << 4, 0, chunkOffset.getBlockZ() << 4);
|
||||
@ -1019,7 +1029,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position);
|
||||
return getBlock(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
public BlockState getFloor(int x, int z) {
|
||||
@ -1042,12 +1052,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return BlockState.getFromInternalId(getCombinedId4Data(x, y, z));
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,6 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
|
||||
}
|
||||
|
||||
public Vector3 getTarget(Player player, boolean adjacent) {
|
||||
Location target = null;
|
||||
int range = this.range > -1 ? getRange() : DEFAULT_RANGE;
|
||||
if (adjacent) {
|
||||
Location face = player.getBlockTraceFace(range, true);
|
||||
|
@ -46,9 +46,7 @@ import java.util.UUID;
|
||||
*/
|
||||
public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
public static int COMPRESSION = 0;
|
||||
public static int MODE = 0;
|
||||
public static int HEADER_SIZE = 14;
|
||||
private static int HEADER_SIZE = 14;
|
||||
|
||||
protected int length;
|
||||
protected int height;
|
||||
@ -61,9 +59,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
private final File file;
|
||||
|
||||
private RandomAccessFile braf;
|
||||
private MappedByteBuffer mbb;
|
||||
private MappedByteBuffer byteBuffer;
|
||||
|
||||
private FileChannel fc;
|
||||
private FileChannel fileChannel;
|
||||
private boolean hasBiomes;
|
||||
|
||||
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
|
||||
@ -78,9 +76,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
braf.setLength(file.length());
|
||||
init();
|
||||
width = mbb.getChar(2);
|
||||
height = mbb.getChar(4);
|
||||
length = mbb.getChar(6);
|
||||
width = byteBuffer.getChar(2);
|
||||
height = byteBuffer.getChar(4);
|
||||
length = byteBuffer.getChar(6);
|
||||
area = width * length;
|
||||
this.volume = length * width * height;
|
||||
|
||||
@ -98,9 +96,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
private void init() throws IOException {
|
||||
if (this.fc == null) {
|
||||
this.fc = braf.getChannel();
|
||||
this.mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
|
||||
if (this.fileChannel == null) {
|
||||
this.fileChannel = braf.getChannel();
|
||||
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +132,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public void setBiome(int index, BiomeType biome) {
|
||||
if (initBiome()) {
|
||||
mbb.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId());
|
||||
byteBuffer.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,8 +141,8 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
if (!hasBiomes()) {
|
||||
return null;
|
||||
}
|
||||
int biomeId = mbb.get(HEADER_SIZE + (volume << 2) + index) & 0xFF;
|
||||
return BiomeTypes.register(biomeId);
|
||||
int biomeId = byteBuffer.get(HEADER_SIZE + (volume << 2) + index) & 0xFF;
|
||||
return BiomeTypes.get(biomeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -154,7 +152,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
int mbbIndex = HEADER_SIZE + (volume << 2);
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++, mbbIndex++) {
|
||||
int biome = mbb.get(mbbIndex) & 0xFF;
|
||||
int biome = byteBuffer.get(mbbIndex) & 0xFF;
|
||||
task.run(index, biome);
|
||||
}
|
||||
}
|
||||
@ -173,9 +171,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
public BlockArrayClipboard toClipboard() {
|
||||
try {
|
||||
CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(width - 1, height - 1, length - 1));
|
||||
int ox = mbb.getShort(8);
|
||||
int oy = mbb.getShort(10);
|
||||
int oz = mbb.getShort(12);
|
||||
int ox = byteBuffer.getShort(8);
|
||||
int oy = byteBuffer.getShort(10);
|
||||
int oz = byteBuffer.getShort(12);
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this);
|
||||
clipboard.setOrigin(BlockVector3.at(ox, oy, oz));
|
||||
return clipboard;
|
||||
@ -213,9 +211,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
if (width * height * length != 0) {
|
||||
init();
|
||||
// write length etc
|
||||
mbb.putChar(2, (char) width);
|
||||
mbb.putChar(4, (char) height);
|
||||
mbb.putChar(6, (char) length);
|
||||
byteBuffer.putChar(2, (char) width);
|
||||
byteBuffer.putChar(4, (char) height);
|
||||
byteBuffer.putChar(6, (char) length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -225,9 +223,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public void setOrigin(BlockVector3 offset) {
|
||||
try {
|
||||
mbb.putShort(8, (short) offset.getBlockX());
|
||||
mbb.putShort(10, (short) offset.getBlockY());
|
||||
mbb.putShort(12, (short) offset.getBlockZ());
|
||||
byteBuffer.putShort(8, (short) offset.getBlockX());
|
||||
byteBuffer.putShort(10, (short) offset.getBlockY());
|
||||
byteBuffer.putShort(12, (short) offset.getBlockZ());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -248,9 +246,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
braf.setLength(size);
|
||||
init();
|
||||
}
|
||||
mbb.putChar(2, (char) width);
|
||||
mbb.putChar(4, (char) height);
|
||||
mbb.putChar(6, (char) length);
|
||||
byteBuffer.putChar(2, (char) width);
|
||||
byteBuffer.putChar(4, (char) height);
|
||||
byteBuffer.putChar(6, (char) length);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -258,7 +256,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
mbb.force();
|
||||
byteBuffer.force();
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(int width, int height, int length) {
|
||||
@ -267,7 +265,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
private void closeDirectBuffer(ByteBuffer cb) {
|
||||
if (cb == null || !cb.isDirect()) return;
|
||||
|
||||
// we could use this type cast and call functions without reflection code,
|
||||
// but static import from sun.* package is risky for non-SUN virtual machine.
|
||||
//try { ((sun.nio.ch.DirectBuffer)cb).cleaner().clean(); } catch (Exception ex) { }
|
||||
@ -299,14 +296,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
if (mbb != null) {
|
||||
mbb.force();
|
||||
fc.close();
|
||||
if (byteBuffer != null) {
|
||||
byteBuffer.force();
|
||||
fileChannel.close();
|
||||
braf.close();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.setWritable(true);
|
||||
closeDirectBuffer(mbb);
|
||||
mbb = null;
|
||||
fc = null;
|
||||
closeDirectBuffer(byteBuffer);
|
||||
byteBuffer = null;
|
||||
fileChannel = null;
|
||||
braf = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -337,13 +335,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public void streamCombinedIds(NBTStreamer.ByteReader task) {
|
||||
try {
|
||||
mbb.force();
|
||||
byteBuffer.force();
|
||||
int pos = HEADER_SIZE;
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
task.run(index++, combinedId);
|
||||
}
|
||||
}
|
||||
@ -360,7 +358,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
@Override
|
||||
public void forEach(final BlockReader task, boolean air) {
|
||||
mbb.force();
|
||||
byteBuffer.force();
|
||||
int pos = HEADER_SIZE;
|
||||
IntegerTrio trio = new IntegerTrio();
|
||||
final boolean hasTile = !nbtMap.isEmpty();
|
||||
@ -369,7 +367,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
@ -388,7 +386,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockState state = BlockState.getFromInternalId(combinedId);
|
||||
task.run(x, y, z, state);
|
||||
}
|
||||
@ -399,7 +397,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
if (!type.getMaterial().isAir()) {
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
@ -427,7 +425,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
public BaseBlock getBlock(int x, int y, int z) {
|
||||
try {
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 2);
|
||||
int combinedId = mbb.getInt(index);
|
||||
int combinedId = byteBuffer.getInt(index);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
@ -440,7 +438,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
} catch (IndexOutOfBoundsException ignore) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
}
|
||||
@ -449,7 +446,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
public BaseBlock getBlock(int i) {
|
||||
try {
|
||||
int diskIndex = (HEADER_SIZE) + (i << 2);
|
||||
int combinedId = mbb.getInt(diskIndex);
|
||||
int combinedId = byteBuffer.getInt(diskIndex);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
@ -499,7 +496,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
try {
|
||||
int index = (HEADER_SIZE) + ((getIndex(x, y, z) << 2));
|
||||
int combined = block.getInternalId();
|
||||
mbb.putInt(index, combined);
|
||||
byteBuffer.putInt(index, combined);
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
setTile(x, y, z, block.getNbtData());
|
||||
@ -516,7 +513,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
try {
|
||||
int combined = block.getInternalId();
|
||||
int index = (HEADER_SIZE) + (i << 2);
|
||||
mbb.putInt(index, combined);
|
||||
byteBuffer.putInt(index, combined);
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
int y = i / area;
|
||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.IntegerTrio;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
@ -28,9 +29,9 @@ import java.util.Map;
|
||||
|
||||
public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
|
||||
public static final int BLOCK_SIZE = 1048576 * 4;
|
||||
public static final int BLOCK_MASK = 1048575;
|
||||
public static final int BLOCK_SHIFT = 20;
|
||||
private static final int BLOCK_SIZE = 1048576 * 4;
|
||||
private static final int BLOCK_MASK = 1048575;
|
||||
private static final int BLOCK_SHIFT = 20;
|
||||
|
||||
private int length;
|
||||
private int height;
|
||||
@ -338,9 +339,9 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
||||
int combinedId = block.getInternalId();
|
||||
setCombinedId(index, combinedId);
|
||||
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData();
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
setTile(index, ((BaseBlock)block).getNbtData());
|
||||
setTile(index, block.getNbtData());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -32,19 +32,14 @@ public class AverageColorPattern extends AbstractExtentPattern {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
|
||||
BlockType blockType = extent.getBlock(getPosition).getBlockType();
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
BlockType blockType = get.getBlock(extent).getBlockType();
|
||||
TextureUtil util = holder.getTextureUtil();
|
||||
int currentColor = util.getColor(blockType);
|
||||
if (currentColor == 0) return false;
|
||||
int newColor = util.averageColor(currentColor, color);
|
||||
BlockType newBlock = util.getNearestBlock(newColor);
|
||||
if (newBlock == blockType) return false;
|
||||
return extent.setBlock(setPosition, newBlock.getDefaultState());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
|
||||
return set.setBlock(extent, newBlock.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
public class DesaturatePattern extends AbstractPattern {
|
||||
private transient TextureHolder holder;
|
||||
private final TextureHolder holder;
|
||||
private final Extent extent;
|
||||
private final double value;
|
||||
|
||||
@ -27,7 +27,11 @@ public class DesaturatePattern extends AbstractPattern {
|
||||
public BaseBlock apply(BlockVector3 position) {
|
||||
BlockType block = extent.getBlock(position).getBlockType();
|
||||
TextureUtil util = holder.getTextureUtil();
|
||||
int color = util.getColor(block);
|
||||
int color = getColor(util.getColor(block));
|
||||
return util.getNearestBlock(color).getDefaultState().toBaseBlock();
|
||||
}
|
||||
|
||||
public int getColor(int color) {
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8) & 0xFF;
|
||||
int b = (color >> 0) & 0xFF;
|
||||
@ -37,35 +41,22 @@ public class DesaturatePattern extends AbstractPattern {
|
||||
int green = (int) (g + value * (l - g));
|
||||
int blue = (int) (b + value * (l - b));
|
||||
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
return util.getNearestBlock(newColor).getDefaultState().toBaseBlock();
|
||||
return newColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
|
||||
BlockType block = extent.getBlock(getPosition).getBlockType();
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
BlockType type = get.getBlock(extent).getBlockType();
|
||||
TextureUtil util = holder.getTextureUtil();
|
||||
int color = util.getColor(block);
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8) & 0xFF;
|
||||
int b = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
double l = 0.3f * r + 0.6f * g + 0.1f * b;
|
||||
int red = (int) (r + value * (l - r));
|
||||
int green = (int) (g + value * (l - g));
|
||||
int blue = (int) (b + value * (l - b));
|
||||
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
int color = util.getColor(type);
|
||||
int newColor = getColor(color);
|
||||
if (newColor == color) {
|
||||
return false;
|
||||
}
|
||||
BlockType newBlock = util.getNextNearestBlock(newColor);
|
||||
if (block.equals(newBlock)) {
|
||||
BlockType newType = util.getNextNearestBlock(newColor);
|
||||
if (type.equals(newType)) {
|
||||
return false;
|
||||
}
|
||||
return extent.setBlock(setPosition, newBlock.getDefaultState());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
|
||||
return set.setBlock(extent, newType.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.beta.FilterBlock;
|
||||
import com.boydti.fawe.util.TextureHolder;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -14,7 +15,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
public class SaturatePattern extends AbstractPattern {
|
||||
private transient TextureHolder holder;
|
||||
private final TextureHolder holder;
|
||||
private final int color;
|
||||
private final Extent extent;
|
||||
|
||||
@ -35,19 +36,14 @@ public class SaturatePattern extends AbstractPattern {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
|
||||
BlockType block = extent.getBlock(getPosition).getBlockType();
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
BlockType block = get.getBlock(extent).getBlockType();
|
||||
TextureUtil util = holder.getTextureUtil();
|
||||
int currentColor = util.getColor(block);
|
||||
if (currentColor == 0) return false;
|
||||
int newColor = util.multiplyColor(currentColor, color);
|
||||
BlockType newBlock = util.getNearestBlock(newColor);
|
||||
if (newBlock.equals(block)) return false;
|
||||
return extent.setBlock(setPosition, newBlock.getDefaultState());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
|
||||
return set.setBlock(extent, newBlock.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,16 @@ package com.boydti.fawe.object.pattern;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ShadePattern extends AbstractPattern {
|
||||
private transient TextureUtil util;
|
||||
private final TextureUtil util;
|
||||
private final Extent extent;
|
||||
private final boolean darken;
|
||||
|
||||
@ -29,8 +28,13 @@ public class ShadePattern extends AbstractPattern {
|
||||
return (darken ? util.getDarkerBlock(block) : util.getLighterBlock(block)).getDefaultState().toBaseBlock();
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
util = Fawe.get().getCachedTextureUtil(true, 0, 100);
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
BlockType type = get.getBlock(extent).getBlockType();
|
||||
BlockType newType = (darken ? util.getDarkerBlock(type) : util.getLighterBlock(type));
|
||||
if (type != newType) {
|
||||
return set.setBlock(extent, newType.getDefaultState());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2,21 +2,24 @@ package com.boydti.fawe.util;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HistoryExtent;
|
||||
import com.boydti.fawe.object.NullChangeSet;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.eventbus.EventBus;
|
||||
@ -26,10 +29,12 @@ import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class EditSessionBuilder {
|
||||
private World world;
|
||||
private String worldName;
|
||||
private FaweQueue queue;
|
||||
private Extent extent;
|
||||
private FawePlayer player;
|
||||
private FaweLimit limit;
|
||||
private FaweChangeSet changeSet;
|
||||
@ -60,9 +65,17 @@ public class EditSessionBuilder {
|
||||
public EditSessionBuilder(@Nonnull World world) {
|
||||
checkNotNull(world);
|
||||
this.world = world;
|
||||
this.extent = world;
|
||||
this.worldName = Fawe.imp().getWorldName(world);
|
||||
}
|
||||
|
||||
public EditSessionBuilder(World world, String worldName) {
|
||||
if (world == null && worldName == null) throw new NullPointerException("Both world and worldname cannot be null");
|
||||
this.world = world;
|
||||
this.extent = world;
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
public EditSessionBuilder(@Nonnull String worldName) {
|
||||
checkNotNull(worldName);
|
||||
this.worldName = worldName;
|
||||
@ -176,8 +189,8 @@ public class EditSessionBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public EditSessionBuilder queue(@Nullable FaweQueue queue) {
|
||||
this.queue = queue;
|
||||
public EditSessionBuilder extent(@Nullable Extent extent) {
|
||||
this.extent = extent;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -191,10 +204,261 @@ public class EditSessionBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean wrapped;
|
||||
|
||||
private AbstractDelegateExtent wrapExtent(final AbstractDelegateExtent extent, final EventBus eventBus, EditSessionEvent event, final EditSession.Stage stage) {
|
||||
event = event.clone(stage);
|
||||
event.setExtent(extent);
|
||||
eventBus.post(event);
|
||||
if (event.isCancelled()) {
|
||||
return new NullExtent(extent, FaweException.MANUAL);
|
||||
}
|
||||
final Extent toReturn = event.getExtent();
|
||||
if(toReturn instanceof com.sk89q.worldedit.extent.NullExtent) {
|
||||
return new NullExtent(toReturn, FaweException.MANUAL);
|
||||
}
|
||||
if (!(toReturn instanceof AbstractDelegateExtent)) {
|
||||
Fawe.debug("Extent " + toReturn + " must be AbstractDelegateExtent");
|
||||
return extent;
|
||||
}
|
||||
if (toReturn != extent) {
|
||||
String className = toReturn.getClass().getName().toLowerCase();
|
||||
for (String allowed : Settings.IMP.EXTENT.ALLOWED_PLUGINS) {
|
||||
if (className.contains(allowed.toLowerCase())) {
|
||||
this.wrapped = true;
|
||||
return (AbstractDelegateExtent) toReturn;
|
||||
}
|
||||
}
|
||||
if (Settings.IMP.EXTENT.DEBUG) {
|
||||
Fawe.debug("&cPotentially unsafe extent blocked: " + toReturn.getClass().getName());
|
||||
Fawe.debug("&8 - &7For area restrictions, it is recommended to use the FaweAPI");
|
||||
Fawe.debug("&8 - &7For block logging, it is recommended to use use BlocksHub");
|
||||
Fawe.debug("&8 - &7To allow this plugin add it to the FAWE `allowed-plugins` list");
|
||||
Fawe.debug("&8 - &7To hide this message set `debug` to false in the FAWE config.yml");
|
||||
if (toReturn.getClass().getName().contains("CoreProtect")) {
|
||||
Fawe.debug("Note on CoreProtect: ");
|
||||
Fawe.debug(" - If you disable CP's WE logger (CP config) and this still shows, please update CP");
|
||||
Fawe.debug(" - Use BlocksHub and set `debug` false in the FAWE config");
|
||||
}
|
||||
}
|
||||
}
|
||||
return extent;
|
||||
}
|
||||
|
||||
private FaweChangeSet changeTask;
|
||||
private int maxY;
|
||||
private HistoryExtent history;
|
||||
private AbstractDelegateExtent bypassHistory;
|
||||
private AbstractDelegateExtent bypassAll;
|
||||
|
||||
public EditSessionBuilder compile() {
|
||||
if (extent != null) return this;
|
||||
|
||||
wrapped = false;
|
||||
if (world == null && !this.worldName.isEmpty()) {
|
||||
world = FaweAPI.getWorld(this.worldName);
|
||||
}
|
||||
if (eventBus == null) {
|
||||
eventBus = WorldEdit.getInstance().getEventBus();
|
||||
}
|
||||
if (event == null) {
|
||||
event = new EditSessionEvent(world, player == null ? null : (player.getPlayer()), -1, null);
|
||||
}
|
||||
if (player == null && event.getActor() != null) {
|
||||
player = FawePlayer.wrap(event.getActor());
|
||||
}
|
||||
if (limit == null) {
|
||||
if (player == null) {
|
||||
limit = FaweLimit.MAX;
|
||||
} else {
|
||||
limit = player.getLimit();
|
||||
}
|
||||
}
|
||||
if (autoQueue == null) {
|
||||
autoQueue = true;
|
||||
}
|
||||
if (fastmode == null) {
|
||||
if (player == null) {
|
||||
fastmode = !Settings.IMP.HISTORY.ENABLE_FOR_CONSOLE;
|
||||
} else {
|
||||
fastmode = player.getSession().hasFastMode();
|
||||
}
|
||||
}
|
||||
if (checkMemory == null) {
|
||||
checkMemory = player != null && !this.fastmode;
|
||||
}
|
||||
if (checkMemory) {
|
||||
if (MemUtil.isMemoryLimitedSlow()) {
|
||||
if (Perm.hasPermission(player, "worldedit.fast")) {
|
||||
BBC.WORLDEDIT_OOM_ADMIN.send(player);
|
||||
}
|
||||
throw FaweException.LOW_MEMORY;
|
||||
}
|
||||
}
|
||||
// this.originalLimit = limit;
|
||||
this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
|
||||
// this.limit = limit.copy();
|
||||
|
||||
// if (queue == null) {
|
||||
// boolean placeChunks = this.fastmode || this.limit.FAST_PLACEMENT;
|
||||
// World unwrapped = WorldWrapper.unwrap(world);
|
||||
// if (unwrapped instanceof FaweQueue) {
|
||||
// queue = (FaweQueue) unwrapped;
|
||||
// } else if (unwrapped instanceof MCAWorld) {
|
||||
// queue = ((MCAWorld) unwrapped).getQueue();
|
||||
// } else if (player != null && world.equals(player.getWorld())) {
|
||||
// queue = player.getFaweQueue(placeChunks, autoQueue);
|
||||
// } else {
|
||||
// queue = SetQueue.IMP.getNewQueue(world, placeChunks, autoQueue);
|
||||
// }
|
||||
// }
|
||||
// if (combineStages == null) {
|
||||
// combineStages =
|
||||
// // If it's enabled in the settings
|
||||
// Settings.IMP.HISTORY.COMBINE_STAGES
|
||||
// // If fast placement is disabled, it's slower to perform a copy on each chunk
|
||||
// && this.limit.FAST_PLACEMENT
|
||||
// // If the specific queue doesn't support it
|
||||
// && queue.supports(FaweQueue.Capability.CHANGE_TASKS)
|
||||
// // If the edit uses items from the inventory we can't use a delayed task
|
||||
// && this.blockBag == null;
|
||||
// }
|
||||
// if (!Settings.IMP.QUEUE.PROGRESS.DISPLAY.equalsIgnoreCase("false") && player != null) {
|
||||
// switch (Settings.IMP.QUEUE.PROGRESS.DISPLAY.toLowerCase()) {
|
||||
// case "chat":
|
||||
// this.queue.setProgressTask(new ChatProgressTracker(player));
|
||||
// break;
|
||||
// case "title":
|
||||
// case "true":
|
||||
// default:
|
||||
// this.queue.setProgressTask(new DefaultProgressTracker(player));
|
||||
// }
|
||||
// }
|
||||
// this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), eventBus, event, EditSession.Stage.BEFORE_CHANGE);
|
||||
// this.bypassHistory = (this.extent = wrapExtent(bypassAll, eventBus, event, EditSession.Stage.BEFORE_REORDER));
|
||||
// if (!this.fastmode || changeSet != null) {
|
||||
// if (changeSet == null) {
|
||||
// if (Settings.IMP.HISTORY.USE_DISK) {
|
||||
// UUID uuid = player == null ? EditSession.CONSOLE : player.getUUID();
|
||||
// if (Settings.IMP.HISTORY.USE_DATABASE) {
|
||||
// changeSet = new RollbackOptimizedHistory(world, uuid);
|
||||
// } else {
|
||||
// changeSet = new DiskStorageHistory(world, uuid);
|
||||
// }
|
||||
// } else if (combineStages && Settings.IMP.HISTORY.COMPRESSION_LEVEL == 0 && !(queue instanceof MCAQueue)) {
|
||||
// changeSet = new CPUOptimizedChangeSet(world);
|
||||
// } else {
|
||||
// changeSet = new MemoryOptimizedHistory(world);
|
||||
// }
|
||||
// }
|
||||
// if (this.limit.SPEED_REDUCTION > 0) {
|
||||
// this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
|
||||
// }
|
||||
// if (changeSet instanceof NullChangeSet && Fawe.imp().getBlocksHubApi() != null && player != null) {
|
||||
// changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
// }
|
||||
// if (!(changeSet instanceof NullChangeSet)) {
|
||||
// if (!(changeSet instanceof LoggingChangeSet) && player != null && Fawe.imp().getBlocksHubApi() != null) {
|
||||
// changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
// }
|
||||
// if (this.blockBag != null) {
|
||||
// changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
|
||||
// }
|
||||
// if (combineStages) {
|
||||
// changeTask = changeSet;
|
||||
// changeSet.addChangeTask(queue);
|
||||
// } else {
|
||||
// this.extent = (history = new HistoryExtent(bypassHistory, changeSet, queue));
|
||||
//// if (this.blockBag != null) {
|
||||
//// this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
|
||||
//// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (allowedRegions == null) {
|
||||
// if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions") && !(queue instanceof VirtualWorld)) {
|
||||
// allowedRegions = player.getCurrentRegions();
|
||||
// }
|
||||
// }
|
||||
// this.maxY = world == null ? 255 : world.getMaxY();
|
||||
// if (allowedRegions != null) {
|
||||
// if (allowedRegions.length == 0) {
|
||||
// this.extent = new NullExtent(this.extent, FaweException.NO_REGION);
|
||||
// } else {
|
||||
// this.extent = new ProcessedWEExtent(this.extent, this.limit);
|
||||
// if (allowedRegions.length == 1) {
|
||||
// this.extent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
|
||||
// } else {
|
||||
// this.extent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// this.extent = new HeightBoundExtent(this.extent, this.limit, 0, maxY);
|
||||
// }
|
||||
// if (this.limit.STRIP_NBT != null && !this.limit.STRIP_NBT.isEmpty()) {
|
||||
// this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT);
|
||||
// }
|
||||
// this.extent = wrapExtent(this.extent, eventBus, event, EditSession.Stage.BEFORE_HISTORY);
|
||||
// return this;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EditSession build() {
|
||||
if (eventBus == null) {
|
||||
eventBus = WorldEdit.getInstance().getEventBus();
|
||||
}
|
||||
return new EditSession(worldName, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
|
||||
return new EditSession(this);
|
||||
}
|
||||
|
||||
public Extent getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
|
||||
public boolean isWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
public boolean hasFastMode() {
|
||||
return fastmode;
|
||||
}
|
||||
|
||||
public HistoryExtent getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
public AbstractDelegateExtent getBypassHistory() {
|
||||
return bypassHistory;
|
||||
}
|
||||
|
||||
public AbstractDelegateExtent getBypassAll() {
|
||||
return bypassAll;
|
||||
}
|
||||
|
||||
public FaweLimit getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public FawePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public FaweChangeSet getChangeTask() {
|
||||
return changeTask;
|
||||
}
|
||||
|
||||
public BlockBag getBlockBag() {
|
||||
return blockBag;
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return maxY;
|
||||
}
|
||||
}
|
||||
|
@ -50,9 +50,8 @@ public final class NBTInputStream implements Closeable {
|
||||
* from the specified input stream.
|
||||
*
|
||||
* @param is the input stream
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public NBTInputStream(InputStream is) throws IOException {
|
||||
public NBTInputStream(InputStream is) {
|
||||
this.is = new DataInputStream(is);
|
||||
}
|
||||
|
||||
@ -364,7 +363,7 @@ public final class NBTInputStream implements Closeable {
|
||||
int toRead = Math.min(length << 2, buf.length);
|
||||
is.readFully(buf, 0, toRead);
|
||||
for (int i = 0; i < toRead; i += 4, index++) {
|
||||
data[index] = ((buf[i + 0] & 0xFF) << 24) + ((buf[i + 1] & 0xFF) << 16) + ((buf[i + 2] & 0xFF) << 8) + (buf[i + 3] & 0xFF);
|
||||
data[index] = ((buf[i] & 0xFF) << 24) + ((buf[i + 1] & 0xFF) << 16) + ((buf[i + 2] & 0xFF) << 8) + (buf[i + 3] & 0xFF);
|
||||
}
|
||||
length -= toRead;
|
||||
}
|
||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -38,6 +38,7 @@ import com.boydti.fawe.util.MaskTraverser;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -91,6 +92,7 @@ import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
|
||||
/**
|
||||
* Clipboard commands.
|
||||
*/
|
||||
@ -123,20 +125,24 @@ public class ClipboardCommands {
|
||||
Mask mask, CommandContext context) throws WorldEditException {
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
BlockVector3 max = region.getMaximumPoint();
|
||||
|
||||
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
|
||||
FaweLimit limit = FawePlayer.wrap(player).getLimit();
|
||||
if (volume >= limit.MAX_CHECKS) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||
throw FaweException.MAX_CHECKS;
|
||||
}
|
||||
fp.checkConfirmationRegion(() -> {
|
||||
session.setClipboard(null);
|
||||
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
||||
|
||||
session.setClipboard(new ClipboardHolder(clipboard));
|
||||
|
||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||
copy.setCopyingEntities(!skipEntities);
|
||||
copy.setCopyingBiomes(copyBiomes);
|
||||
|
||||
Mask sourceMask = editSession.getSourceMask();
|
||||
if (sourceMask != null) {
|
||||
new MaskTraverser(sourceMask).reset(editSession);
|
||||
@ -204,12 +210,13 @@ public class ClipboardCommands {
|
||||
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
|
||||
FaweLimit limit = FawePlayer.wrap(player).getLimit();
|
||||
if (volume >= limit.MAX_CHECKS) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||
throw FaweException.MAX_CHECKS;
|
||||
}
|
||||
if (volume >= limit.MAX_CHANGES) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||
throw FaweException.MAX_CHANGES;
|
||||
}
|
||||
session.setClipboard(null);
|
||||
|
||||
ReadOnlyClipboard lazyClipboard = new WorldCutClipboard(editSession, region, !skipEntities, copyBiomes);
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
|
||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||
@ -221,6 +228,7 @@ public class ClipboardCommands {
|
||||
name = "/cut",
|
||||
desc = "Cut the selection to the clipboard",
|
||||
descFooter = "WARNING: Cutting and pasting entities cannot be undone!"
|
||||
|
||||
)
|
||||
@CommandPermissions("worldedit.clipboard.cut")
|
||||
@Logging(REGION)
|
||||
@ -237,21 +245,24 @@ public class ClipboardCommands {
|
||||
CommandContext context) throws WorldEditException {
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
BlockVector3 max = region.getMaximumPoint();
|
||||
|
||||
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
|
||||
FaweLimit limit = FawePlayer.wrap(player).getLimit();
|
||||
if (volume >= limit.MAX_CHECKS) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||
throw FaweException.MAX_CHECKS;
|
||||
}
|
||||
if (volume >= limit.MAX_CHANGES) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||
throw FaweException.MAX_CHANGES;
|
||||
}
|
||||
fp.checkConfirmationRegion(() -> {
|
||||
session.setClipboard(null);
|
||||
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||
|
||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
|
||||
copy.setCopyingEntities(!skipEntities);
|
||||
copy.setCopyingEntities(copyEntities);
|
||||
copy.setRemovingEntities(true);
|
||||
copy.setCopyingBiomes(copyBiomes);
|
||||
Mask sourceMask = editSession.getSourceMask();
|
||||
@ -413,6 +424,7 @@ public class ClipboardCommands {
|
||||
@Command(
|
||||
name = "/paste",
|
||||
desc = "Paste the clipboard's contents"
|
||||
|
||||
)
|
||||
@CommandPermissions("worldedit.clipboard.paste")
|
||||
@Logging(PLACEMENT)
|
||||
@ -481,6 +493,7 @@ public class ClipboardCommands {
|
||||
name = "/place",
|
||||
desc = "Place the clipboard's contents without applying transformations (e.g. rotate)"
|
||||
)
|
||||
|
||||
@CommandPermissions("worldedit.clipboard.place")
|
||||
@Logging(PLACEMENT)
|
||||
public void place(Player player, LocalSession session, final EditSession editSession,
|
||||
@ -551,6 +564,7 @@ public class ClipboardCommands {
|
||||
public void flip(Player player, LocalSession session,
|
||||
@Arg(desc = "The direction to flip, defaults to look direction.", def = Direction.AIM)
|
||||
@Direction BlockVector3 direction) throws WorldEditException {
|
||||
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
AffineTransform transform = new AffineTransform();
|
||||
transform = transform.scale(direction.abs().multiply(-2).add(1, 1, 1).toVector3());
|
||||
@ -563,7 +577,7 @@ public class ClipboardCommands {
|
||||
desc = "Clear your clipboard"
|
||||
)
|
||||
@CommandPermissions("worldedit.clipboard.clear")
|
||||
public void clearClipboard(Player player, LocalSession session) throws WorldEditException {
|
||||
public void clearClipboard(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
|
||||
session.setClipboard(null);
|
||||
BBC.CLIPBOARD_CLEARED.send(player);
|
||||
}
|
||||
|
@ -205,6 +205,7 @@ public class PatternCommands extends MethodCommands {
|
||||
" - Use to replace slabs or where the data values needs to be shifted instead of set"
|
||||
)
|
||||
public Pattern iddatamask(Actor actor, LocalSession session, Extent extent, @Range(min = 0, max = 15) int bitmask, Pattern pattern) {
|
||||
|
||||
return new IdDataMaskPattern(extent, pattern, bitmask);
|
||||
}
|
||||
|
||||
@ -213,6 +214,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Only change the block id"
|
||||
)
|
||||
public Pattern id(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new IdPattern(extent, pattern);
|
||||
}
|
||||
|
||||
@ -221,6 +223,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Only change the block data"
|
||||
)
|
||||
public Pattern data(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new DataPattern(extent, pattern);
|
||||
}
|
||||
|
||||
@ -230,6 +233,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Set the biome"
|
||||
)
|
||||
public Pattern biome(Actor actor, LocalSession session, Extent extent, BiomeType biome) {
|
||||
|
||||
return new BiomePattern(extent, biome);
|
||||
}
|
||||
|
||||
@ -239,6 +243,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Offset the pattern to where you click"
|
||||
)
|
||||
public Pattern relative(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new RelativePattern(pattern);
|
||||
}
|
||||
|
||||
@ -250,6 +255,7 @@ public class PatternCommands extends MethodCommands {
|
||||
"Example: #!x[#!z[#~[#l3d[pattern]]]]"
|
||||
)
|
||||
public Pattern nox(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new NoXPattern(pattern);
|
||||
}
|
||||
|
||||
@ -259,6 +265,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "The pattern will not be provided the y axis info"
|
||||
)
|
||||
public Pattern noy(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new NoYPattern(pattern);
|
||||
}
|
||||
|
||||
@ -268,6 +275,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "The pattern will not be provided the z axis info"
|
||||
)
|
||||
public Pattern noz(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
|
||||
|
||||
return new NoZPattern(pattern);
|
||||
}
|
||||
|
||||
@ -285,6 +293,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Offset a pattern"
|
||||
)
|
||||
public Pattern offset(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
|
||||
return new OffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@ -293,6 +302,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Applies to only blocks on a surface. Selects a block from provided pattern with a given ranomized offset `[0, <distance>)`. e.g. Use `#existing` to randomly offset blocks in the world, or `#copy` to offset blocks in your clipboard"
|
||||
)
|
||||
public Pattern surfacespread(Actor actor, LocalSession session, double distance, Pattern pattern) {
|
||||
|
||||
return new SurfaceRandomOffsetPattern(pattern, (int) distance);
|
||||
}
|
||||
|
||||
@ -301,6 +311,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Randomly spread solid blocks"
|
||||
)
|
||||
public Pattern solidspread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
|
||||
return new SolidRandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@ -310,6 +321,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Randomly spread blocks"
|
||||
)
|
||||
public Pattern spread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
|
||||
return new RandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@ -319,6 +331,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Sequentially set blocks from a list of patterns"
|
||||
)
|
||||
public Pattern linear(Actor actor, LocalSession session, Pattern other) {
|
||||
|
||||
if (other instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
|
||||
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
@ -332,6 +345,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Use the x,y,z coordinate to pick a block from the list"
|
||||
)
|
||||
public Pattern linear3d(Actor actor, LocalSession session, Pattern other) {
|
||||
|
||||
if (other instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
|
||||
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
@ -345,6 +359,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Use the x,z coordinate to pick a block from the list"
|
||||
)
|
||||
public Pattern linear2d(Actor actor, LocalSession session, Pattern other) {
|
||||
|
||||
if (other instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
|
||||
return new Linear2DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
@ -358,6 +373,7 @@ public class PatternCommands extends MethodCommands {
|
||||
desc = "Expression pattern: http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax"
|
||||
)
|
||||
public Pattern expression(Actor actor, LocalSession session, Extent extent, String input) throws ExpressionException {
|
||||
|
||||
Expression exp = Expression.compile(input, "x", "y", "z");
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(extent, Vector3.ONE, Vector3.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
|
@ -29,7 +29,11 @@ import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
|
||||
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
|
||||
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
||||
|
||||
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.beta.filters.SetFilter;
|
||||
import com.boydti.fawe.beta.implementation.QueueHandler;
|
||||
import com.boydti.fawe.beta.filters.DistrFilter;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.example.NMSMappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
@ -54,6 +58,7 @@ import com.sk89q.worldedit.function.generator.FloraGenerator;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.LayerVisitor;
|
||||
@ -76,9 +81,11 @@ import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||
import com.sk89q.worldedit.util.command.binding.Range;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.biome.Biomes;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import java.util.ArrayList;
|
||||
@ -109,6 +116,43 @@ public class RegionCommands {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = {"debugtest"},
|
||||
usage = "",
|
||||
desc = "debugtest",
|
||||
help = "debugtest"
|
||||
)
|
||||
@CommandPermissions("fawe.admin.debug")
|
||||
public void debugtest(Player player, @Selection Region region) throws WorldEditException {
|
||||
QueueHandler queueHandler = Fawe.get().getQueueHandler();
|
||||
World world = player.getWorld();
|
||||
DistrFilter filter = new DistrFilter();
|
||||
long start = System.currentTimeMillis();
|
||||
queueHandler.apply(world, region, filter);
|
||||
long diff = System.currentTimeMillis() - start;
|
||||
System.out.println(diff);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"db2"},
|
||||
usage = "",
|
||||
desc = "db2",
|
||||
help = "db2"
|
||||
)
|
||||
@CommandPermissions("fawe.admin.debug")
|
||||
public void db2(Player player, @Selection Region region, String blockStr) throws WorldEditException {
|
||||
QueueHandler queueHandler = Fawe.get().getQueueHandler();
|
||||
World world = player.getWorld();
|
||||
BlockState block = BlockState.get(blockStr);
|
||||
SetFilter filter = new SetFilter(block);
|
||||
long start = System.currentTimeMillis();
|
||||
queueHandler.apply(world, region, filter);
|
||||
long diff = System.currentTimeMillis() - start;
|
||||
System.out.println(diff);
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
name = "/fixlighting",
|
||||
desc = "Get the light at a position"
|
||||
@ -417,7 +461,7 @@ public class RegionCommands {
|
||||
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
|
||||
FaweLimit limit = FawePlayer.wrap(player).getLimit();
|
||||
if (volume >= limit.MAX_CHECKS) {
|
||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||
throw FaweException.MAX_CHECKS;
|
||||
}
|
||||
player.checkConfirmationRegion(() -> {
|
||||
try {
|
||||
@ -673,6 +717,7 @@ public class RegionCommands {
|
||||
descFooter = "Hollows out the object contained in this selection.\n" +
|
||||
"Optionally fills the hollowed out part with the given block.\n" +
|
||||
"Thickness is measured in manhattan distance."
|
||||
|
||||
)
|
||||
@CommandPermissions("worldedit.region.hollow")
|
||||
@Logging(REGION)
|
||||
@ -682,9 +727,11 @@ public class RegionCommands {
|
||||
int thickness,
|
||||
@Arg(desc = "The pattern of blocks to replace the hollowed area with", def = "air")
|
||||
Pattern pattern,
|
||||
|
||||
CommandContext context) throws WorldEditException {
|
||||
Mask finalMask = mask == null ? new SolidBlockMask(editSession) : mask;
|
||||
player.checkConfirmationRegion(() -> {
|
||||
int affected = editSession.hollowOutRegion(region, thickness, pattern);
|
||||
int affected = editSession.hollowOutRegion(region, thickness, pattern, finalMask);
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}, getArguments(context), region, context);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.clipboard.remap.ClipboardRemapper;
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
@ -80,6 +81,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import org.enginehub.piston.annotation.Command;
|
||||
import org.enginehub.piston.annotation.CommandContainer;
|
||||
@ -403,8 +405,8 @@ public class SchematicCommands {
|
||||
}
|
||||
if (new PlayerSaveClipboardEvent(player, clipboard, uri, f.toURI()).call()) {
|
||||
try (ClipboardWriter writer = format.getWriter(fos)) {
|
||||
if (writer instanceof StructureFormat) {
|
||||
((StructureFormat) writer).write(target, player.getName());
|
||||
if (writer instanceof MinecraftStructure) {
|
||||
((MinecraftStructure) writer).write(target, player.getName());
|
||||
} else {
|
||||
writer.write(target);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.object.regions.selector.FuzzyRegionSelector;
|
||||
import com.boydti.fawe.object.regions.selector.PolyhedralRegionSelector;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
@ -490,7 +491,7 @@ public class SelectionCommands {
|
||||
// TODO multi clipboard distribution
|
||||
Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing
|
||||
region = clipboard.getRegion();
|
||||
editSession.setExtent(new AbstractDelegateExtent(clipboard));
|
||||
new ExtentTraverser<AbstractDelegateExtent>(editSession).setNext(new AbstractDelegateExtent(clipboard));
|
||||
} else {
|
||||
region = session.getSelection(player.getWorld());
|
||||
}
|
||||
@ -499,6 +500,7 @@ public class SelectionCommands {
|
||||
else
|
||||
distribution = (List) editSession.getBlockDistribution(region);
|
||||
|
||||
|
||||
if (distribution.isEmpty()) { // *Should* always be false
|
||||
player.printError("No blocks counted.");
|
||||
return;
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
|
||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.DelegateConsumer;
|
||||
@ -60,6 +61,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
||||
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
@ -75,6 +75,7 @@ public class WorldEditCommands {
|
||||
FaweVersion fVer = Fawe.get().getVersion();
|
||||
String fVerStr = fVer == null ? "unknown" : "-" + fVer.build;
|
||||
actor.print("FastAsyncWorldEdit" + fVerStr + " created by Empire92");
|
||||
|
||||
if (fVer != null) {
|
||||
actor.printDebug("----------- Platforms -----------");
|
||||
FaweVersion version = Fawe.get().getVersion();
|
||||
|
@ -48,6 +48,7 @@ import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxBrushRadiusException;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -643,15 +644,16 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
||||
Brush brush = current.getBrush();
|
||||
if (brush == null) return;
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
EditSession editSession = new EditSessionBuilder(player.getWorld())
|
||||
EditSessionBuilder builder = new EditSessionBuilder(player.getWorld())
|
||||
.player(fp)
|
||||
.allowedRegionsEverywhere()
|
||||
.autoQueue(false)
|
||||
.blockBag(null)
|
||||
.changeSetNull()
|
||||
.combineStages(false)
|
||||
.build();
|
||||
VisualExtent newVisualExtent = new VisualExtent(editSession.getExtent(), editSession.getQueue());
|
||||
.combineStages(false);
|
||||
EditSession editSession = builder.build();
|
||||
|
||||
VisualExtent newVisualExtent = new VisualExtent(builder.getExtent(), builder.getQueue());
|
||||
BlockVector3 position = getPosition(editSession, player);
|
||||
if (position != null) {
|
||||
editSession.setExtent(newVisualExtent);
|
||||
|
@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
public class GravityBrush implements Brush {
|
||||
@ -43,8 +44,8 @@ public class GravityBrush implements Brush {
|
||||
for (int x = position.getBlockX() + size; x > position.getBlockX() - size; --x) {
|
||||
for (int z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
|
||||
int freeSpot = startCheckY;
|
||||
for (int y = startCheckY; y <= endY; ++y) {
|
||||
final BlockState block = editSession.getLazyBlock(x, y, z);
|
||||
for (int y = startCheckY; y <= endY; y++) {
|
||||
BlockStateHolder block = editSession.getBlock(x, y, z);
|
||||
if (!block.getBlockType().getMaterial().isAir()) {
|
||||
if (y != freeSpot) {
|
||||
editSession.setBlock(x, y, z, BlockTypes.AIR.getDefaultState());
|
||||
|
@ -47,10 +47,8 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||
*/
|
||||
public class AbstractDelegateExtent implements LightingExtent {
|
||||
|
||||
private transient final Extent extent;
|
||||
protected MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0);
|
||||
public class AbstractDelegateExtent implements Extent, LightingExtent {
|
||||
private final Extent extent;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -62,126 +60,18 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getSkyLight(x, y, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return extent.getMaxY();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBlockLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getBlockLight(x, y, z);
|
||||
}
|
||||
return getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getOpacity(x, y, z);
|
||||
}
|
||||
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getLight(x, y, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getBrightness(x, y, z);
|
||||
}
|
||||
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extent.
|
||||
*
|
||||
* @return the extent
|
||||
*/
|
||||
public Extent getExtent() {
|
||||
public final Extent getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
return extent.getLazyBlock(mutable.setComponents(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return extent.getLazyBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
return setBlock(mutable.setComponents(x, y, z), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return extent.getBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return extent.getFullBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
|
||||
return extent.setBlock(location, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
return extent.createEntity(location, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities() {
|
||||
return extent.getEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
return extent.getEntities(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector2 position) {
|
||||
return extent.getBiome(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
||||
return extent.setBiome(position, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return extent.setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
return extent.getHighestTerrainBlock(x, z, minY, maxY);
|
||||
}
|
||||
|
||||
/*
|
||||
Bounds
|
||||
*/
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return extent.getMinimumPoint();
|
||||
@ -192,78 +82,90 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
return extent.getMaximumPoint();
|
||||
}
|
||||
|
||||
protected Operation commitBefore() {
|
||||
return null;
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return extent.getMaxY();
|
||||
}
|
||||
|
||||
/*
|
||||
Input + Output
|
||||
*/
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return extent.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return extent.getFullBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return extent.getBiomeType(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return extent.setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
return extent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
/*
|
||||
Light
|
||||
*/
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getSkyLight(x, y, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getBlockLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getBlockLight(x, y, z);
|
||||
}
|
||||
return getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
public int getOpacity(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getOpacity(x, y, z);
|
||||
}
|
||||
return getBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getLight(x, y, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getBrightness(int x, int y, int z) {
|
||||
if (extent instanceof LightingExtent) {
|
||||
return ((LightingExtent) extent).getBrightness(x, y, z);
|
||||
}
|
||||
return getBlock(x, y, z).getBlockType().getMaterial().getLightValue();
|
||||
}
|
||||
|
||||
/*
|
||||
Generic
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + extent.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
return extent.getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
|
||||
return extent.getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, boolean ignoreAir) {
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCaves(Region region) throws WorldEditException {
|
||||
extent.addCaves(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Region region, GenBase gen) throws WorldEditException {
|
||||
extent.generate(region, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
|
||||
extent.spawnResource(region, gen, rarity, frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 pt) {
|
||||
return extent.contains(pt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
extent.addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
extent.addOres(region, mask);
|
||||
protected Operation commitBefore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -281,6 +183,4 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ package com.sk89q.worldedit.extent;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -45,30 +47,13 @@ public interface InputExtent {
|
||||
* @param position position of the block
|
||||
* @return the block
|
||||
*/
|
||||
BlockState getBlock(BlockVector3 position);
|
||||
default BlockState getBlock(BlockVector3 position) {
|
||||
return getBlock(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lazy, immutable snapshot of the block at the given location that only
|
||||
* immediately contains information about the block's type (and metadata).
|
||||
*
|
||||
* <p>Further information (such as NBT data) will be available <strong>by the
|
||||
* time of access</strong>. Therefore, it is not recommended that
|
||||
* this method is used if the world is being simulated at the time of
|
||||
* call. If the block needs to be stored for future use, then this method should
|
||||
* definitely not be used. Moreover, the block that is returned is immutable (or
|
||||
* should be), and therefore modifications should not be attempted on it. If a
|
||||
* modifiable copy is required, then the block should be cloned.</p>
|
||||
*
|
||||
* <p>This method exists because it is sometimes important to inspect the block
|
||||
* at a given location, but {@link #getBlock(BlockVector3)} may be too expensive in
|
||||
* the underlying implementation. It is also not possible to implement
|
||||
* caching if the returned object is mutable, so this methods allows caching
|
||||
* implementations to be used.</p>
|
||||
*
|
||||
* @param position position of the block
|
||||
* @return the block
|
||||
*/
|
||||
BlockState getLazyBlock(BlockVector3 position);
|
||||
default BlockState getBlock(int x, int y, int z) {
|
||||
return getBlock(MutableBlockVector3.get(x, y, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a immutable snapshot of the block at the given location.
|
||||
@ -76,7 +61,13 @@ public interface InputExtent {
|
||||
* @param position position of the block
|
||||
* @return the block
|
||||
*/
|
||||
BaseBlock getFullBlock(BlockVector3 position);
|
||||
default BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getFullBlock(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
default BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return getFullBlock(MutableBlockVector3.get(x, y, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the biome at the given location.
|
||||
@ -87,6 +78,11 @@ public interface InputExtent {
|
||||
* @param position the (x, z) location to check the biome at
|
||||
* @return the biome at the location
|
||||
*/
|
||||
BiomeType getBiome(BlockVector2 position);
|
||||
default BiomeType getBiome(BlockVector2 position) {
|
||||
return getBiomeType(position.getX(), position.getZ());
|
||||
}
|
||||
|
||||
default BiomeType getBiomeType(int x, int z) {
|
||||
return getBiome(MutableBlockVector2.get(x, z));
|
||||
}
|
||||
}
|
||||
|
@ -73,16 +73,10 @@ public class NullExtent implements Extent {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getBlock(position).toBaseBlock();
|
||||
|
@ -199,9 +199,20 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
setupClipboard(0, uuid);
|
||||
}
|
||||
int[] pos = value.getIntArray("Pos");
|
||||
int x = pos[0];
|
||||
int y = pos[1];
|
||||
int z = pos[2];
|
||||
int x,y,z;
|
||||
if (pos.length != 3) {
|
||||
System.out.println("Invalid tile " + value);
|
||||
if (!value.containsKey("x") || !value.containsKey("y") || !value.containsKey("z")) {
|
||||
return;
|
||||
}
|
||||
x = value.getInt("x");
|
||||
y = value.getInt("y");
|
||||
z = value.getInt("z");
|
||||
} else {
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
z = pos[2];
|
||||
}
|
||||
Map<String, Tag> values = value.getValue();
|
||||
Tag id = values.get("Id");
|
||||
if (id != null) {
|
||||
|
@ -51,6 +51,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -94,19 +95,11 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
}
|
||||
|
||||
private static long[] adapt(Direction... dirs) {
|
||||
long[] arr = new long[dirs.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = 1L << dirs[i].ordinal();
|
||||
}
|
||||
return arr;
|
||||
return Arrays.stream(dirs).mapToLong(dir -> 1L << dir.ordinal()).toArray();
|
||||
}
|
||||
|
||||
private static long[] adapt(Long... dirs) {
|
||||
long[] arr = new long[dirs.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = dirs[i];
|
||||
}
|
||||
return arr;
|
||||
return Arrays.stream(dirs).mapToLong(dir -> dir).toArray();
|
||||
}
|
||||
|
||||
private static long[] getDirections(AbstractProperty property) {
|
||||
@ -138,7 +131,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
case FACING: {
|
||||
List<Direction> directions = new ArrayList<>();
|
||||
for (Object value : values) {
|
||||
directions.add(Direction.valueOf(value.toString().toUpperCase()));
|
||||
directions.add(Direction.valueOf(value.toString().toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
return adapt(directions.toArray(new Direction[0]));
|
||||
}
|
||||
@ -220,9 +213,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
}
|
||||
|
||||
private static long notIndex(long mask, int... indexes) {
|
||||
for (int index : indexes) {
|
||||
mask = mask | (1L << (index + values().length));
|
||||
}
|
||||
mask |= Arrays.stream(indexes).mapToLong(index -> (1L << (index + values().length))).reduce(0, (a, b) -> a | b);
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -344,10 +335,10 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
Object southState = tmp.getState(PropertyKey.SOUTH);
|
||||
Object westState = tmp.getState(PropertyKey.WEST);
|
||||
|
||||
tmp = tmp.with(PropertyKey.valueOf(newNorth.name().toUpperCase()), northState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newEast.name().toUpperCase()), eastState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newSouth.name().toUpperCase()), southState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newWest.name().toUpperCase()), westState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newNorth.name().toUpperCase(Locale.ROOT)), northState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newEast.name().toUpperCase(Locale.ROOT)), eastState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newSouth.name().toUpperCase(Locale.ROOT)), southState);
|
||||
tmp = tmp.with(PropertyKey.valueOf(newWest.name().toUpperCase(Locale.ROOT)), westState);
|
||||
|
||||
newMaskedId = tmp.getInternalId();
|
||||
}
|
||||
@ -476,7 +467,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
return BlockState.getFromInternalId(newMaskedId);
|
||||
}
|
||||
|
||||
public final BaseBlock transform(BlockStateHolder block) {
|
||||
public final BaseBlock transform(BlockStateHolder<BaseBlock> block) {
|
||||
BlockState transformed = transform(block.toImmutableState());
|
||||
if (block.hasNbtData()) {
|
||||
return transformBaseBlockNBT(transformed, block.getNbtData(), transform);
|
||||
@ -501,13 +492,8 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
return transform(super.getLazyBlock(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return transform(super.getLazyBlock(position));
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return transform(super.getBlock(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,256 +19,215 @@
|
||||
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.object.collection.FastBitSet;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.NullExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
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.block.BlockTypes;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A mask that checks whether blocks at the given positions are matched by
|
||||
* a block in a list.
|
||||
*
|
||||
* <p>This mask checks for both an exact block type and state value match,
|
||||
* respecting fuzzy status of the BlockState.</p>
|
||||
* @deprecated use BlockMaskBuilder
|
||||
*/
|
||||
@Deprecated
|
||||
public class BlockMask extends AbstractExtentMask {
|
||||
|
||||
private final long[][] bitSets;
|
||||
protected final static long[] ALL = new long[0];
|
||||
|
||||
|
||||
/**
|
||||
* Create a new block mask.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param blocks a list of blocks to match
|
||||
*/
|
||||
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
|
||||
super(extent);
|
||||
checkNotNull(blocks);
|
||||
this.bitSets = new BlockMaskBuilder().addBlocks(blocks).optimize().getBits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new block mask.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param block an array of blocks to match
|
||||
*/
|
||||
public BlockMask(Extent extent, BaseBlock... block) {
|
||||
super(extent);
|
||||
checkNotNull(block);
|
||||
this.bitSets = new BlockMaskBuilder().addBlocks(block).optimize().getBits();
|
||||
}
|
||||
public class BlockMask extends ABlockMask {
|
||||
private final boolean[] ordinals;
|
||||
|
||||
public BlockMask() {
|
||||
super(NullExtent.INSTANCE);
|
||||
this.bitSets = new long[BlockTypes.size()][];
|
||||
this(new NullExtent());
|
||||
}
|
||||
|
||||
protected BlockMask(Extent extent, long[][] bitSets) {
|
||||
super(extent);
|
||||
this.bitSets = bitSets;
|
||||
public BlockMask(Extent extent) {
|
||||
this(extent, new boolean[BlockTypes.states.length]);
|
||||
}
|
||||
|
||||
public BlockMaskBuilder toBuilder() {
|
||||
return new BlockMaskBuilder(this.bitSets);
|
||||
public BlockMask(Extent extent, boolean[] ordinals) {
|
||||
super(extent == null ? new NullExtent() : extent);
|
||||
this.ordinals = ordinals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated NBT not supported by this mask
|
||||
*/
|
||||
@Deprecated
|
||||
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
|
||||
this(extent);
|
||||
add(blocks);
|
||||
}
|
||||
|
||||
public BlockMask add(Predicate<BlockState> predicate) {
|
||||
for (int i = 0; i < ordinals.length; i++) {
|
||||
if (!ordinals[i]) {
|
||||
BlockState state = BlockTypes.states[i];
|
||||
if (state != null) ordinals[i] = predicate.test(state);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask add(BlockState... states) {
|
||||
addStates(Arrays.asList(states));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask remove(BlockState... states) {
|
||||
for (BlockState state : states) ordinals[state.getOrdinal()] = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask clear() {
|
||||
Arrays.fill(ordinals, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
for (boolean value : ordinals) {
|
||||
if (value) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public BlockMask addStates(Collection<BlockState> states) {
|
||||
for (BlockState state : states) ordinals[state.getOrdinal()] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask add(BlockType... types) {
|
||||
addTypes(Arrays.asList(types));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockMask addTypes(Collection<BlockType> types) {
|
||||
for (BlockType type : types) {
|
||||
for (BlockState state : type.getAllStates()) {
|
||||
ordinals[state.getOrdinal()] = true;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated NBT not supported by this mask
|
||||
*/
|
||||
@Deprecated
|
||||
public void add(Collection<BaseBlock> blocks) {
|
||||
for (BaseBlock block : blocks) {
|
||||
add(block.toBlockState());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> strings = new ArrayList<>();
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
if (bitSets[i] != null) {
|
||||
long[] set = bitSets[i];
|
||||
BlockType type = BlockTypes.get(i);
|
||||
if (set == ALL) {
|
||||
strings.add(type.getId());
|
||||
} else {
|
||||
for (BlockState state : type.getAllStates()) {
|
||||
if (test(state)) {
|
||||
strings.add(state.getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return StringMan.join(strings, ",");
|
||||
public boolean test(BlockState state) {
|
||||
return ordinals[state.getOrdinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask optimize() {
|
||||
Map<Object, Integer> states = new HashMap<>();
|
||||
int indexFound = -1;
|
||||
{
|
||||
int indexNull = -1;
|
||||
int indexAll = -1;
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
long[] bs = bitSets[i];
|
||||
if (bs == null) {
|
||||
indexNull = i;
|
||||
states.put(null, states.getOrDefault(null, 0) + 1);
|
||||
} else if (bs.length == 0) {
|
||||
indexAll = i;
|
||||
states.put(ALL, states.getOrDefault(ALL, 0) + 1);
|
||||
} else if (indexFound == -1) {
|
||||
indexFound = i;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
// Only types, no states
|
||||
if (indexFound == -1) {
|
||||
if (states.size() == 1) {
|
||||
return states.keySet().iterator().next() == null ? Masks.alwaysFalse() : Masks.alwaysTrue();
|
||||
}
|
||||
if (states.get(ALL) == 1) return new SingleBlockTypeMask(getExtent(), BlockTypes.get(indexAll));
|
||||
if (states.get(null) == 1)
|
||||
return new SingleBlockTypeMask(getExtent(), BlockTypes.get(indexNull)).inverse();
|
||||
|
||||
boolean[] types = new boolean[BlockTypes.size()];
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
if (bitSets[i].length == 0) types[i] = true;
|
||||
}
|
||||
return new BlockTypeMask(getExtent(), types);
|
||||
}
|
||||
}
|
||||
BlockType type = BlockTypes.get(indexFound);
|
||||
Mask mask = getOptimizedMask(type, bitSets[indexFound]);
|
||||
if (mask == null) { // Try with inverse
|
||||
long[] newBitSet = bitSets[indexFound];
|
||||
for (int i = 0; i < newBitSet.length; i++) newBitSet[i] = ~newBitSet[i];
|
||||
mask = getOptimizedMask(type, bitSets[indexFound]);
|
||||
if (mask != null) mask = mask.inverse();
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
private Mask getOptimizedMask(BlockType type, long[] bitSet) {
|
||||
boolean single = true;
|
||||
int and = type.getInternalId();
|
||||
List<? extends Property> properties = type.getProperties();
|
||||
for (AbstractProperty prop : (List<AbstractProperty<?>>) type.getProperties()) {
|
||||
List values = prop.getValues();
|
||||
int numSet = 0;
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
int localI = i << prop.getBitOffset();
|
||||
if (FastBitSet.get(bitSet, localI)) {
|
||||
numSet++;
|
||||
and |= prop.modify(and, i);
|
||||
}
|
||||
}
|
||||
// Cannot optimize multiple property values - use current mask (null)
|
||||
if (numSet != values.size() && numSet != 1) {
|
||||
return null;
|
||||
}
|
||||
single = single && numSet == 1;
|
||||
}
|
||||
if (single)
|
||||
return new SingleBlockStateMask(getExtent(), BlockState.getFromInternalId(and));
|
||||
return new SingleBlockStateBitMask(getExtent(), and);
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return ordinals[vector.getOrdinal(getExtent())];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask and(Mask other) {
|
||||
if (other instanceof BlockMask) {
|
||||
long[][] otherBitSets = ((BlockMask) other).bitSets;
|
||||
for (int i = 0; i < otherBitSets.length; i++) {
|
||||
long[] otherBitSet = otherBitSets[i];
|
||||
long[] bitSet = bitSets[i];
|
||||
if (otherBitSet == null) bitSets[i] = null;
|
||||
else if (otherBitSet.length == 0) continue;
|
||||
else if (bitSet == null) continue;
|
||||
else if (bitSet.length == 0) bitSets[i] = otherBitSet;
|
||||
else for (int j = 0; j < otherBitSet.length; j++) bitSet[j] &= otherBitSet[j];
|
||||
public Mask and(Mask mask) {
|
||||
if (mask instanceof ABlockMask) {
|
||||
ABlockMask other = (ABlockMask) mask;
|
||||
for (int i = 0; i < ordinals.length; i++) {
|
||||
if (ordinals[i]) {
|
||||
ordinals[i] = other.test(BlockState.getFromOrdinal(i));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
if (other instanceof SingleBlockStateMask) {
|
||||
return new BlockMaskBuilder(bitSets).filter(((SingleBlockStateMask) other).getBlockState()).build(getExtent());
|
||||
}
|
||||
if (other instanceof SingleBlockTypeMask) {
|
||||
return new BlockMaskBuilder(bitSets).filter(((SingleBlockTypeMask) other).getBlockType()).build(getExtent());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask or(Mask other) {
|
||||
if (other instanceof BlockMask) {
|
||||
long[][] otherBitSets = ((BlockMask) other).bitSets;
|
||||
for (int i = 0; i < otherBitSets.length; i++) {
|
||||
long[] otherBitSet = otherBitSets[i];
|
||||
long[] bitSet = bitSets[i];
|
||||
if (otherBitSet == null) continue;
|
||||
else if (otherBitSet.length == 0) bitSets[i] = ALL;
|
||||
else if (bitSet == null) bitSets[i] = otherBitSet;
|
||||
else if (bitSet.length == 0) continue;
|
||||
else for (int j = 0; j < otherBitSet.length; j++) bitSet[j] |= otherBitSet[j];
|
||||
public Mask or(Mask mask) {
|
||||
if (mask instanceof ABlockMask) {
|
||||
ABlockMask other = (ABlockMask) mask;
|
||||
for (int i = 0; i < ordinals.length; i++) {
|
||||
if (!ordinals[i]) {
|
||||
ordinals[i] = other.test(BlockState.getFromOrdinal(i));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
if (other instanceof SingleBlockStateMask) {
|
||||
return new BlockMaskBuilder(bitSets).add(((SingleBlockStateMask) other).getBlockState()).build(getExtent());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask optimize() {
|
||||
int setStates = 0;
|
||||
BlockState setState = null;
|
||||
BlockState unsetState = null;
|
||||
int totalStates = 0;
|
||||
|
||||
int setTypes = 0;
|
||||
BlockType setType = null;
|
||||
BlockType unsetType = null;
|
||||
int totalTypes = 0;
|
||||
|
||||
for (BlockType type : BlockTypes.values) {
|
||||
if (type != null) {
|
||||
totalTypes++;
|
||||
boolean hasAll = true;
|
||||
boolean hasAny = false;
|
||||
List<BlockState> all = type.getAllStates();
|
||||
for (BlockState state : all) {
|
||||
totalStates++;
|
||||
hasAll &= test(state);
|
||||
hasAny = true;
|
||||
}
|
||||
if (hasAll) {
|
||||
setTypes++;
|
||||
setType = type;
|
||||
setStates += all.size();
|
||||
setState = type.getDefaultState();
|
||||
} else if (hasAny) {
|
||||
for (BlockState state : all) {
|
||||
if (test(state)) {
|
||||
setStates++;
|
||||
setState = state;
|
||||
} else {
|
||||
unsetState = state;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsetType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (other instanceof SingleBlockTypeMask) {
|
||||
return new BlockMaskBuilder(bitSets).add(((SingleBlockTypeMask) other).getBlockType()).build(getExtent());
|
||||
if (setStates == 0) {
|
||||
return Masks.alwaysFalse();
|
||||
}
|
||||
if (setStates == totalStates) {
|
||||
return Masks.alwaysTrue();
|
||||
}
|
||||
|
||||
if (setStates == 1) {
|
||||
return new SingleBlockStateMask(getExtent(), setState);
|
||||
}
|
||||
|
||||
if (setStates == totalStates - 1) {
|
||||
return new InverseSingleBlockStateMask(getExtent(), unsetState);
|
||||
}
|
||||
|
||||
if (setTypes == 1) {
|
||||
return new SingleBlockTypeMask(getExtent(), setType);
|
||||
}
|
||||
|
||||
if (setTypes == totalTypes - 1) {
|
||||
return new InverseSingleBlockTypeMask(getExtent(), unsetType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask inverse() {
|
||||
long[][] cloned = bitSets.clone();
|
||||
for (int i = 0; i < cloned.length; i++) {
|
||||
if (cloned[i] == null) cloned[i] = ALL;
|
||||
else if (cloned[i] == ALL) cloned[i] = null;
|
||||
else {
|
||||
for (int j = 0; j < cloned[i].length; j++)
|
||||
cloned[i][j] = ~cloned[i][j];
|
||||
}
|
||||
}
|
||||
boolean[] cloned = ordinals.clone();
|
||||
for (int i = 0; i < cloned.length; i++) cloned[i] = !cloned[i];
|
||||
return new BlockMask(getExtent(), cloned);
|
||||
}
|
||||
|
||||
public boolean test(BlockState block) {
|
||||
long[] bitSet = bitSets[block.getInternalBlockTypeId()];
|
||||
if (bitSet == null) return false;
|
||||
if (bitSet.length == 0) return true;
|
||||
return FastBitSet.get(bitSet, block.getInternalPropertiesId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
BlockStateHolder block = getExtent().getBlock(vector);
|
||||
long[] bitSet = bitSets[block.getInternalBlockTypeId()];
|
||||
if (bitSet == null) return false;
|
||||
if (bitSet.length == 0) return true;
|
||||
return FastBitSet.get(bitSet, block.getInternalPropertiesId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
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.block.BlockTypes;
|
||||
@ -28,6 +29,8 @@ public class BlockMaskBuilder {
|
||||
private static final Operator LESS_EQUAL = (a, b) -> a <= b;
|
||||
private static final Operator NOT = (a, b) -> a != b;
|
||||
|
||||
private final static long[] ALL = new long[0];
|
||||
|
||||
private interface Operator {
|
||||
boolean test(int left, int right);
|
||||
}
|
||||
@ -223,7 +226,7 @@ public class BlockMaskBuilder {
|
||||
if (states == null) return false;
|
||||
List values = prop.getValues();
|
||||
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
return (states == BlockMask.ALL || FastBitSet.get(states, localI));
|
||||
return (states == ALL || FastBitSet.get(states, localI));
|
||||
}
|
||||
|
||||
private void suggest(String input, String property, Collection<BlockType> finalTypes) throws InputParseException {
|
||||
@ -240,6 +243,7 @@ public class BlockMaskBuilder {
|
||||
///// end internal /////
|
||||
|
||||
private long[][] bitSets;
|
||||
private boolean[] ordinals;
|
||||
|
||||
private boolean optimizedStates = true;
|
||||
|
||||
@ -256,14 +260,23 @@ public class BlockMaskBuilder {
|
||||
}
|
||||
|
||||
public BlockMaskBuilder addAll() {
|
||||
Arrays.fill(bitSets, BlockMask.ALL);
|
||||
optimizedStates = true;
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
bitSets[i] = ALL;
|
||||
}
|
||||
reset(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void reset(boolean optimized) {
|
||||
this.ordinals = null;
|
||||
this.optimizedStates = optimized;
|
||||
}
|
||||
|
||||
public BlockMaskBuilder clear() {
|
||||
Arrays.fill(bitSets, null);
|
||||
optimizedStates = true;
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
bitSets[i] = null;
|
||||
}
|
||||
reset(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -277,13 +290,13 @@ public class BlockMaskBuilder {
|
||||
int i = type.getInternalId();
|
||||
long[] states = bitSets[i];
|
||||
if (states != null) {
|
||||
if (states == BlockMask.ALL) {
|
||||
if (states == ALL) {
|
||||
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
Arrays.fill(states, -1);
|
||||
}
|
||||
int stateId = state.getInternalPropertiesId();
|
||||
FastBitSet.clear(states, stateId);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -305,7 +318,7 @@ public class BlockMaskBuilder {
|
||||
if (states != null) {
|
||||
int stateId = state.getInternalPropertiesId();
|
||||
boolean set = true;
|
||||
if (states == BlockMask.ALL) {
|
||||
if (states == ALL) {
|
||||
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
} else {
|
||||
set = FastBitSet.get(states, stateId);
|
||||
@ -315,7 +328,7 @@ public class BlockMaskBuilder {
|
||||
FastBitSet.set(states, stateId);
|
||||
else
|
||||
bitSets[i] = null;
|
||||
optimizedStates = true;
|
||||
reset(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -344,14 +357,14 @@ public class BlockMaskBuilder {
|
||||
List values = prop.getValues();
|
||||
for (int j = 0; j < values.size(); j++) {
|
||||
int localI = j << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
if (states == BlockMask.ALL || FastBitSet.get(states, localI)) {
|
||||
if (states == ALL || FastBitSet.get(states, localI)) {
|
||||
if (!allowed.test(type, new AbstractMap.SimpleEntry(prop, values.get(j)))) {
|
||||
if (states == BlockMask.ALL) {
|
||||
if (states == ALL) {
|
||||
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
FastBitSet.setAll(states);
|
||||
}
|
||||
FastBitSet.clear(states, localI);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,7 +374,7 @@ public class BlockMaskBuilder {
|
||||
}
|
||||
|
||||
public BlockMaskBuilder add(BlockType type) {
|
||||
bitSets[type.getInternalId()] = BlockMask.ALL;
|
||||
bitSets[type.getInternalId()] = ALL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -369,13 +382,13 @@ public class BlockMaskBuilder {
|
||||
BlockType type = state.getBlockType();
|
||||
int i = type.getInternalId();
|
||||
long[] states = bitSets[i];
|
||||
if (states != BlockMask.ALL) {
|
||||
if (states != ALL) {
|
||||
if (states == null) {
|
||||
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
}
|
||||
int stateId = state.getInternalPropertiesId();
|
||||
FastBitSet.set(states, stateId);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -404,7 +417,7 @@ public class BlockMaskBuilder {
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
BlockType type = BlockTypes.get(i);
|
||||
if (allow.test(type)) {
|
||||
bitSets[i] = BlockMask.ALL;
|
||||
bitSets[i] = ALL;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@ -413,7 +426,7 @@ public class BlockMaskBuilder {
|
||||
public BlockMaskBuilder addAll(Predicate<BlockType> typePredicate, BiPredicate<BlockType, Map.Entry<Property<?>, ?>> propPredicate) {
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
long[] states = bitSets[i];
|
||||
if (states == BlockMask.ALL) continue;
|
||||
if (states == ALL) continue;
|
||||
BlockType type = BlockTypes.get(i);
|
||||
if (!typePredicate.test(type)) {
|
||||
continue;
|
||||
@ -428,7 +441,7 @@ public class BlockMaskBuilder {
|
||||
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
}
|
||||
FastBitSet.set(states, localI);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -440,7 +453,7 @@ public class BlockMaskBuilder {
|
||||
public BlockMaskBuilder add(BlockType type, Property property, int index) {
|
||||
AbstractProperty prop = (AbstractProperty) property;
|
||||
long[] states = bitSets[type.getInternalId()];
|
||||
if (states == BlockMask.ALL) return this;
|
||||
if (states == ALL) return this;
|
||||
|
||||
List values = property.getValues();
|
||||
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
@ -449,7 +462,7 @@ public class BlockMaskBuilder {
|
||||
bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
}
|
||||
set(type, states, property, index);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -460,13 +473,13 @@ public class BlockMaskBuilder {
|
||||
if (states == null) return this;
|
||||
List values = property.getValues();
|
||||
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
if (states == BlockMask.ALL || FastBitSet.get(states, localI)) {
|
||||
if (states == BlockMask.ALL) {
|
||||
if (states == ALL || FastBitSet.get(states, localI)) {
|
||||
if (states == ALL) {
|
||||
bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1);
|
||||
FastBitSet.setAll(states);
|
||||
}
|
||||
clear(type, states, property, index);
|
||||
optimizedStates = false;
|
||||
reset(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -512,7 +525,7 @@ public class BlockMaskBuilder {
|
||||
if (!optimizedStates) {
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
long[] bitSet = bitSets[i];
|
||||
if (bitSet == null || bitSet == BlockMask.ALL) continue;
|
||||
if (bitSet == null || bitSet == ALL) continue;
|
||||
BlockType type = BlockTypes.get(i);
|
||||
int maxStateId = type.getMaxStateId();
|
||||
if (maxStateId == 0) {
|
||||
@ -520,7 +533,7 @@ public class BlockMaskBuilder {
|
||||
bitSets[i] = null;
|
||||
continue;
|
||||
} else {
|
||||
bitSets[i] = BlockMask.ALL;
|
||||
bitSets[i] = ALL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -535,19 +548,38 @@ public class BlockMaskBuilder {
|
||||
}
|
||||
}
|
||||
if (set == 0) bitSets[i] = null;
|
||||
else if (clear == 0) bitSets[i] = BlockMask.ALL;
|
||||
else if (clear == 0) bitSets[i] = ALL;
|
||||
}
|
||||
optimizedStates = true;
|
||||
reset(true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
protected long[][] getBits() {
|
||||
return this.bitSets;
|
||||
private boolean[] getOrdinals() {
|
||||
if (ordinals == null) {
|
||||
ordinals = new boolean[BlockTypes.states.length];
|
||||
for (int i = 0; i < BlockTypes.values.length; i++) {
|
||||
long[] bitSet = bitSets[i];
|
||||
if (bitSet == null) continue;
|
||||
BlockType type = BlockTypes.values[i];
|
||||
if (bitSet == ALL) {
|
||||
for (BlockState state : type.getAllStates()) {
|
||||
ordinals[state.getOrdinal()] = true;
|
||||
}
|
||||
} else {
|
||||
for (BlockState state : type.getAllStates()) {
|
||||
if (FastBitSet.get(bitSet, state.getInternalPropertiesId())) {
|
||||
ordinals[state.getOrdinal()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ordinals;
|
||||
}
|
||||
|
||||
public BlockMask build(Extent extent) {
|
||||
optimize();
|
||||
return new BlockMask(extent, bitSets);
|
||||
return new BlockMask(extent, getOrdinals());
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -37,8 +36,12 @@ import java.util.Set;
|
||||
*
|
||||
* <p>This mask checks for ONLY the block type. If state should also be checked,
|
||||
* use {@link BlockMask}.</p>
|
||||
* @deprecated use BlockMaskBuilder
|
||||
*/
|
||||
public class BlockTypeMask extends AbstractExtentMask {
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@Deprecated
|
||||
public final class BlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
private final boolean[] types;
|
||||
|
||||
@ -110,12 +113,11 @@ public class BlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return types[getExtent().getBlock(vector).getBlockType().getInternalId()];
|
||||
return test(vector.getBlock(getExtent()).getBlockType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
public boolean test(BlockType block) {
|
||||
return types[block.getInternalId()];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
public class SingleBlockTypeMask extends AbstractExtentMask {
|
||||
public class SingleBlockTypeMask extends ABlockMask {
|
||||
private final int internalId;
|
||||
|
||||
public SingleBlockTypeMask(Extent extent, BlockType type) {
|
||||
@ -15,12 +16,17 @@ public class SingleBlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return getExtent().getBlock(vector).getBlockType().getInternalId() == internalId;
|
||||
return test(vector.getBlock(getExtent()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean test(BlockState state) {
|
||||
return state.getBlockType().getInternalId() == internalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask inverse() {
|
||||
return new BlockMaskBuilder().add(BlockTypes.get(internalId)).build(getExtent()).inverse();
|
||||
return new InverseSingleBlockTypeMask(getExtent(), BlockTypes.values[internalId]);
|
||||
}
|
||||
|
||||
public BlockType getBlockType() {
|
||||
|
@ -27,10 +27,10 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SolidBlockMask extends BlockTypeMask {
|
||||
|
||||
public class SolidBlockMask extends BlockMask {
|
||||
public SolidBlockMask(Extent extent) {
|
||||
super(extent, getTypes());
|
||||
super(extent);
|
||||
add(state -> state.getMaterial().isSolid());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,11 +22,7 @@ package com.sk89q.worldedit.function.visitor;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.MappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.object.IntegerTrio;
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
@ -38,8 +34,11 @@ import com.sk89q.worldedit.util.Direction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Performs a breadth-first search starting from points added with
|
||||
* {@link #visit(BlockVector3)}. The search continues
|
||||
@ -81,13 +80,12 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
}
|
||||
|
||||
private final RegionFunction function;
|
||||
private BlockVectorSet queue;
|
||||
private BlockVector3[] directions;
|
||||
private BlockVectorSet visited;
|
||||
private BlockVectorSet queue;
|
||||
private int affected = 0;
|
||||
private int currentDepth = 0;
|
||||
private final int maxDepth;
|
||||
private List<BlockVector3> directions = new ArrayList<>();
|
||||
private final MappedFaweQueue mFaweQueue;
|
||||
private int maxBranch = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
@ -101,33 +99,20 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
}
|
||||
|
||||
public BreadthFirstSearch(RegionFunction function, int maxDepth) {
|
||||
this(function, maxDepth, null);
|
||||
checkNotNull(function);
|
||||
|
||||
}
|
||||
|
||||
public BreadthFirstSearch(RegionFunction function, int maxDepth, HasFaweQueue faweQueue) {
|
||||
checkNotNull(function);
|
||||
FaweQueue fq = faweQueue != null ? faweQueue.getQueue() : null;
|
||||
this.mFaweQueue = fq instanceof MappedFaweQueue ? (MappedFaweQueue) fq : null;
|
||||
this.queue = new BlockVectorSet();
|
||||
this.visited = new BlockVectorSet();
|
||||
this.function = function;
|
||||
this.directions.addAll(Arrays.asList(DEFAULT_DIRECTIONS));
|
||||
this.directions = DEFAULT_DIRECTIONS;
|
||||
this.maxDepth = maxDepth;
|
||||
}
|
||||
|
||||
public void setDirections(List<BlockVector3> directions) {
|
||||
public void setDirections(BlockVector3... directions) {
|
||||
this.directions = directions;
|
||||
}
|
||||
|
||||
private IntegerTrio[] getIntDirections() {
|
||||
IntegerTrio[] array = new IntegerTrio[directions.size()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
BlockVector3 dir = directions.get(i);
|
||||
array[i] = new IntegerTrio(dir.getBlockX(), dir.getBlockY(), dir.getBlockZ());
|
||||
}
|
||||
return array;
|
||||
public void setDirections(Collection<BlockVector3> directions) {
|
||||
setDirections(directions.toArray(new BlockVector3[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,34 +123,36 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
* unit vectors. An example of a valid direction is
|
||||
* {@code BlockVector3.at(1, 0, 1)}.</p>
|
||||
*
|
||||
* <p>The list of directions can be cleared.</p>
|
||||
*
|
||||
* @return the list of directions
|
||||
*/
|
||||
protected Collection<BlockVector3> getDirections() {
|
||||
return directions;
|
||||
public Collection<BlockVector3> getDirections() {
|
||||
return Arrays.asList(directions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the directions along the axes as directions to visit.
|
||||
*/
|
||||
protected void addAxes() {
|
||||
directions.add(BlockVector3.UNIT_MINUS_Y);
|
||||
directions.add(BlockVector3.UNIT_Y);
|
||||
directions.add(BlockVector3.UNIT_MINUS_X);
|
||||
directions.add(BlockVector3.UNIT_X);
|
||||
directions.add(BlockVector3.UNIT_MINUS_Z);
|
||||
directions.add(BlockVector3.UNIT_Z);
|
||||
public void addAxes() {
|
||||
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
|
||||
set.add(BlockVector3.UNIT_MINUS_Y);
|
||||
set.add(BlockVector3.UNIT_Y);
|
||||
set.add(BlockVector3.UNIT_MINUS_X);
|
||||
set.add(BlockVector3.UNIT_X);
|
||||
set.add(BlockVector3.UNIT_MINUS_Z);
|
||||
set.add(BlockVector3.UNIT_Z);
|
||||
setDirections(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the diagonal directions as directions to visit.
|
||||
*/
|
||||
protected void addDiagonal() {
|
||||
directions.add(Direction.NORTHEAST.toBlockVector());
|
||||
directions.add(Direction.SOUTHEAST.toBlockVector());
|
||||
directions.add(Direction.SOUTHWEST.toBlockVector());
|
||||
directions.add(Direction.NORTHWEST.toBlockVector());
|
||||
public void addDiagonal() {
|
||||
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
|
||||
set.add(Direction.NORTHEAST.toBlockVector());
|
||||
set.add(Direction.SOUTHEAST.toBlockVector());
|
||||
set.add(Direction.SOUTHWEST.toBlockVector());
|
||||
set.add(Direction.NORTHWEST.toBlockVector());
|
||||
setDirections(set);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,21 +193,6 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
public void setMaxBranch(int maxBranch) {
|
||||
this.maxBranch = maxBranch;
|
||||
}
|
||||
/**
|
||||
* Try to visit the given 'to' location.
|
||||
*
|
||||
* @param from the origin block
|
||||
* @param to the block under question
|
||||
*/
|
||||
private void visit(BlockVector3 from, BlockVector3 to) {
|
||||
BlockVector3 blockVector = to;
|
||||
if (!visited.contains(blockVector)) {
|
||||
visited.add(blockVector);
|
||||
if (isVisitable(from, to)) {
|
||||
queue.add(blockVector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given 'to' block should be visited, starting from the
|
||||
@ -244,42 +216,22 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
IntegerTrio[] dirs = getIntDirections();
|
||||
// MutableBlockVector3 mutable2 = new MutableBlockVector3();
|
||||
boolean shouldTrim = false;
|
||||
BlockVector3[] dirs = directions;
|
||||
BlockVectorSet tempQueue = new BlockVectorSet();
|
||||
BlockVectorSet chunkLoadSet = new BlockVectorSet();
|
||||
for (currentDepth = 0; !queue.isEmpty() && currentDepth <= maxDepth; currentDepth++) {
|
||||
if (mFaweQueue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 1) {
|
||||
int cx = Integer.MIN_VALUE;
|
||||
int cz = Integer.MIN_VALUE;
|
||||
for (BlockVector3 from : queue) {
|
||||
for (IntegerTrio direction : dirs) {
|
||||
int x = from.getBlockX() + direction.x;
|
||||
int z = from.getBlockZ() + direction.z;
|
||||
if (cx != (cx = x >> 4) || cz != (cz = z >> 4)) {
|
||||
int y = from.getBlockY() + direction.y;
|
||||
if (y < 0 || y >= 256) {
|
||||
continue;
|
||||
}
|
||||
if (!visited.contains(x, y, z)) {
|
||||
chunkLoadSet.add(cx, 0, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (BlockVector3 chunk : chunkLoadSet) {
|
||||
mFaweQueue.queueChunkLoad(chunk.getBlockX(), chunk.getBlockZ());
|
||||
}
|
||||
}
|
||||
for (BlockVector3 from : queue) {
|
||||
if (function.apply(from)) affected++;
|
||||
for (int i = 0, j = 0; i < dirs.length && j < maxBranch; i++) {
|
||||
IntegerTrio direction = dirs[i];
|
||||
int y = from.getBlockY() + direction.y;
|
||||
BlockVector3 direction = dirs[i];
|
||||
int y = from.getBlockY() + direction.getY();
|
||||
if (y < 0 || y >= 256) {
|
||||
continue;
|
||||
}
|
||||
int x = from.getBlockX() + direction.x;
|
||||
int z = from.getBlockZ() + direction.z;
|
||||
int x = from.getBlockX() + direction.getX();
|
||||
int z = from.getBlockZ() + direction.getZ();
|
||||
if (!visited.contains(x, y, z)) {
|
||||
if (isVisitable(from, mutable.setComponents(x, y, z))) {
|
||||
j++;
|
||||
|
@ -21,30 +21,36 @@ package com.sk89q.worldedit.math;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* An immutable 3-dimensional vector.
|
||||
*/
|
||||
public class BlockVector3 {
|
||||
public abstract class BlockVector3 {
|
||||
|
||||
public static final BlockVector3 ZERO = new BlockVector3(0, 0, 0);
|
||||
public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0);
|
||||
public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0);
|
||||
public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1);
|
||||
public static final BlockVector3 UNIT_MINUS_X = new BlockVector3(-1, 0, 0);
|
||||
public static final BlockVector3 UNIT_MINUS_Y = new BlockVector3(0, -1, 0);
|
||||
public static final BlockVector3 UNIT_MINUS_Z = new BlockVector3(0, 0, -1);
|
||||
public static final BlockVector3 ONE = new BlockVector3(1, 1, 1);
|
||||
public static final BlockVector3 ZERO = BlockVector3.at(0, 0, 0);
|
||||
public static final BlockVector3 UNIT_X = BlockVector3.at(1, 0, 0);
|
||||
public static final BlockVector3 UNIT_Y = BlockVector3.at(0, 1, 0);
|
||||
public static final BlockVector3 UNIT_Z = BlockVector3.at(0, 0, 1);
|
||||
public static final BlockVector3 UNIT_MINUS_X = BlockVector3.at(-1, 0, 0);
|
||||
public static final BlockVector3 UNIT_MINUS_Y = BlockVector3.at(0, -1, 0);
|
||||
public static final BlockVector3 UNIT_MINUS_Z = BlockVector3.at(0, 0, -1);
|
||||
public static final BlockVector3 ONE = BlockVector3.at(1, 1, 1);
|
||||
|
||||
public static BlockVector3 at(double x, double y, double z) {
|
||||
return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
|
||||
}
|
||||
|
||||
public static BlockVector3 at(int x, int y, int z) {
|
||||
return new BlockVector3(x, y, z);
|
||||
return new BlockVector3Imp(x, y, z);
|
||||
}
|
||||
|
||||
// thread-safe initialization idiom
|
||||
@ -65,23 +71,6 @@ public class BlockVector3 {
|
||||
return YzxOrderComparator.YZX_ORDER;
|
||||
}
|
||||
|
||||
protected int x, y, z;
|
||||
|
||||
protected BlockVector3(){}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param y the Y coordinate
|
||||
* @param z the Z coordinate
|
||||
*/
|
||||
protected BlockVector3(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public MutableBlockVector3 setComponents(double x, double y, double z) {
|
||||
return new MutableBlockVector3((int) x, (int) y, (int) z);
|
||||
}
|
||||
@ -91,37 +80,71 @@ public class BlockVector3 {
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutX(double x) {
|
||||
return new MutableBlockVector3((int) x, y, z);
|
||||
return new MutableBlockVector3((int) x, getY(), getZ());
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutY(double y) {
|
||||
return new MutableBlockVector3(x, (int) y, z);
|
||||
return new MutableBlockVector3(getX(), (int) y, getZ());
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutZ(double z) {
|
||||
return new MutableBlockVector3(x, y, (int) z);
|
||||
return new MutableBlockVector3(getX(), getY(), (int) z);
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutX(int x) {
|
||||
return new MutableBlockVector3(x, y, z);
|
||||
return new MutableBlockVector3(x, getY(), getZ());
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutY(int y) {
|
||||
return new MutableBlockVector3(x, y, z);
|
||||
return new MutableBlockVector3(getX(), y, getZ());
|
||||
}
|
||||
|
||||
public MutableBlockVector3 mutZ(int z) {
|
||||
return new MutableBlockVector3(x, y, z);
|
||||
return new MutableBlockVector3(getX(), getY(), z);
|
||||
}
|
||||
|
||||
public BlockVector3 toImmutable() {
|
||||
return BlockVector3.at(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the BlockVector3 to the north<br>
|
||||
// * Normal use you would use north(this),
|
||||
// * To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3)
|
||||
// * There is no gaurantee it will use this provided vector
|
||||
// * @param orDefault the vector to use as the result<br>
|
||||
// * @return BlockVector3
|
||||
// */
|
||||
// public BlockVector3 north(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX(), getY(), getZ() - 1);
|
||||
// }
|
||||
//
|
||||
// public BlockVector3 east(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX() + 1, getY(), getZ());
|
||||
// }
|
||||
//
|
||||
// public BlockVector3 south(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX(), getY(), getZ() + 1);
|
||||
// }
|
||||
//
|
||||
// public BlockVector3 west(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX() - 1, getY(), getZ());
|
||||
// }
|
||||
//
|
||||
// public BlockVector3 up(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX(), getY() + 1, getZ());
|
||||
// }
|
||||
//
|
||||
// public BlockVector3 down(BlockVector3 orDefault) {
|
||||
// return orDefault.setComponents(getX(), getY() - 1, getZ());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the X coordinate.
|
||||
*
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
public abstract int getX();
|
||||
|
||||
/**
|
||||
* Get the X coordinate.
|
||||
@ -129,7 +152,7 @@ public class BlockVector3 {
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public int getBlockX() {
|
||||
return x;
|
||||
return getX();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +162,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 withX(int x) {
|
||||
return BlockVector3.at(x, y, z);
|
||||
return BlockVector3.at(x, getY(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,9 +170,7 @@ public class BlockVector3 {
|
||||
*
|
||||
* @return the y coordinate
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
public abstract int getY();
|
||||
|
||||
/**
|
||||
* Get the Y coordinate.
|
||||
@ -157,7 +178,7 @@ public class BlockVector3 {
|
||||
* @return the y coordinate
|
||||
*/
|
||||
public int getBlockY() {
|
||||
return y;
|
||||
return getY();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +188,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 withY(int y) {
|
||||
return BlockVector3.at(x, y, z);
|
||||
return BlockVector3.at(getX(), y, getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,9 +196,7 @@ public class BlockVector3 {
|
||||
*
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
public abstract int getZ();
|
||||
|
||||
/**
|
||||
* Get the Z coordinate.
|
||||
@ -185,7 +204,7 @@ public class BlockVector3 {
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public int getBlockZ() {
|
||||
return z;
|
||||
return getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +214,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 withZ(int z) {
|
||||
return BlockVector3.at(x, y, z);
|
||||
return BlockVector3.at(getX(), getY(), z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,7 +224,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 add(BlockVector3 other) {
|
||||
return add(other.x, other.y, other.z);
|
||||
return add(other.getX(), other.getY(), other.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,7 +236,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 add(int x, int y, int z) {
|
||||
return BlockVector3.at(this.x + x, this.y + y, this.z + z);
|
||||
return BlockVector3.at(this.getX() + x, this.getY() + y, this.getZ() + z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,12 +247,12 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 add(BlockVector3... others) {
|
||||
int newX = x, newY = y, newZ = z;
|
||||
int newX = getX(), newY = getY(), newZ = getZ();
|
||||
|
||||
for (BlockVector3 other : others) {
|
||||
newX += other.x;
|
||||
newY += other.y;
|
||||
newZ += other.z;
|
||||
newX += other.getX();
|
||||
newY += other.getY();
|
||||
newZ += other.getZ();
|
||||
}
|
||||
|
||||
return BlockVector3.at(newX, newY, newZ);
|
||||
@ -247,7 +266,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 subtract(BlockVector3 other) {
|
||||
return subtract(other.x, other.y, other.z);
|
||||
return subtract(other.getX(), other.getY(), other.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,7 +279,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 subtract(int x, int y, int z) {
|
||||
return BlockVector3.at(this.x - x, this.y - y, this.z - z);
|
||||
return BlockVector3.at(this.getX() - x, this.getY() - y, this.getZ() - z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,12 +290,12 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 subtract(BlockVector3... others) {
|
||||
int newX = x, newY = y, newZ = z;
|
||||
int newX = getX(), newY = getY(), newZ = getZ();
|
||||
|
||||
for (BlockVector3 other : others) {
|
||||
newX -= other.x;
|
||||
newY -= other.y;
|
||||
newZ -= other.z;
|
||||
newX -= other.getX();
|
||||
newY -= other.getY();
|
||||
newZ -= other.getZ();
|
||||
}
|
||||
|
||||
return BlockVector3.at(newX, newY, newZ);
|
||||
@ -289,7 +308,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 multiply(BlockVector3 other) {
|
||||
return multiply(other.x, other.y, other.z);
|
||||
return multiply(other.getX(), other.getY(), other.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,7 +320,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 multiply(int x, int y, int z) {
|
||||
return BlockVector3.at(this.x * x, this.y * y, this.z * z);
|
||||
return BlockVector3.at(this.getX() * x, this.getY() * y, this.getZ() * z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -311,12 +330,12 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 multiply(BlockVector3... others) {
|
||||
int newX = x, newY = y, newZ = z;
|
||||
int newX = getX(), newY = getY(), newZ = getZ();
|
||||
|
||||
for (BlockVector3 other : others) {
|
||||
newX *= other.x;
|
||||
newY *= other.y;
|
||||
newZ *= other.z;
|
||||
newX *= other.getX();
|
||||
newY *= other.getY();
|
||||
newZ *= other.getZ();
|
||||
}
|
||||
|
||||
return BlockVector3.at(newX, newY, newZ);
|
||||
@ -339,7 +358,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 divide(BlockVector3 other) {
|
||||
return divide(other.x, other.y, other.z);
|
||||
return divide(other.getX(), other.getY(), other.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,7 +370,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 divide(int x, int y, int z) {
|
||||
return BlockVector3.at(this.x / x, this.y / y, this.z / z);
|
||||
return BlockVector3.at(this.getX() / x, this.getY() / y, this.getZ() / z);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,7 +442,7 @@ public class BlockVector3 {
|
||||
* @return length, squared
|
||||
*/
|
||||
public int lengthSq() {
|
||||
return x * x + y * y + z * z;
|
||||
return getX() * getX() + getY() * getY() + getZ() * getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -443,9 +462,9 @@ public class BlockVector3 {
|
||||
* @return distance
|
||||
*/
|
||||
public int distanceSq(BlockVector3 other) {
|
||||
int dx = other.x - x;
|
||||
int dy = other.y - y;
|
||||
int dz = other.z - z;
|
||||
int dx = other.getX() - getX();
|
||||
int dy = other.getY() - getY();
|
||||
int dz = other.getZ() - getZ();
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
@ -457,9 +476,9 @@ public class BlockVector3 {
|
||||
*/
|
||||
public BlockVector3 normalize() {
|
||||
double len = length();
|
||||
double x = this.x / len;
|
||||
double y = this.y / len;
|
||||
double z = this.z / len;
|
||||
double x = this.getX() / len;
|
||||
double y = this.getY() / len;
|
||||
double z = this.getZ() / len;
|
||||
return BlockVector3.at(x, y, z);
|
||||
}
|
||||
|
||||
@ -470,7 +489,7 @@ public class BlockVector3 {
|
||||
* @return the dot product of this and the other vector
|
||||
*/
|
||||
public double dot(BlockVector3 other) {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -480,10 +499,10 @@ public class BlockVector3 {
|
||||
* @return the cross product of this and the other vector
|
||||
*/
|
||||
public BlockVector3 cross(BlockVector3 other) {
|
||||
return new BlockVector3(
|
||||
y * other.z - z * other.y,
|
||||
z * other.x - x * other.z,
|
||||
x * other.y - y * other.x
|
||||
return new BlockVector3Imp(
|
||||
getY() * other.getZ() - getZ() * other.getY(),
|
||||
getZ() * other.getX() - getX() * other.getZ(),
|
||||
getX() * other.getY() - getY() * other.getX()
|
||||
);
|
||||
}
|
||||
|
||||
@ -495,7 +514,7 @@ public class BlockVector3 {
|
||||
* @return true if the vector is contained
|
||||
*/
|
||||
public boolean containedWithin(BlockVector3 min, BlockVector3 max) {
|
||||
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
|
||||
return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,11 +526,11 @@ public class BlockVector3 {
|
||||
*/
|
||||
public BlockVector3 clampY(int min, int max) {
|
||||
checkArgument(min <= max, "minimum cannot be greater than maximum");
|
||||
if (y < min) {
|
||||
return BlockVector3.at(x, min, z);
|
||||
if (getY() < min) {
|
||||
return BlockVector3.at(getX(), min, getZ());
|
||||
}
|
||||
if (y > max) {
|
||||
return BlockVector3.at(x, max, z);
|
||||
if (getY() > max) {
|
||||
return BlockVector3.at(getX(), max, getZ());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -555,7 +574,7 @@ public class BlockVector3 {
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector3 abs() {
|
||||
return BlockVector3.at(Math.abs(x), Math.abs(y), Math.abs(z));
|
||||
return BlockVector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -571,8 +590,8 @@ public class BlockVector3 {
|
||||
*/
|
||||
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
|
||||
angle = Math.toRadians(angle);
|
||||
double x = this.x - aboutX;
|
||||
double z = this.z - aboutZ;
|
||||
double x = this.getX() - aboutX;
|
||||
double z = this.getZ() - aboutZ;
|
||||
double cos = Math.cos(angle);
|
||||
double sin = Math.sin(angle);
|
||||
double x2 = x * cos - z * sin;
|
||||
@ -580,7 +599,7 @@ public class BlockVector3 {
|
||||
|
||||
return BlockVector3.at(
|
||||
x2 + aboutX + translateX,
|
||||
y,
|
||||
getY(),
|
||||
z2 + aboutZ + translateZ
|
||||
);
|
||||
}
|
||||
@ -626,10 +645,10 @@ public class BlockVector3 {
|
||||
* @return minimum
|
||||
*/
|
||||
public BlockVector3 getMinimum(BlockVector3 v2) {
|
||||
return new BlockVector3(
|
||||
Math.min(x, v2.x),
|
||||
Math.min(y, v2.y),
|
||||
Math.min(z, v2.z)
|
||||
return new BlockVector3Imp(
|
||||
Math.min(getX(), v2.getX()),
|
||||
Math.min(getY(), v2.getY()),
|
||||
Math.min(getZ(), v2.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
@ -640,44 +659,110 @@ public class BlockVector3 {
|
||||
* @return maximum
|
||||
*/
|
||||
public BlockVector3 getMaximum(BlockVector3 v2) {
|
||||
return new BlockVector3(
|
||||
Math.max(x, v2.x),
|
||||
Math.max(y, v2.y),
|
||||
Math.max(z, v2.z)
|
||||
return new BlockVector3Imp(
|
||||
Math.max(getX(), v2.getX()),
|
||||
Math.max(getY(), v2.getY()),
|
||||
Math.max(getZ(), v2.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Methods for getting/setting blocks
|
||||
|
||||
Why are these methods here?
|
||||
- Getting a block at a position requires various operations
|
||||
(bounds checks, cache checks, ensuring loaded chunk, get ChunkSection, etc.)
|
||||
- When iterating over a region, it will provide custom BlockVector3 positions
|
||||
- These override the below set/get and avoid lookups (as the iterator shifts it to the chunk level)
|
||||
*/
|
||||
|
||||
public boolean setOrdinal(Extent orDefault, int ordinal) {
|
||||
return orDefault.setBlock(this, BlockState.getFromOrdinal(ordinal));
|
||||
}
|
||||
|
||||
public boolean setBlock(Extent orDefault, BlockState state) {
|
||||
return orDefault.setBlock(this, state);
|
||||
}
|
||||
|
||||
public boolean setFullBlock(Extent orDefault, BaseBlock block) {
|
||||
return orDefault.setBlock(this, block);
|
||||
}
|
||||
|
||||
public boolean setBiome(Extent orDefault, BiomeType biome) {
|
||||
return orDefault.setBiome(getX(), getY(), getZ(), biome);
|
||||
}
|
||||
|
||||
public int getOrdinal(Extent orDefault) {
|
||||
return getBlock(orDefault).getOrdinal();
|
||||
}
|
||||
|
||||
public char getOrdinalChar(Extent orDefault) {
|
||||
return (char) getOrdinal(orDefault);
|
||||
}
|
||||
|
||||
public BlockState getBlock(Extent orDefault) {
|
||||
return orDefault.getBlock(this);
|
||||
}
|
||||
|
||||
public BaseBlock getFullBlock(Extent orDefault) {
|
||||
return orDefault.getFullBlock(this);
|
||||
}
|
||||
|
||||
public CompoundTag getNbtData(Extent orDefault) {
|
||||
return orDefault.getFullBlock(getX(), getY(), getZ()).getNbtData();
|
||||
}
|
||||
|
||||
public BlockState getOrdinalBelow(Extent orDefault) {
|
||||
return orDefault.getBlock(getX(), getY() - 1, getZ());
|
||||
}
|
||||
|
||||
public BlockState getStateAbove(Extent orDefault) {
|
||||
return orDefault.getBlock(getX(), getY() + 1, getZ());
|
||||
}
|
||||
|
||||
public BlockState getStateRelativeY(Extent orDefault, final int y) {
|
||||
return orDefault.getBlock(getX(), getY() + y, getZ());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Adapt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a 2D vector by dropping the Y component from this vector.
|
||||
*
|
||||
* @return a new {@link BlockVector2}
|
||||
*/
|
||||
public BlockVector2 toBlockVector2() {
|
||||
return BlockVector2.at(x, z);
|
||||
return BlockVector2.at(getX(), getZ());
|
||||
}
|
||||
|
||||
public Vector3 toVector3() {
|
||||
return Vector3.at(x, y, z);
|
||||
return Vector3.at(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public final boolean equals(Object obj) {
|
||||
if (!(obj instanceof BlockVector3)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BlockVector3 other = (BlockVector3) obj;
|
||||
return other.x == this.x && other.y == this.y && other.z == this.z;
|
||||
return equals((BlockVector3) obj);
|
||||
}
|
||||
|
||||
public final boolean equals(BlockVector3 other) {
|
||||
return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (x ^ (z << 12)) ^ (y << 24);
|
||||
return (getX() ^ (getZ() << 12)) ^ (getY() << 24);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
return "(" + getX() + ", " + getY() + ", " + getZ() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,18 @@
|
||||
package com.sk89q.worldedit.math;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
|
||||
public class MutableVector3 extends Vector3 {
|
||||
|
||||
public MutableVector3() {
|
||||
}
|
||||
public static MutableVector3 get(int x, int y, int z) {
|
||||
return FaweCache.MUTABLE_VECTOR3.get().setComponents(x, y, z);
|
||||
}
|
||||
|
||||
public static MutableVector3 get(double x, double y, double z) {
|
||||
return FaweCache.MUTABLE_VECTOR3.get().setComponents(x, y, z);
|
||||
}
|
||||
|
||||
public MutableVector3(double x, double y, double z) {
|
||||
super(x, y, z);
|
||||
@ -77,7 +86,4 @@ public class MutableVector3 extends Vector3 {
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ package com.sk89q.worldedit.regions;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.beta.ChunkFilterBlock;
|
||||
import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -387,7 +392,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ && y >= this.minY && y <= this.maxY;
|
||||
@ -398,14 +402,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
|
||||
return position.containedWithin(min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<BlockVector3> iterator() {
|
||||
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) {
|
||||
@ -610,4 +606,51 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
BlockVector3 size = BlockVector3.ONE.multiply(apothem);
|
||||
return new CuboidRegion(origin.subtract(size), origin.add(size));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return minY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
|
||||
int X = chunk.getX();
|
||||
int Z = chunk.getZ();
|
||||
block = block.init(X, Z, get);
|
||||
|
||||
if ((minX + 15) >> 4 <= X && (maxX - 15) >> 4 >= X && (minZ + 15) >> 4 <= Z && (maxZ - 15) >> 4 >= Z) {
|
||||
filter(chunk, filter, block, get, set, minY, maxY);
|
||||
return;
|
||||
}
|
||||
int localMinX = Math.max(minX, X << 4) & 15;
|
||||
int localMaxX = Math.min(maxX, 15 + X << 4) & 15;
|
||||
int localMinZ = Math.max(minZ, Z << 4) & 15;
|
||||
int localMaxZ = Math.min(maxZ, 15 + Z << 4) & 15;
|
||||
|
||||
int yStart = (minY & 15);
|
||||
int yEnd = (maxY & 15);
|
||||
|
||||
int minSection = minY >> 4;
|
||||
int maxSection = maxY >> 4;
|
||||
if (minSection == maxSection) {
|
||||
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
|
||||
return;
|
||||
}
|
||||
if (yStart != 0) {
|
||||
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, 15, localMaxZ);
|
||||
minSection++;
|
||||
}
|
||||
if (yEnd != 15) {
|
||||
filter(chunk, filter, block, get, set, minSection, localMinX, 0, localMinZ, localMaxX, 15, localMaxZ);
|
||||
maxSection--;
|
||||
}
|
||||
for (int layer = minSection; layer < maxSection; layer++) {
|
||||
filter(chunk, filter, block, get, set, layer, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,11 @@ package com.sk89q.worldedit.regions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.beta.ChunkFilterBlock;
|
||||
import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -288,26 +293,22 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
|
||||
minY += changeY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a point is inside this region.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
final int blockY = position.getBlockY();
|
||||
if (blockY < minY || blockY > maxY) {
|
||||
public boolean contains(int x, int y, int z) {
|
||||
if (y < minY || y > maxY) {
|
||||
return false;
|
||||
}
|
||||
//todo the following lines can possibly be removed and replaced with upstream
|
||||
int px = position.getBlockX();
|
||||
int pz = position.getBlockZ();
|
||||
return contains(x, z);
|
||||
}
|
||||
|
||||
double dx = Math.abs(px - center.getBlockX()) * radiusInverse.getX();
|
||||
double dz = Math.abs(pz - center.getBlockZ()) * radiusInverse.getZ();
|
||||
@Override
|
||||
public boolean contains(int x, int z) {
|
||||
double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX();
|
||||
double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ();
|
||||
|
||||
return dx * dx + dz * dz <= 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the height of the cylinder to fit the specified Y.
|
||||
*
|
||||
@ -362,6 +363,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
|
||||
return Polygons.polygonizeCylinder(center, radius, maxPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return minY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance with the given center and radius in the X and Z
|
||||
* axes with a Y that extends from the bottom of the extent to the top
|
||||
@ -381,4 +392,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
|
||||
return new CylinderRegion(center, radiusVec, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(final IChunk chunk, final Filter filter, final ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
|
||||
int bcx = chunk.getX() >> 4;
|
||||
int bcz = chunk.getZ() >> 4;
|
||||
int tcx = bcx + 15;
|
||||
int tcz = bcz + 15;
|
||||
if (contains(bcx, bcz) && contains(tcx, tcz)) {
|
||||
filter(chunk, filter, block, get, set, minY, maxY);
|
||||
return;
|
||||
}
|
||||
super.filter(chunk, filter, block, get, set);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,13 @@
|
||||
|
||||
package com.sk89q.worldedit.regions;
|
||||
|
||||
|
||||
import com.boydti.fawe.beta.ChunkFilterBlock;
|
||||
import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
@ -44,6 +51,7 @@ public class EllipsoidRegion extends AbstractRegion {
|
||||
private Vector3 radius;
|
||||
|
||||
private Vector3 radiusSqr;
|
||||
private Vector3 inverseRadius;
|
||||
private int radiusLengthSqr;
|
||||
private boolean sphere;
|
||||
|
||||
@ -180,6 +188,12 @@ public class EllipsoidRegion extends AbstractRegion {
|
||||
radiusSqr = radius.multiply(radius);
|
||||
radiusLengthSqr = (int) radiusSqr.getX();
|
||||
this.sphere = radius.getY() == radius.getX() && radius.getX() == radius.getZ();
|
||||
if (radius.getY() == radius.getX() && radius.getX() == radius.getZ()) {
|
||||
this.sphere = true;
|
||||
} else {
|
||||
this.sphere = false;
|
||||
}
|
||||
inverseRadius = Vector3.ONE.divide(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -206,30 +220,50 @@ public class EllipsoidRegion extends AbstractRegion {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
int cx = x - center.getBlockX();
|
||||
int cx2 = cx * cx;
|
||||
if (cx2 > radiusSqr.getBlockX()) {
|
||||
return false;
|
||||
}
|
||||
int cz = z - center.getBlockZ();
|
||||
int cz2 = cz * cz;
|
||||
if (cz2 > radiusSqr.getBlockZ()) {
|
||||
return false;
|
||||
}
|
||||
int cy = y - center.getBlockY();
|
||||
int cy2 = cy * cy;
|
||||
if (radiusSqr.getBlockY() < 255 && cy2 > radiusSqr.getBlockY()) {
|
||||
return false;
|
||||
}
|
||||
if (sphere) {
|
||||
return cx2 + cy2 + cz2 <= radiusLengthSqr;
|
||||
}
|
||||
double cxd = cx2 * inverseRadius.getX();
|
||||
double cyd = cy2 * inverseRadius.getY();
|
||||
double czd = cz2 * inverseRadius.getZ();
|
||||
return cxd + cyd + czd <= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 position) {
|
||||
int cx = position.getBlockX() - center.getBlockX();
|
||||
public boolean contains(int x, int z) {
|
||||
int cx = x - center.getBlockX();
|
||||
int cx2 = cx * cx;
|
||||
if (cx2 > radiusSqr.getBlockX()) {
|
||||
return false;
|
||||
}
|
||||
int cz = position.getBlockZ() - center.getBlockZ();
|
||||
int cz = z - center.getBlockZ();
|
||||
int cz2 = cz * cz;
|
||||
if (cz2 > radiusSqr.getBlockZ()) {
|
||||
return false;
|
||||
}
|
||||
int cy = position.getBlockY() - center.getBlockY();
|
||||
int cy2 = cy * cy;
|
||||
if (radiusSqr.getBlockY() < 255 && cy2 > radiusSqr.getBlockY()) {
|
||||
return false;
|
||||
}
|
||||
if (sphere) {
|
||||
return cx2 + cy2 + cz2 <= radiusLengthSqr;
|
||||
return cx2 + cz2 <= radiusLengthSqr;
|
||||
}
|
||||
double cxd = (double) cx / radius.getBlockX();
|
||||
double cyd = (double) cy / radius.getBlockY();
|
||||
double czd = (double) cz / radius.getBlockZ();
|
||||
return cxd * cxd + cyd * cyd + czd * czd <= 1;
|
||||
double cxd = cx2 * inverseRadius.getX();
|
||||
double czd = cz2 * inverseRadius.getZ();
|
||||
return cxd + czd <= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,4 +286,113 @@ public class EllipsoidRegion extends AbstractRegion {
|
||||
return (EllipsoidRegion) super.clone();
|
||||
}
|
||||
|
||||
private void filterSpherePartial(int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
|
||||
int sectionStart = y1 >> 4;
|
||||
int sectionEnd = y2 >> 4;
|
||||
|
||||
}
|
||||
|
||||
private void filterSpherePartial(int layer, int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
|
||||
int cx = center.getBlockX();
|
||||
int cy = center.getBlockY();
|
||||
int cz = center.getBlockZ();
|
||||
|
||||
block.init(get, set, layer);
|
||||
|
||||
int by = layer << 4;
|
||||
int diffY;
|
||||
for (int y = y1, yy = by + y1; y <= y2; y++, yy++) {
|
||||
diffY = cy - yy;
|
||||
int remainderY = radiusLengthSqr - (diffY * diffY);
|
||||
if (remainderY >= 0) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = z + bz;
|
||||
int diffZ = cz - zz;
|
||||
int remainderZ = remainderY - (diffZ * diffZ);
|
||||
if (remainderZ >= 0) {
|
||||
int diffX = MathMan.usqrt(remainderZ);
|
||||
int minX = Math.max(0, cx - diffX - bx);
|
||||
int maxX = Math.min(15, cx + diffX - bx);
|
||||
if (minX != maxX) {
|
||||
block.filter(filter, minX, y, z, maxX, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(IChunk chunk, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
|
||||
// Check bounds
|
||||
// This needs to be able to perform 50M blocks/sec otherwise it becomes a bottleneck
|
||||
int cx = center.getBlockX();
|
||||
int cz = center.getBlockZ();
|
||||
int bx = chunk.getX() << 4;
|
||||
int bz = chunk.getZ() << 4;
|
||||
int tx = bx + 15;
|
||||
int tz = bz + 15;
|
||||
int cx1 = bx - cx;
|
||||
int cx2 = tx - cx;
|
||||
int cxMax, cxMin;
|
||||
if (cx1 < cx2) {
|
||||
cxMin = cx1;
|
||||
cxMax = cx2;
|
||||
} else {
|
||||
cxMin = cx2;
|
||||
cxMax = cx1;
|
||||
}
|
||||
int cxMin2 = cxMin * cxMin;
|
||||
int cxMax2 = cxMax * cxMax;
|
||||
int cz1 = bz - cz;
|
||||
int cz2 = tz - cz;
|
||||
int czMax, czMin;
|
||||
if (cz1 < cz2) {
|
||||
czMin = cz1;
|
||||
czMax = cz2;
|
||||
} else {
|
||||
czMin = cz2;
|
||||
czMax = cz1;
|
||||
}
|
||||
int czMin2 = czMin * czMin;
|
||||
int czMax2 = czMax * czMax;
|
||||
|
||||
|
||||
if (sphere) {
|
||||
// Does not contain chunk
|
||||
if (cxMin2 + czMin2 >= radiusLengthSqr) {
|
||||
return;
|
||||
}
|
||||
int diffY2 = radiusLengthSqr - cxMax2 - czMax2;
|
||||
// (shortcut) Contains all of certain layers
|
||||
if (diffY2 >= 0) {
|
||||
// Get the solid layers
|
||||
int cy = center.getBlockY();
|
||||
int diffYFull = MathMan.usqrt(diffY2);
|
||||
int yBotFull = Math.max(0, cy - diffYFull);
|
||||
int yTopFull = Math.min(255, cy + diffYFull);
|
||||
// Set those layers
|
||||
filter(chunk, filter, block, get, set, yBotFull, yTopFull);
|
||||
|
||||
// Fill the remaining layers
|
||||
if (yBotFull != 0 || yTopFull != 255) {
|
||||
int diffYPartial = MathMan.usqrt(radiusLengthSqr - cxMin * cxMin - czMin * czMin);
|
||||
|
||||
if (yBotFull != 0) {
|
||||
int yBotPartial = Math.max(0, cy - diffYPartial);
|
||||
filterSpherePartial(yBotPartial, yBotFull - 1, bx, bz, filter, block, get, set);
|
||||
}
|
||||
|
||||
if (yTopFull != 255) {
|
||||
int yTopPartial = Math.min(255, cy + diffYPartial);
|
||||
filterSpherePartial(yTopFull + 1, yTopPartial - 1, bx, bz, filter, block, get, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
super.filter(chunk, filter, block, get, set); // TODO optimize non spheres
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,17 +20,16 @@
|
||||
package com.sk89q.worldedit.world;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
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.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
@ -69,7 +68,7 @@ public abstract class AbstractWorld implements World {
|
||||
|
||||
@Override
|
||||
public Mask createLiquidMask() {
|
||||
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
|
||||
return new BlockMask(this).add(BlockTypes.LAVA, BlockTypes.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,11 +95,6 @@ public abstract class AbstractWorld implements World {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return getBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean queueBlockBreakEffect(Platform server, BlockVector3 position, BlockType blockType, double priority) {
|
||||
if (taskId == -1) {
|
||||
|
@ -26,9 +26,8 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
@ -41,6 +40,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* An abstract implementation of {@link World}.
|
||||
@ -59,12 +59,16 @@ public interface SimpleWorld extends World {
|
||||
|
||||
@Override
|
||||
default BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position).toBaseBlock();
|
||||
return getBlock(position).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
<B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 pt, B block) throws WorldEditException;
|
||||
|
||||
@Nullable @Override default Path getStoragePath() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getMaxY() {
|
||||
return getMaximumPoint().getBlockY();
|
||||
@ -72,7 +76,7 @@ public interface SimpleWorld extends World {
|
||||
|
||||
@Override
|
||||
default Mask createLiquidMask() {
|
||||
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
|
||||
return new BlockMask(this).add(BlockTypes.LAVA, BlockTypes.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -115,11 +119,6 @@ public interface SimpleWorld extends World {
|
||||
return BlockVector3.at(30000000, 255, 30000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
default @Nullable Operation commit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
|
||||
|
@ -26,6 +26,7 @@ import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.ABlockMask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
@ -47,8 +48,8 @@ import java.util.Objects;
|
||||
*/
|
||||
public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
|
||||
private BlockState blockState;
|
||||
@Nullable protected CompoundTag nbtData;
|
||||
private final BlockState blockState;
|
||||
private final CompoundTag nbtData;
|
||||
|
||||
@Deprecated
|
||||
public BaseBlock() {
|
||||
@ -71,6 +72,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
*/
|
||||
public BaseBlock(BlockState blockState) {
|
||||
this.blockState = blockState;
|
||||
nbtData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +183,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
|
||||
@Override
|
||||
public void setNbtData(@Nullable CompoundTag nbtData) {
|
||||
this.nbtData = nbtData;
|
||||
throw new UnsupportedOperationException("Immutable");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,13 +235,19 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock() {
|
||||
public final char getOrdinalChar() {
|
||||
return blockState.getOrdinalChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BaseBlock toBaseBlock() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
return extent.setBlock(set, this);
|
||||
set.setFullBlock(extent, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -280,7 +288,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return blockState.hashCode(); // stop changing this
|
||||
return getOrdinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -291,5 +299,4 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
return blockState.getAsString();
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,14 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
|
||||
import com.sk89q.worldedit.function.pattern.FawePattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -38,13 +35,16 @@ import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public class BlockType implements FawePattern, Keyed {
|
||||
private final String id;
|
||||
@ -173,10 +173,15 @@ public class BlockType implements FawePattern, Keyed {
|
||||
*
|
||||
* @return The default state
|
||||
*/
|
||||
public BlockState getDefaultState() {
|
||||
public final BlockState getDefaultState() {
|
||||
return this.settings.defaultState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Deprecated use a Mask instead
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public FuzzyBlockState getFuzzyMatcher() {
|
||||
return new FuzzyBlockState(this);
|
||||
}
|
||||
@ -288,7 +293,7 @@ public class BlockType implements FawePattern, Keyed {
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
return extent.setBlock(set, this.getDefaultState());
|
||||
return set.setBlock(extent, getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -296,7 +301,11 @@ public class BlockType implements FawePattern, Keyed {
|
||||
return this.getDefaultState().toBaseBlock();
|
||||
}
|
||||
|
||||
public Mask toMask(Extent extent) {
|
||||
public SingleBlockTypeMask toMask() {
|
||||
return toMask(null);
|
||||
}
|
||||
|
||||
public SingleBlockTypeMask toMask(Extent extent) {
|
||||
return new SingleBlockTypeMask(extent, this);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class ItemTypes {
|
||||
|
||||
@ -914,7 +915,7 @@ public final class ItemTypes {
|
||||
|
||||
@Nullable
|
||||
public static ItemType parse(String input) {
|
||||
input = input.toLowerCase();
|
||||
input = input.toLowerCase(Locale.ROOT);
|
||||
if (!Character.isAlphabetic(input.charAt(0))) {
|
||||
try {
|
||||
ItemType legacy = LegacyMapper.getInstance().getItemFromLegacy(input);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren