Interactive CFI
This commit is contained in:
parent
b4c3e3989c
commit
8ac2bf6da3
@ -104,5 +104,6 @@ subprojects {
|
||||
maven {url "http://ci.frostcast.net/plugin/repository/everything"}
|
||||
maven {url "http://maven.sk89q.com/artifactory/repo"}
|
||||
maven {url "http://repo.spongepowered.org/maven"}
|
||||
maven {url "https://repo.inventivetalent.org/content/groups/public/"}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import com.boydti.fawe.bukkit.regions.Worldguard;
|
||||
import com.boydti.fawe.bukkit.util.BukkitTaskMan;
|
||||
import com.boydti.fawe.bukkit.util.ItemUtil;
|
||||
import com.boydti.fawe.bukkit.util.VaultUtil;
|
||||
import com.boydti.fawe.bukkit.util.image.BukkitImageListener;
|
||||
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener;
|
||||
@ -33,9 +35,11 @@ import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.Jars;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
import com.sk89q.bukkit.util.FallbackRegistrationListener;
|
||||
import com.sk89q.worldedit.bukkit.BukkitPlayerBlockBag;
|
||||
@ -44,6 +48,7 @@ import com.sk89q.worldedit.bukkit.EditSessionBlockChangeDelegate;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -59,6 +64,7 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.primesoft.blockshub.BlocksHubBukkit;
|
||||
|
||||
@ -68,6 +74,8 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
private VaultUtil vault;
|
||||
private WorldEditPlugin worldedit;
|
||||
private ItemUtil itemUtil;
|
||||
private boolean listening;
|
||||
private BukkitImageListener listener;
|
||||
|
||||
public VaultUtil getVault() {
|
||||
return this.vault;
|
||||
@ -130,6 +138,35 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ImageViewer getImageViewer(FawePlayer fp) {
|
||||
if (listening && listener == null) return null;
|
||||
try {
|
||||
listening = true;
|
||||
PluginManager manager = Bukkit.getPluginManager();
|
||||
if (manager.getPlugin("PacketListenerApi") == null) {
|
||||
File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.6.0-SNAPSHOT.jar");
|
||||
byte[] jarData = Jars.PL_v3_6_0.download();
|
||||
try (FileOutputStream fos = new FileOutputStream(output)) {
|
||||
fos.write(jarData);
|
||||
}
|
||||
}
|
||||
if (manager.getPlugin("MapManager") == null) {
|
||||
File output = new File(plugin.getDataFolder().getParentFile(), "MapManager_v1.4.0-SNAPSHOT.jar");
|
||||
byte[] jarData = Jars.MM_v1_4_0.download();
|
||||
try (FileOutputStream fos = new FileOutputStream(output)) {
|
||||
fos.write(jarData);
|
||||
}
|
||||
}
|
||||
BukkitImageViewer viewer = new BukkitImageViewer((Player) fp.parent);
|
||||
if (listener == null) {
|
||||
this.listener = new BukkitImageListener(plugin);
|
||||
}
|
||||
return viewer;
|
||||
} catch (Throwable ignore) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
return plugin.getServer().getOnlinePlayers().size();
|
||||
|
@ -42,7 +42,7 @@ public class BrushBoundBaseBlock extends BaseBlock implements BrushHolder {
|
||||
}
|
||||
|
||||
public BrushBoundBaseBlock(Player player, LocalSession session, ItemStack item) {
|
||||
super(item.getTypeId(), item.getType().getMaxDurability() != 0 ? 0 : Math.max(0, item.getDurability()), getNBT(item));
|
||||
super(item.getTypeId(), item.getType().getMaxDurability() != 0 || item.getDurability() > 15 ? 0 : Math.max(0, item.getDurability()), getNBT(item));
|
||||
this.item = item;
|
||||
this.tool = brushCache.get(getKey(item));
|
||||
this.player = player;
|
||||
|
@ -0,0 +1,31 @@
|
||||
package com.boydti.fawe.bukkit.util.cui;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class CUIListener implements Listener {
|
||||
|
||||
public CUIListener(Plugin plugin) {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
if ((int) from.getX() != (int) to.getX() || (int) from.getZ() != (int) to.getZ()) {
|
||||
FawePlayer<Object> player = FawePlayer.wrap(event.getPlayer());
|
||||
CUI cui = player.getMeta("CUI");
|
||||
if (cui instanceof StructureCUI) {
|
||||
StructureCUI sCui = (StructureCUI) cui;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.boydti.fawe.bukkit.util.cui;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
import com.sk89q.worldedit.internal.cui.SelectionPointEvent;
|
||||
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class StructureCUI extends CUI {
|
||||
private boolean cuboid;
|
||||
private Map<Vector2D, Material> chunkMap = new HashMap<>();
|
||||
|
||||
public StructureCUI(FawePlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCUIEvent(CUIEvent event) {
|
||||
if (event instanceof SelectionShapeEvent) {
|
||||
clear();
|
||||
this.cuboid = event.getParameters()[0].equalsIgnoreCase("cuboid");
|
||||
} else if (cuboid && event instanceof SelectionPointEvent) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(Vector pos1, Vector pos2) {
|
||||
Player player = this.<Player>getPlayer().parent;
|
||||
Location position = player.getLocation();
|
||||
|
||||
int view;
|
||||
if (Bukkit.getVersion().contains("paper")) {
|
||||
view = player.getViewDistance();
|
||||
} else {
|
||||
view = Bukkit.getViewDistance();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,259 @@
|
||||
package com.boydti.fawe.bukkit.util.image;
|
||||
|
||||
import com.boydti.fawe.command.CFICommands;
|
||||
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.BrushSettings;
|
||||
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Rotation;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class BukkitImageListener implements Listener {
|
||||
private Location mutable = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
|
||||
public BukkitImageListener(Plugin plugin) {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onHangingBreakByEntity(HangingBreakByEntityEvent event) {
|
||||
if(!(event.getRemover() instanceof Player)) return;
|
||||
handleInteract(event, (Player) event.getRemover(), event.getEntity(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
|
||||
if(!(event.getDamager() instanceof Player)) return;
|
||||
handleInteract(event, (Player) event.getDamager(), event.getEntity(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (event.useItemInHand() == Event.Result.DENY) return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
if (fp.getMeta("CFISettings") == null) return;
|
||||
try {
|
||||
if (event.getHand() == EquipmentSlot.OFF_HAND) return;
|
||||
} catch (NoSuchFieldError | NoSuchMethodError ignored) {}
|
||||
|
||||
List<Block> target = player.getLastTwoTargetBlocks((Set<Material>) null, 100);
|
||||
if (target.isEmpty()) return;
|
||||
|
||||
Block targetBlock = target.get(0);
|
||||
World world = player.getWorld();
|
||||
mutable.setWorld(world);
|
||||
mutable.setX(targetBlock.getX() + 0.5);
|
||||
mutable.setY(targetBlock.getY() + 0.5);
|
||||
mutable.setZ(targetBlock.getZ() + 0.5);
|
||||
Collection<Entity> entities = world.getNearbyEntities(mutable, 0.46875, 0, 0.46875);
|
||||
|
||||
if (!entities.isEmpty()) {
|
||||
Action action = event.getAction();
|
||||
boolean primary = action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK;
|
||||
|
||||
double minDist = Integer.MAX_VALUE;
|
||||
ItemFrame minItemFrame = null;
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemFrame) {
|
||||
ItemFrame itemFrame = (ItemFrame) entity;
|
||||
Location loc = itemFrame.getLocation();
|
||||
double dx = loc.getX() - mutable.getX();
|
||||
double dy = loc.getY() - mutable.getY();
|
||||
double dz = loc.getZ() - mutable.getZ();
|
||||
double dist = dx * dx + dy * dy + dz * dz;
|
||||
if (dist < minDist) {
|
||||
minItemFrame = itemFrame;
|
||||
minDist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minItemFrame != null) {
|
||||
handleInteract(event, minItemFrame, primary);
|
||||
if (event.isCancelled()) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
handleInteract(event, event.getRightClicked(), true);
|
||||
}
|
||||
|
||||
private BukkitImageViewer get(HeightMapMCAGenerator generator) {
|
||||
if (generator == null) return null;
|
||||
|
||||
ImageViewer viewer = generator.getImageViewer();
|
||||
if (viewer == null || !(viewer instanceof BukkitImageViewer)) return null;
|
||||
|
||||
BukkitImageViewer biv = (BukkitImageViewer) viewer;
|
||||
return biv;
|
||||
}
|
||||
|
||||
private void handleInteract(PlayerEvent event, Entity entity, boolean primary) {
|
||||
handleInteract(event, event.getPlayer(), entity, primary);
|
||||
}
|
||||
|
||||
private void handleInteract(Event event, Player player, Entity entity, boolean primary) {
|
||||
if (!(entity instanceof ItemFrame)) return;
|
||||
ItemFrame itemFrame = (ItemFrame) entity;
|
||||
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
CFICommands.CFISettings settings = fp.getMeta("CFISettings");
|
||||
HeightMapMCAGenerator generator = settings == null ? null : settings.getGenerator();
|
||||
BukkitImageViewer viewer = get(generator);
|
||||
if (viewer == null) return;
|
||||
|
||||
if (itemFrame.getRotation() != Rotation.NONE) {
|
||||
itemFrame.setRotation(Rotation.NONE);
|
||||
}
|
||||
|
||||
LocalSession session = fp.getSession();
|
||||
BrushTool tool;
|
||||
try {
|
||||
tool = session.getBrushTool(fp.getPlayer(), false);
|
||||
} catch (InvalidToolBindException e) { return; }
|
||||
if (tool == null) return;
|
||||
BrushSettings context = primary ? tool.getPrimary() : tool.getSecondary();
|
||||
Brush brush = context.getBrush();
|
||||
|
||||
ItemFrame[][] frames = viewer.getItemFrames();
|
||||
if (frames == null || brush == null) {
|
||||
viewer.selectFrame(itemFrame);
|
||||
TaskManager.IMP.laterAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
viewer.view(generator.draw());
|
||||
}
|
||||
}, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (brush == null) return;
|
||||
tool.setContext(context);
|
||||
|
||||
if (event instanceof Cancellable) {
|
||||
((Cancellable) event).setCancelled(true);
|
||||
}
|
||||
|
||||
Location target = itemFrame.getLocation();
|
||||
Location source = player.getLocation();
|
||||
|
||||
double yawRad = Math.toRadians(source.getYaw() + 90d);
|
||||
double pitchRad = Math.toRadians(-source.getPitch());
|
||||
|
||||
double a = Math.cos(pitchRad);
|
||||
double xRat = Math.cos(yawRad) * a;
|
||||
double zRat = Math.sin(yawRad) * a;
|
||||
|
||||
BlockFace facing = itemFrame.getFacing();
|
||||
double thickness = 1/32d + 1/128d;
|
||||
double modX = facing.getModX();
|
||||
double modZ = facing.getModZ();
|
||||
double dx = source.getX() - target.getX() - modX * thickness;
|
||||
double dy = source.getY() + player.getEyeHeight() - target.getY();
|
||||
double dz = source.getZ() - target.getZ() - modZ * thickness;
|
||||
|
||||
double offset;
|
||||
double localX;
|
||||
if (modX != 0) {
|
||||
offset = dx / xRat;
|
||||
localX = (-modX) * (dz - offset * zRat);
|
||||
} else {
|
||||
offset = dz / zRat;
|
||||
localX = (modZ) * (dx - offset * xRat);
|
||||
}
|
||||
double localY = dy - offset * Math.sin(pitchRad);
|
||||
int localPixelX = (int)((localX + 0.5) * 128);
|
||||
int localPixelY = (int)((localY + 0.5) * 128);
|
||||
|
||||
UUID uuid = itemFrame.getUniqueId();
|
||||
for (int blockX = 0; blockX < frames.length; blockX++) {
|
||||
for (int blockY = 0; blockY < frames[0].length; blockY++) {
|
||||
if (uuid.equals(frames[blockX][blockY].getUniqueId())) {
|
||||
int pixelX = localPixelX + blockX * 128;
|
||||
int pixelY = (128 * frames[0].length) - (localPixelY + blockY * 128 + 1);
|
||||
|
||||
int width = generator.getWidth();
|
||||
int length = generator.getLength();
|
||||
int worldX = (int) (pixelX * width / (frames.length * 128d));
|
||||
int worldZ = (int) (pixelY * length / (frames[0].length * 128d));
|
||||
|
||||
if (worldX < 0 || worldX > width || worldZ < 0 || worldZ > length) return;
|
||||
|
||||
Vector wPos = new Vector(worldX, 0, worldZ);
|
||||
|
||||
fp.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
viewer.refresh();
|
||||
int topY = generator.getNearestSurfaceTerrainBlock(wPos.getBlockX(), wPos.getBlockZ(), 255, 0, 255);
|
||||
wPos.mutY(topY);
|
||||
|
||||
EditSession es = new EditSessionBuilder(fp.getWorld()).player(fp).combineStages(false).autoQueue(false).blockBag(null).limitUnlimited().build();
|
||||
ExtentTraverser last = new ExtentTraverser(es.getExtent()).last();
|
||||
if (last.get() instanceof FastWorldEditExtent) last = last.previous();
|
||||
last.setNext(generator);
|
||||
try {
|
||||
brush.build(es, wPos, context.getMaterial(), context.getSize());
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
es.flushQueue();
|
||||
viewer.view(generator.draw());
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package com.boydti.fawe.bukkit.util.image;
|
||||
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Rotation;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.inventivetalent.mapmanager.MapManagerPlugin;
|
||||
import org.inventivetalent.mapmanager.controller.MapController;
|
||||
import org.inventivetalent.mapmanager.controller.MultiMapController;
|
||||
import org.inventivetalent.mapmanager.manager.MapManager;
|
||||
import org.inventivetalent.mapmanager.wrapper.MapWrapper;
|
||||
|
||||
public class BukkitImageViewer implements ImageViewer {
|
||||
private final MapManager mapManager;
|
||||
private final Player player;
|
||||
private BufferedImage last;
|
||||
private ItemFrame[][] frames;
|
||||
private boolean reverse;
|
||||
|
||||
|
||||
public BukkitImageViewer(Player player) {
|
||||
mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void selectFrame(ItemFrame start) {
|
||||
Location pos1 = start.getLocation().clone();
|
||||
Location pos2 = start.getLocation().clone();
|
||||
|
||||
BlockFace facing = start.getFacing();
|
||||
int planeX = facing.getModX() == 0 ? 1 : 0;
|
||||
int planeY = facing.getModY() == 0 ? 1 : 0;
|
||||
int planeZ = facing.getModZ() == 0 ? 1 : 0;
|
||||
|
||||
ItemFrame[][] res = find(pos1, pos2, facing);
|
||||
Location tmp;
|
||||
while (true) {
|
||||
if (res != null) {
|
||||
frames = res;
|
||||
}
|
||||
tmp = pos1.clone().subtract(planeX, planeY, planeZ);
|
||||
if ((res = find(tmp, pos2, facing)) != null) {
|
||||
pos1 = tmp;
|
||||
continue;
|
||||
}
|
||||
tmp = pos2.clone().add(planeX, planeY, planeZ);
|
||||
if ((res = find(pos1, tmp, facing)) != null) {
|
||||
pos2 = tmp;
|
||||
continue;
|
||||
}
|
||||
tmp = pos1.clone().subtract(planeX, 0, planeZ);
|
||||
if ((res = find(tmp, pos2, facing)) != null) {
|
||||
pos1 = tmp;
|
||||
continue;
|
||||
}
|
||||
tmp = pos2.clone().add(planeX, 0, planeZ);
|
||||
if ((res = find(pos1, tmp, facing)) != null) {
|
||||
pos2 = tmp;
|
||||
continue;
|
||||
}
|
||||
tmp = pos1.clone().subtract(0, 1, 0);
|
||||
if ((res = find(tmp, pos2, facing)) != null) {
|
||||
pos1 = tmp;
|
||||
continue;
|
||||
}
|
||||
tmp = pos2.clone().add(0, 1, 0);
|
||||
if ((res = find(pos1, tmp, facing)) != null) {
|
||||
pos2 = tmp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemFrame[][] getItemFrames() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
private ItemFrame[][] find(Location pos1, Location pos2, BlockFace facing) {
|
||||
try {
|
||||
Location distance = pos2.clone().subtract(pos1).add(1, 1, 1);
|
||||
int width = Math.max(distance.getBlockX(), distance.getBlockZ());
|
||||
ItemFrame[][] frames = new ItemFrame[width][distance.getBlockY()];
|
||||
|
||||
World world = pos1.getWorld();
|
||||
|
||||
this.reverse = (facing == BlockFace.NORTH || facing == BlockFace.EAST);
|
||||
int v = 0;
|
||||
for (double y = pos1.getY(); y <= pos2.getY(); y++, v++) {
|
||||
int h = 0;
|
||||
for (double z = pos1.getZ(); z <= pos2.getZ(); z++) {
|
||||
for (double x = pos1.getX(); x <= pos2.getX(); x++, h++) {
|
||||
Location pos = new Location(world, x, y, z);
|
||||
Collection<Entity> entities = world.getNearbyEntities(pos, 0.1, 0.1, 0.1);
|
||||
boolean contains = false;
|
||||
for (Entity ent : entities) {
|
||||
if (ent instanceof ItemFrame && ((ItemFrame) ent).getFacing() == facing) {
|
||||
ItemFrame itemFrame = (ItemFrame) ent;
|
||||
itemFrame.setRotation(Rotation.NONE);
|
||||
contains = true;
|
||||
frames[reverse ? width - 1 - h : h][v] = (ItemFrame) ent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!contains) return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return frames;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void view(BufferedImage image) {
|
||||
last = image;
|
||||
if (this.frames != null) {
|
||||
int width = frames.length;
|
||||
int height = frames[0].length;
|
||||
BufferedImage scaled = ImageUtil.getScaledInstance(image, 128 * width, 128 * height, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||
MapWrapper mapWrapper = mapManager.wrapMultiImage(scaled, width, height);
|
||||
MultiMapController controller = (MultiMapController) mapWrapper.getController();
|
||||
controller.addViewer(player);
|
||||
controller.sendContent(player);
|
||||
controller.showInFrames(player, frames, true);
|
||||
} else {
|
||||
BufferedImage scaled = ImageUtil.getScaledInstance(image, 128, 128, RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||
MapWrapper mapWrapper = mapManager.wrapImage(scaled);
|
||||
MapController controller = mapWrapper.getController();
|
||||
controller.addViewer(player);
|
||||
controller.sendContent(player);
|
||||
controller.showInHand(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
if (last != null) view(last);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
last = null;
|
||||
}
|
||||
}
|
@ -131,6 +131,14 @@ public class AsyncBlockState implements BlockState {
|
||||
return result;
|
||||
}
|
||||
|
||||
public CompoundTag getNbtData() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public void setNbtData(CompoundTag nbt) {
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getRawData() {
|
||||
return data;
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.boydti.fawe.bukkit.wrapper.state;
|
||||
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlockState;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.util.Map;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
public class AsyncSign extends AsyncBlockState implements Sign {
|
||||
public AsyncSign(AsyncBlock block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getLines() {
|
||||
CompoundTag nbt = getNbtData();
|
||||
String[] data = new String[4];
|
||||
if (nbt != null) {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
data[i - 1] = nbt.getString("Text" + i);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLine(int index) throws IndexOutOfBoundsException {
|
||||
CompoundTag nbt = getNbtData();
|
||||
return nbt == null ? null : nbt.getString("Text" + (index + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(int index, String line) throws IndexOutOfBoundsException {
|
||||
CompoundTag nbt = getNbtData();
|
||||
if (nbt != null) {
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nbt.getValue());
|
||||
map.put("Text" + (index + 1), new StringTag(line));
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ dependencies {
|
||||
compile(group: 'com.sk89q.worldedit', name: 'worldedit-core', version:'6.1.3-SNAPSHOT') {
|
||||
exclude(module: 'bukkit-classloader-check')
|
||||
}
|
||||
compile 'org.inventivetalent:mapmanager:1.4.0-SNAPSHOT'
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@ -19,6 +19,7 @@ import com.boydti.fawe.util.Updater;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.boydti.fawe.util.chat.ChatManager;
|
||||
import com.boydti.fawe.util.chat.PlainChatManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
@ -68,6 +69,7 @@ import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.extension.platform.PlayerProxy;
|
||||
@ -355,6 +357,25 @@ public class Fawe {
|
||||
return false;
|
||||
}
|
||||
|
||||
public CUI getCUI(Actor actor) {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(actor);
|
||||
CUI cui = fp.getMeta("CUI");
|
||||
if (cui == null) {
|
||||
cui = Fawe.imp().getCUI(fp);
|
||||
if (cui != null) {
|
||||
synchronized (fp) {
|
||||
CUI tmp = fp.getMeta("CUI");
|
||||
if (tmp == null) {
|
||||
fp.setMeta("CUI", cui);
|
||||
} else {
|
||||
cui = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cui;
|
||||
}
|
||||
|
||||
public ChatManager getChatManager() {
|
||||
return chatManager;
|
||||
}
|
||||
|
@ -812,6 +812,8 @@ public class FaweCache {
|
||||
return asTag((int[]) value);
|
||||
} else if (value instanceof Tag) {
|
||||
return (Tag) value;
|
||||
} else if (value instanceof Boolean) {
|
||||
return asTag((byte) ((boolean) value ? 1 : 0));
|
||||
} else if (value == null) {
|
||||
System.out.println("Invalid nbt: " + value);
|
||||
return null;
|
||||
|
@ -5,6 +5,8 @@ import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
@ -33,6 +35,9 @@ public interface IFawe {
|
||||
|
||||
public void startMetrics();
|
||||
|
||||
default CUI getCUI(FawePlayer player) { return null; }
|
||||
|
||||
default ImageViewer getImageViewer(FawePlayer player) { return null; }
|
||||
|
||||
default int getPlayerCount() {
|
||||
return Fawe.get().getCachedPlayers().size();
|
||||
@ -42,7 +47,6 @@ public interface IFawe {
|
||||
|
||||
public boolean isOnlineMode();
|
||||
|
||||
|
||||
public String getPlatform();
|
||||
|
||||
public UUID getUUID(String name);
|
||||
|
83
core/src/main/java/com/boydti/fawe/command/CFICommand.java
Normal file
83
core/src/main/java/com/boydti/fawe/command/CFICommand.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
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;
|
||||
|
||||
public class CFICommand extends MethodCommands {
|
||||
|
||||
private final CFICommands child;
|
||||
private final SimpleDispatcher dispatcher;
|
||||
|
||||
public CFICommand(WorldEdit worldEdit, ParametricBuilder builder) {
|
||||
super(worldEdit);
|
||||
this.child = new CFICommands(worldEdit);
|
||||
this.dispatcher = new SimpleDispatcher();
|
||||
builder.registerMethodsAsCommands(dispatcher, child);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"cfi", "createfromimage"},
|
||||
usage = "",
|
||||
min = 0,
|
||||
max = -1,
|
||||
anyFlags = true,
|
||||
desc = "Start CreateFromImage"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void cfi(FawePlayer fp, CommandContext context) throws CommandException {
|
||||
CFICommands.CFISettings settings = child.getSettings(fp);
|
||||
if (!settings.hasGenerator()) {
|
||||
switch (context.argsLength()) {
|
||||
case 0: {
|
||||
String hmCmd = child.alias() + " ";
|
||||
if (settings.image == null) {
|
||||
hmCmd += "image";
|
||||
} else {
|
||||
hmCmd = Commands.getAlias(CFICommands.class, "heightmap") + " " + settings.imageArg;
|
||||
}
|
||||
child.msg("What do you want to use as the base?").newline()
|
||||
.text("&7[&aHeightMap&7]").cmdTip(hmCmd).text(" - A heightmap like ").text("&7[&athis&7]").linkTip("http://i.imgur.com/qCd30MR.jpg")
|
||||
.newline()
|
||||
.text("&7[&aEmpty&7]").cmdTip(child.alias() + " empty").text("- An empty map of a specific size")
|
||||
.send(fp);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
String remaining = context.getJoinedStrings(0);
|
||||
if (!dispatcher.contains(context.getString(0))) {
|
||||
switch (context.argsLength()) {
|
||||
case 1: {
|
||||
String cmd = Commands.getAlias(CFICommands.class, "heightmap") + " " + context.getJoinedStrings(0);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (context.argsLength()) {
|
||||
case 0:
|
||||
child.mainMenu(fp);
|
||||
break;
|
||||
default:
|
||||
dispatcher.call(context.getJoinedStrings(0), context.getLocals(), new String[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
843
core/src/main/java/com/boydti/fawe/command/CFICommands.java
Normal file
843
core/src/main/java/com/boydti/fawe/command/CFICommands.java
Normal file
@ -0,0 +1,843 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FilteredTextureUtil;
|
||||
import com.boydti.fawe.util.ImgurUtility;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.commands.Auto;
|
||||
import com.intellectualcrafters.plot.config.C;
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotId;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.object.worlds.PlotAreaManager;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotArea;
|
||||
import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.MethodCommands;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@Command(aliases = {"/cfi"}, desc = "Create a world from images: [More Info](https://git.io/v5iDy)")
|
||||
public class CFICommands extends MethodCommands {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param worldEdit reference to WorldEdit
|
||||
*/
|
||||
public CFICommands(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"heightmap"},
|
||||
usage = "<url>",
|
||||
desc = "Start CFI with a height map as a base"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void heightmap(FawePlayer fp, BufferedImage image) {
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(image, null);
|
||||
setup(generator, fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"empty"},
|
||||
usage = "<width> <length>",
|
||||
desc = "Start CFI with an empty map as a base"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void heightmap(FawePlayer fp, int width, int length) {
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(width, length, null);
|
||||
setup(generator, fp);
|
||||
}
|
||||
|
||||
private void setup(HeightMapMCAGenerator generator, FawePlayer fp) {
|
||||
CFISettings settings = getSettings(fp);
|
||||
settings.remove().setGenerator(generator).bind();
|
||||
generator.setImageViewer(Fawe.imp().getImageViewer(fp));
|
||||
mainMenu(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"brush"},
|
||||
usage = "",
|
||||
desc = "Info about using brushes with CFI"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void brush(FawePlayer fp) throws ParameterException{
|
||||
CFISettings settings = assertSettings(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();
|
||||
} else {
|
||||
msg = msg("This is not supported with your platform/version").newline();
|
||||
}
|
||||
msg.text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"cancel", "exit"},
|
||||
usage = "",
|
||||
desc = "Cancel creation"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void cancel(FawePlayer fp) throws ParameterException, IOException {
|
||||
getSettings(fp).remove();
|
||||
fp.sendMessage(BBC.getPrefix() + "Cancelled!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"done", "create"},
|
||||
usage = "",
|
||||
desc = "Create the world"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void done(FawePlayer fp) throws ParameterException, IOException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
|
||||
PlotAreaManager manager = PS.get().getPlotAreaManager();
|
||||
if (manager instanceof SinglePlotAreaManager) {
|
||||
SinglePlotAreaManager sManager = (SinglePlotAreaManager) manager;
|
||||
SinglePlotArea area = sManager.getArea();
|
||||
PlotPlayer player = PlotPlayer.wrap(fp.parent);
|
||||
|
||||
fp.sendMessage(BBC.getPrefix() + "Claiming world");
|
||||
Plot plot = TaskManager.IMP.sync(new RunnableVal<Plot>() {
|
||||
@Override
|
||||
public void run(Plot o) {
|
||||
int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(area.worldname);
|
||||
int diff = player.getAllowedPlots() - currentPlots;
|
||||
if (diff < 1) {
|
||||
C.CANT_CLAIM_MORE_PLOTS_NUM.send(player, -diff);
|
||||
return;
|
||||
}
|
||||
if (area.getMeta("lastPlot") == null) {
|
||||
area.setMeta("lastPlot", new PlotId(0, 0));
|
||||
}
|
||||
PlotId lastId = (PlotId) area.getMeta("lastPlot");
|
||||
while (true) {
|
||||
lastId = Auto.getNextPlotId(lastId, 1);
|
||||
if (area.canClaim(player, lastId, lastId)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
area.setMeta("lastPlot", lastId);
|
||||
this.value = area.getPlot(lastId);
|
||||
this.value.setOwner(player.getUUID());
|
||||
}
|
||||
});
|
||||
if (plot == null) return;
|
||||
|
||||
File folder = new File(PS.imp().getWorldContainer(), plot.getWorldName() + File.separator + "region");
|
||||
HeightMapMCAGenerator generator = settings.getGenerator();
|
||||
generator.setFolder(folder);
|
||||
|
||||
fp.sendMessage(BBC.getPrefix() + "Generating");
|
||||
generator.generate();
|
||||
settings.remove();
|
||||
fp.sendMessage(BBC.getPrefix() + "Done!");
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
plot.teleportPlayer(player);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fp.sendMessage(BBC.getPrefix() + "Must have the `worlds` component enabled in the PlotSquared config.yml");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"column", "setcolumn"},
|
||||
usage = "<pattern> [url|mask]",
|
||||
desc = "Set the floor and main block"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void column(FawePlayer fp, Pattern pattern, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setColumn(image, pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setColumn(mask, pattern);
|
||||
else gen.setColumn(pattern);
|
||||
fp.sendMessage("Set column!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"floor", "setfloor"},
|
||||
usage = "<pattern> [url|mask]",
|
||||
desc = "Set the floor (default: grass)"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void floor(FawePlayer fp, Pattern pattern, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setFloor(image, pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setFloor(mask, pattern);
|
||||
else gen.setFloor(pattern);
|
||||
fp.sendMessage("Set floor!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"main", "setmain"},
|
||||
usage = "<pattern> [url|mask]",
|
||||
desc = "Set the main block (default: stone)"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void main(FawePlayer fp, Pattern pattern, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setMain(image, pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setMain(mask, pattern);
|
||||
else gen.setMain(pattern);
|
||||
fp.sendMessage("Set main!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"overlay", "setoverlay"},
|
||||
usage = "<pattern> [url|mask]",
|
||||
desc = "Set the overlay block",
|
||||
help = "Change the block directly above the floor (default: air)\n" +
|
||||
"e.g. Tallgrass"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void overlay(FawePlayer fp, Pattern pattern, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setOverlay(image, pattern, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setOverlay(mask, pattern);
|
||||
else gen.setOverlay(pattern);
|
||||
fp.sendMessage("Set overlay!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"smooth"},
|
||||
usage = "<radius> <iterations> [image|mask]",
|
||||
desc = "Smooth the terrain",
|
||||
help = "Smooth terrain within an image-mask, or worldedit mask\n" +
|
||||
" - You can use !0 as the mask to smooth everything\n" +
|
||||
" - This supports smoothing snow layers (set the floor to 78:7)\n" +
|
||||
" - A good value for radius and iterations would be 1 8."
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void smooth(FawePlayer fp, int radius, int iterations, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.smooth(image, !disableWhiteOnly, radius, iterations);
|
||||
else gen.smooth(mask, radius, iterations);
|
||||
fp.sendMessage("Performed smooth!");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"snow"},
|
||||
usage = "[image|mask]",
|
||||
desc = "Create some snow"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void snow(FawePlayer fp, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
floor(fp, FaweCache.getBlock(78, 7), image, mask, disableWhiteOnly);
|
||||
smooth(fp, 1, 8, image, mask, disableWhiteOnly);
|
||||
msg("Added snow!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"biomepriority", "palettebiomepriority", "setpalettebiomepriority"},
|
||||
usage = "[percent=50]",
|
||||
desc = "Set the biome priority",
|
||||
help = "Increase or decrease biome priority when using blockBiomeColor.\n" +
|
||||
"A value of 50 is the default\n" +
|
||||
"Above 50 will prefer to color with biomes\n" +
|
||||
"Below 50 will prefer to color with blocks"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void biomepriority(FawePlayer fp, int value) throws ParameterException{
|
||||
assertSettings(fp).getGenerator().setBiomePriority(value);
|
||||
coloring(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"paletteblocks", "colorpaletterblocks", "setcolorpaletteblocks"},
|
||||
usage = "<blocks|#clipboard|*>",
|
||||
desc = "Set the blocks used for coloring",
|
||||
help = "Allow only specific blocks to be used for coloring\n" +
|
||||
"`blocks` is a list of blocks e.g. stone,bedrock,wool\n" +
|
||||
"`#clipboard` will only use the blocks present in your clipboard."
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void paletteblocks(FawePlayer fp, @Optional String arg) throws ParameterException, EmptyClipboardException, InputParseException, FileNotFoundException {
|
||||
if (arg == null) {
|
||||
msg("What blocks do you want to color with?").newline()
|
||||
.text("&7[&aAll&7]").cmdTip(alias() + " PaletteBlocks *").text(" - All available blocks")
|
||||
.newline()
|
||||
.text("&7[&aClipboard&7]").cmdTip(alias() + " PaletteBlocks #clipboard").text(" - The blocks in your clipboard")
|
||||
.newline()
|
||||
.text("&7[&aList&7]").suggestTip(alias() + " PaletteBlocks stone,gravel").text(" - A comma separated list of blocks")
|
||||
.newline()
|
||||
.text("&7[&aComplexity&7]").cmdTip(alias() + " Complexity").text(" - Block textures within a complexity range")
|
||||
.newline()
|
||||
.text("&8< &7[&aBack&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "coloring"))
|
||||
.send(fp);
|
||||
return;
|
||||
}
|
||||
HeightMapMCAGenerator generator = assertSettings(fp).getGenerator();
|
||||
ParserContext context = new ParserContext();
|
||||
context.setActor(fp.getPlayer());
|
||||
context.setWorld(fp.getWorld());
|
||||
context.setSession(fp.getSession());
|
||||
context.setExtent(generator);
|
||||
Request.request().setExtent(generator);
|
||||
|
||||
Set<BaseBlock> blocks;
|
||||
switch (arg.toLowerCase()) {
|
||||
case "*": {
|
||||
generator.setTextureUtil(Fawe.get().getTextureUtil());
|
||||
return;
|
||||
}
|
||||
case "#clipboard": {
|
||||
ClipboardHolder holder = fp.getSession().getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
boolean[] ids = new boolean[Character.MAX_VALUE + 1];
|
||||
for (Vector pt : clipboard.getRegion()) {
|
||||
ids[clipboard.getBlock(pt).getCombined()] = true;
|
||||
}
|
||||
blocks = new HashSet<>();
|
||||
for (int combined = 0; combined < ids.length; combined++) {
|
||||
if (ids[combined]) blocks.add(FaweCache.CACHE_BLOCK[combined]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
blocks = worldEdit.getBlockFactory().parseFromListInput(arg, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
generator.setTextureUtil(new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks));
|
||||
coloring(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"randomization", "paletterandomization"},
|
||||
usage = "<true|false>",
|
||||
desc = "Set whether randomization is enabled",
|
||||
help = "This is enabled by default, randomization will add some random variation in the blocks used to closer match the provided image.\n" +
|
||||
"If disabled, the closest block to the color will always be used.\n" +
|
||||
"Randomization will allow mixing biomes when coloring with biomes"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void randomization(FawePlayer fp, boolean enabled) throws ParameterException {
|
||||
assertSettings(fp).getGenerator().setTextureRandomVariation(enabled);
|
||||
coloring(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"complexity", "palettecomplexity"},
|
||||
usage = "<minPercent> <maxPercent>",
|
||||
desc = "Set the complexity for coloring",
|
||||
help = "Set the complexity for coloring\n" +
|
||||
"Filter out blocks to use based on their complexity, which is a measurement of how much color variation there is in the texture for that block.\n" +
|
||||
"Glazed terracotta is complex, and not very pleasant for terrain, whereas stone and wool are simpler textures.\n" +
|
||||
"Using 0 73 for the min/max would use the simplest 73% of blocks for coloring, and is a reasonable value."
|
||||
)
|
||||
@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));
|
||||
coloring(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"schem", "schematic", "schems", "schematics", "addschems"},
|
||||
usage = "[url] <mask> <file|folder|url> <rarity> <distance> <rotate=true>",
|
||||
desc = "Populate schematics",
|
||||
help = "Populate a schematic on the terrain\n" +
|
||||
" - Change the mask (e.g. angle mask) to only place the schematic in specific locations.\n" +
|
||||
" - The rarity is a value between 0 and 100.\n" +
|
||||
" - The distance is the spacing between each schematic"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void schem(FawePlayer fp, @Optional BufferedImage imageMask, Mask mask, String schematic, int rarity, int distance, boolean rotate) throws ParameterException, IOException, WorldEditException {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
|
||||
World world = fp.getWorld();
|
||||
WorldData wd = world.getWorldData();
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), wd, schematic, true);
|
||||
if (clipboards == null) {
|
||||
return;
|
||||
}
|
||||
if (imageMask == null) {
|
||||
gen.addSchems(mask, wd, clipboards, rarity, distance, rotate);
|
||||
} else {
|
||||
gen.addSchems(imageMask, mask, wd, clipboards, rarity, distance, rotate);
|
||||
}
|
||||
msg("Added schematics!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"biome", "setbiome"},
|
||||
usage = "<biome> [image|mask]",
|
||||
desc = "Set the biome",
|
||||
help = "Set the biome in specific parts of the map.\n" +
|
||||
" - If an image is used, the biome will have a chance to be set based on how white the pixel is (white #FFF = 100% chance)" +
|
||||
" - The whiteOnly parameter determines if only white values on the image are set" +
|
||||
" - If a mask is used, the biome will be set anywhere the mask applies"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void biome(FawePlayer fp, BaseBiome biome, @Optional BufferedImage image, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException{
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (image != null) gen.setBiome(image, (byte) biome.getId(), !disableWhiteOnly);
|
||||
else if (mask != null) gen.setBiome(mask, (byte) biome.getId());
|
||||
else gen.setBiome((byte) biome.getId());
|
||||
msg("Set biome!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"caves", "addcaves"},
|
||||
desc = "Generate vanilla caves"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void caves(FawePlayer fp) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().addCaves();
|
||||
msg("Added caves!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"ore", "addore"},
|
||||
usage = "<mask=stone> <pattern> <size> <frequency> <rarity> <minY> <maxY>",
|
||||
desc = "Add an ore",
|
||||
help = "Use a specific pattern and settings to generate ore"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void ore(FawePlayer fp, Mask mask, Pattern pattern, int size, int frequency, int rariry, int minY, int maxY) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().addOre(mask, pattern, size, frequency, rariry, minY, maxY);
|
||||
msg("Added ore!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"ores", "addores"},
|
||||
usage = "<mask=stone>",
|
||||
desc = "Generate the vanilla ores"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void ores(FawePlayer fp, Mask mask) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().addDefaultOres(mask);
|
||||
msg("Added ores!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"height", "setheight"},
|
||||
usage = "<height|image>",
|
||||
desc = "Set the height",
|
||||
help = "Set the terrain height either based on an image heightmap, or a numeric value."
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void height(FawePlayer fp, String arg) throws ParameterException, WorldEditException {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (!MathMan.isInteger(arg)) {
|
||||
gen.setHeight(ImageUtil.getImage(arg));
|
||||
} else {
|
||||
gen.setHeights(Integer.parseInt(arg));
|
||||
}
|
||||
msg("Set height!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"water", "waterid"},
|
||||
usage = "<block>",
|
||||
desc = "Change the block used for water\n" +
|
||||
"e.g. Lava"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void waterId(FawePlayer fp, BaseBlock block) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setWaterId(block.getId());
|
||||
msg("Set water id!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"waterheight", "sealevel", "setwaterheight"},
|
||||
usage = "<height>",
|
||||
desc = "Set the level water is generated at\n" +
|
||||
"Set the level water is generated at\n" +
|
||||
" - By default water is disabled (with a value of 0)"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void height(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setWaterHeight(height);
|
||||
msg("Set height!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"glass", "glasscolor", "setglasscolor"},
|
||||
usage = "<url>",
|
||||
desc = "Color terrain using glass"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void glass(FawePlayer fp, BufferedImage image, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setColorWithGlass(image);
|
||||
msg("Set color with glass!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"color", "setcolor", "blockcolor", "blocks"},
|
||||
usage = "<url> [imageMask|mask]",
|
||||
desc = "Set the color with blocks and biomes",
|
||||
help = "Color the terrain using only blocks\n" +
|
||||
"Provide an image, or worldedit mask for the 2nd argument to restrict what areas are colored\n" +
|
||||
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void color(FawePlayer fp, BufferedImage image, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
if (imageMask != null) gen.setColor(image, imageMask, !disableWhiteOnly);
|
||||
else if (mask != null) gen.setColor(image, mask);
|
||||
else gen.setColor(image);
|
||||
msg("Set color with blocks!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"blockbiomecolor", "setblockandbiomecolor", "blockandbiome"},
|
||||
usage = "<url> [imageMask|mask]",
|
||||
desc = "Set the color with blocks and biomes",
|
||||
help = "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"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void blockbiome(FawePlayer fp, BufferedImage image, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setBlockAndBiomeColor(image, mask, imageMask, !disableWhiteOnly);
|
||||
msg("Set color with blocks and biomes!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"biomecolor", "setbiomecolor", "biomes"},
|
||||
usage = "<url> [imageMask|mask]",
|
||||
desc = "Color the terrain using biomes.\n" +
|
||||
"Note: Biome coloring does not change blocks:\n" +
|
||||
" - If you changed the block to something other than grass you will not see anything."
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void biomecolor(FawePlayer fp, BufferedImage image, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setBiomeColor(image);
|
||||
msg("Set color with biomes!").newline().text("&8> &7[&aNext&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = {"coloring", "palette"},
|
||||
usage = "",
|
||||
desc = "Color the world using an image"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void coloring(FawePlayer fp) throws ParameterException{
|
||||
CFISettings settings = assertSettings(fp);
|
||||
HeightMapMCAGenerator gen = settings.getGenerator();
|
||||
boolean rand = gen.getTextureRandomVariation();
|
||||
String mask;
|
||||
if (settings.imageMask != null) {
|
||||
mask = "Mask Image";
|
||||
} else if (settings.mask != null) {
|
||||
mask = "WorldEdit Mask";
|
||||
} else {
|
||||
mask = "NONE";
|
||||
}
|
||||
TextureUtil tu = gen.getRawTextureUtil();
|
||||
String blocks;
|
||||
if (tu.getClass() == TextureUtil.class) {
|
||||
blocks = "All";
|
||||
} else if (tu.getClass() == CleanTextureUtil.class) {
|
||||
CleanTextureUtil clean = (CleanTextureUtil) tu;
|
||||
blocks = "Complexity(" + clean.getMin() + "," + clean.getMax() + ")";
|
||||
} else if (tu.getClass() == FilteredTextureUtil.class) {
|
||||
blocks = "Selected";
|
||||
} else {
|
||||
blocks = "Undefined";
|
||||
}
|
||||
|
||||
Set<String> materials = new HashSet<>();
|
||||
char[] blockArray = tu.getValidBlockIds();
|
||||
for (char combined : blockArray) {
|
||||
int id = FaweCache.getId(combined);
|
||||
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(id);
|
||||
if (block != null) {
|
||||
if (block.id.contains(":"))
|
||||
materials.add(block.id.contains(":") ? block.id.substring(block.id.indexOf(":") + 1) : block.id);
|
||||
} else materials.add(Integer.toString(id));
|
||||
}
|
||||
String blockList = materials.size() > 100 ? materials.size() + " blocks" : StringMan.join(materials, ',');
|
||||
|
||||
int biomePriority = gen.getBiomePriority();
|
||||
|
||||
Message msg = msg("Current settings:").newline()
|
||||
.text("Randomization ").text("&7[&a" + (Boolean.toString(rand).toUpperCase()) + "&7]").cmdTip(alias() + " randomization " + (!rand))
|
||||
.newline()
|
||||
.text("Mask ").text("&7[&a" + mask + "&7]").cmdTip(alias() + " mask")
|
||||
.newline()
|
||||
.text("Blocks ").text("&7[&a" + blocks + "&7]").tooltip(blockList).command(alias() + " paletteBlocks")
|
||||
.newline()
|
||||
.text("BiomePriority ").text("&7[&a" + biomePriority + "&7]").cmdTip(alias() + " biomepriority")
|
||||
.newline();
|
||||
|
||||
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");
|
||||
|
||||
msg.text("Image: ")
|
||||
.text("&7[&a" + settings.imageArg + "&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "image"))
|
||||
.newline().newline()
|
||||
.text("Let's Color: ")
|
||||
.cmdOptions(alias() + " ", colorArgs.toString(), "Biomes", "Blocks", "BlockAndBiome", "Glass")
|
||||
.newline();
|
||||
} else {
|
||||
msg.newline().text("You can color a world using an image like ")
|
||||
.text("&7[&aThis&7]").linkTip("http://i.imgur.com/vJYinIU.jpg").newline()
|
||||
.text("Please provide an image: ")
|
||||
.text("&7[&aNone&7]").cmdTip(alias() + " " + Commands.getAlias(Command.class, "image")).newline();
|
||||
}
|
||||
msg.text("&8< &7[&aBack&7]").cmdTip(alias()).send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"mask"},
|
||||
usage = "<imageMask|mask>",
|
||||
desc = "Select a mask"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void mask(FawePlayer fp, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly, CommandContext context) throws ParameterException{
|
||||
CFISettings settings = assertSettings(fp);
|
||||
String[] split = getArguments(context).split(" ");
|
||||
int index = 2;
|
||||
settings.imageMask = imageMask;
|
||||
settings.imageMaskArg = imageMask != null ? split[index++] : null;
|
||||
settings.mask = mask;
|
||||
settings.maskArg = mask != null ? split[index++] : null;
|
||||
settings.whiteOnly = disableWhiteOnly;
|
||||
|
||||
StringBuilder cmd = new StringBuilder(alias() + " mask ");
|
||||
if (!settings.whiteOnly) cmd.append("-w ");
|
||||
|
||||
msg("Current settings:").newline()
|
||||
.text("Image Mask ").text("&7[&a" + settings.imageMaskArg + "&7]").suggestTip(cmd + "http://")
|
||||
.newline()
|
||||
.text("WorldEdit Mask ").text("&7[&a" + settings.maskArg + "&7]").suggestTip(cmd + "<mask>")
|
||||
.send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"download"},
|
||||
desc = "Download the current image"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void download(FawePlayer fp) throws ParameterException, IOException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
BufferedImage image = settings.getGenerator().draw();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "jpg", baos );
|
||||
byte[] data = baos.toByteArray();
|
||||
fp.sendMessage(BBC.getPrefix() + "Please wait...");
|
||||
URL url = ImgurUtility.uploadImage(data);
|
||||
BBC.DOWNLOAD_LINK.send(fp, url);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"image"},
|
||||
usage = "<image>",
|
||||
desc = "Select an image"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void image(FawePlayer fp, @Optional BufferedImage image, CommandContext context) throws ParameterException{
|
||||
CFISettings settings = getSettings(fp).bind();
|
||||
String[] split = getArguments(context).split(" ");
|
||||
int index = 2;
|
||||
|
||||
settings.image = image;
|
||||
settings.imageArg = image != null ? split[index++] : null;
|
||||
String maskArg = settings.maskArg == null ? "Click Here" : settings.maskArg;
|
||||
|
||||
StringBuilder cmd = new StringBuilder(alias() + " image ");
|
||||
Message msg;
|
||||
if (image == null) {
|
||||
msg = msg("Please provide an image:").newline()
|
||||
.text("From a URL: ").text("&7[&aClick Here&7]").suggestTip(cmd + "http://")
|
||||
.newline()
|
||||
.text("From a file: ").text("&7[&aClick Here&7]").suggestTip(cmd + "file://");
|
||||
} else {
|
||||
msg = msg("Current image: ")
|
||||
.text("&7[&a" + settings.imageArg + "&7]").suggestTip(cmd.toString())
|
||||
.newline();
|
||||
if (settings.hasGenerator()) {
|
||||
msg.text("&8< &7[&aBack&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "coloring"));
|
||||
} else {
|
||||
msg.text("&8> &7[&aNext&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "heightmap " + settings.imageArg));
|
||||
}
|
||||
}
|
||||
msg.send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"populate"},
|
||||
usage = "",
|
||||
desc = ""
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void populate(FawePlayer fp) throws ParameterException{
|
||||
CFISettings settings = assertSettings(fp);
|
||||
|
||||
msg("What would you like to populate?").newline()
|
||||
.cmdOptions(alias() + " ", "", "Ores", "Ore", "Caves", "Schematics", "Snow")
|
||||
.newline().text("&8< &7[&aBack&7]").cmdTip(alias())
|
||||
.send(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"component", "components"},
|
||||
usage = "",
|
||||
desc = "Components menu"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void component(FawePlayer fp) throws ParameterException{
|
||||
CFISettings settings = assertSettings(fp);
|
||||
msg("What component would you like to change?").newline()
|
||||
.cmdOptions(alias() + " ", "", "WaterId", "WaterHeight", "Floor", "Main", "Column", "Overlay", "Height", "Smooth")
|
||||
.newline().text("&8< &7[&aBack&7]").cmdTip(alias())
|
||||
.send(fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private CFISettings assertSettings(FawePlayer fp) throws ParameterException {
|
||||
CFISettings settings = getSettings(fp);
|
||||
if (!settings.hasGenerator()) throw new ParameterException("Please use /" + alias());
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
protected CFISettings getSettings(FawePlayer fp) {
|
||||
CFISettings settings = fp.getMeta("CFISettings");
|
||||
return settings == null ? new CFISettings(fp) : settings;
|
||||
}
|
||||
|
||||
public static class CFISettings {
|
||||
private final FawePlayer fp;
|
||||
|
||||
private HeightMapMCAGenerator generator;
|
||||
|
||||
protected BufferedImage image;
|
||||
protected String imageArg;
|
||||
protected Mask mask;
|
||||
protected BufferedImage imageMask;
|
||||
protected boolean whiteOnly = true;
|
||||
protected String maskArg;
|
||||
protected String imageMaskArg;
|
||||
|
||||
public CFISettings(FawePlayer player) {
|
||||
this.fp = player;
|
||||
}
|
||||
|
||||
public boolean hasGenerator() {
|
||||
return generator != null;
|
||||
}
|
||||
|
||||
public HeightMapMCAGenerator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
public void setMask(Mask mask, String arg) {
|
||||
this.mask = mask;
|
||||
this.maskArg = arg;
|
||||
}
|
||||
|
||||
public void setImage(BufferedImage image, String arg) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public void setImageMask(BufferedImage imageMask, String arg) {
|
||||
this.imageMask = imageMask;
|
||||
this.imageMaskArg = arg;
|
||||
}
|
||||
|
||||
public CFISettings setGenerator(HeightMapMCAGenerator generator) {
|
||||
this.generator = generator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CFISettings bind() {
|
||||
fp.setMeta("CFISettings", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CFISettings remove() {
|
||||
fp.deleteMeta("CFISettings");
|
||||
generator = null;
|
||||
image = null;
|
||||
imageArg = null;
|
||||
mask = null;
|
||||
imageMask = null;
|
||||
whiteOnly = true;
|
||||
maskArg = null;
|
||||
imageMaskArg = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
protected String alias() {
|
||||
return Commands.getAlias(CFICommand.class, "/cfi");
|
||||
}
|
||||
|
||||
protected Message msg(String text) {
|
||||
return new Message(BBC.getPrefix())
|
||||
.text(text);
|
||||
}
|
||||
|
||||
protected void mainMenu(FawePlayer fp) {
|
||||
msg("What do you want to do now?").newline()
|
||||
.cmdOptions(alias() + " ", "", "Coloring", "Populate", "Component", "Brush")
|
||||
.newline().text("&3<> &7[&aView&7]").command(alias() + " " + Commands.getAlias(CFICommands.class, "download")).tooltip("View full resolution image")
|
||||
.newline().text("&4>< &7[&aCancel&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "cancel"))
|
||||
.newline().text("&2>> &7[&aDone&7]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "done"))
|
||||
.send(fp);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -29,6 +30,7 @@ import com.sk89q.worldedit.util.command.parametric.BindingHelper;
|
||||
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.annotation.Annotation;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -66,6 +68,13 @@ public class FawePrimitiveBinding extends BindingHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
@BindingMatch(
|
||||
type = {BufferedImage.class},
|
||||
behavior = BindingBehavior.CONSUMES
|
||||
)
|
||||
public BufferedImage getImage(ArgumentStack context) throws ParameterException {
|
||||
return ImageUtil.getImage(context.next());
|
||||
}
|
||||
|
||||
@BindingMatch(
|
||||
type = {Extent.class},
|
||||
|
@ -310,6 +310,11 @@ public class Settings extends Config {
|
||||
"Allows brushes to be persistent",
|
||||
})
|
||||
public boolean PERSISTENT_BRUSHES = false;
|
||||
@Comment({
|
||||
"Allow CFI visualization",
|
||||
})
|
||||
public boolean CFI_VISUALIZATION = false;
|
||||
|
||||
}
|
||||
|
||||
public static class WEB {
|
||||
|
@ -0,0 +1,142 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class HeightMapMCADrawer {
|
||||
private final HeightMapMCAGenerator gen;
|
||||
private final TextureUtil tu;
|
||||
private final ForkJoinPool pool;
|
||||
|
||||
public HeightMapMCADrawer(HeightMapMCAGenerator generator, TextureUtil textureUtil) {
|
||||
this.gen = generator;
|
||||
this.tu = textureUtil;
|
||||
this.pool = new ForkJoinPool();
|
||||
}
|
||||
|
||||
public HeightMapMCADrawer(HeightMapMCAGenerator generator) {
|
||||
this(generator, Fawe.get().getCachedTextureUtil(false, 0, 100));
|
||||
}
|
||||
|
||||
public BufferedImage draw() {
|
||||
BufferedImage img = new BufferedImage(gen.getWidth(), gen.getLength(), BufferedImage.TYPE_INT_RGB);
|
||||
final char[] overlay = gen.overlay == null ? gen.floor : gen.overlay;
|
||||
final char[] floor = gen.floor;
|
||||
final char[] main = gen.main;
|
||||
final byte[] heights = gen.heights;
|
||||
final int waterHeight = gen.waterHeight;
|
||||
final int width = gen.getWidth();
|
||||
final int length = gen.getLength();
|
||||
|
||||
int[] raw = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
|
||||
|
||||
int parallelism = pool.getParallelism();
|
||||
int size = (heights.length + parallelism - 1) / parallelism;
|
||||
for (int i = 0; i < parallelism; i++) {
|
||||
int start = i * size;
|
||||
int end = Math.min(heights.length, start + size);
|
||||
pool.submit((Runnable) () -> {
|
||||
for (int index = start; index < end; index ++) {
|
||||
int height = (heights[index] & 0xFF);
|
||||
char combined;
|
||||
if ((combined = overlay[index]) == 0) {
|
||||
height--;
|
||||
combined = floor[index];
|
||||
if (combined == 0) {
|
||||
height--;
|
||||
combined = main[index];
|
||||
}
|
||||
}
|
||||
// draw combined
|
||||
int color;
|
||||
switch (combined >> 4) {
|
||||
case 2:
|
||||
color = getAverageBiomeColor(gen.biomes, width, index);
|
||||
break;
|
||||
case 78:
|
||||
color = (0xDD << 16) + (0xDD << 8) + (0xDD << 0);
|
||||
break;
|
||||
default:
|
||||
color = tu.getColor(FaweCache.CACHE_BLOCK[combined]);
|
||||
break;
|
||||
}
|
||||
int slope = getSlope(heights, width, index, height);
|
||||
if (slope != 0) {
|
||||
slope = (slope << 3) + (slope << 2);
|
||||
int r = MathMan.clamp(((color >> 16) & 0xFF) + slope, 0, 255);
|
||||
int g = MathMan.clamp(((color >> 8) & 0xFF) + slope, 0, 255);
|
||||
int b = MathMan.clamp(((color >> 0) & 0xFF) + slope, 0, 255);
|
||||
color = (r << 16) + (g << 8) + (b << 0);
|
||||
}
|
||||
if (height + 1 < waterHeight) {
|
||||
byte waterId = gen.waterId;
|
||||
int waterColor = 0;
|
||||
switch (waterId) {
|
||||
case BlockID.WATER:
|
||||
case BlockID.STATIONARY_WATER:
|
||||
color = tu.averageColor((0x11 << 16) + (0x66 << 8) + (0xCC), color);
|
||||
break;
|
||||
case BlockID.LAVA:
|
||||
case BlockID.STATIONARY_LAVA:
|
||||
color = (0xCC << 16) + (0x33 << 8) + (0);
|
||||
break;
|
||||
default:
|
||||
color = tu.getColor(FaweCache.getBlock(waterId, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
raw[index] = color;
|
||||
}
|
||||
});
|
||||
}
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
pool.shutdownNow();
|
||||
return img;
|
||||
}
|
||||
|
||||
private final int getAverageBiomeColor(byte[] biomes, int width, int index) {
|
||||
int c0 = tu.getBiome(biomes[index] & 0xFF).grassCombined;
|
||||
int c2 = getBiome(biomes, index + 1 + width, index);
|
||||
int c1 = getBiome(biomes, index - 1 - width, index);
|
||||
// int c3 = getBiome(biomes, index + width, index);
|
||||
// int c4 = getBiome(biomes, index - width, index);
|
||||
int r = ((c0 >> 16) & 0xFF) + ((c1 >> 16) & 0xFF) + ((c2 >> 16) & 0xFF);// + ((c3 >> 16) & 0xFF) + ((c4 >> 16) & 0xFF);
|
||||
int g = ((c0 >> 8) & 0xFF) + ((c1 >> 8) & 0xFF) + ((c2 >> 8) & 0xFF);// + ((c3 >> 8) & 0xFF) + ((c4 >> 8) & 0xFF);
|
||||
int b = ((c0) & 0xFF) + ((c1) & 0xFF) + ((c2) & 0xFF);// + ((c3) & 0xFF) + ((c4) & 0xFF);
|
||||
r = r * 85 >> 8;
|
||||
g = g * 85 >> 8;
|
||||
b = b * 85 >> 8;
|
||||
return (r << 16) + (g << 8) + (b);
|
||||
}
|
||||
|
||||
private final int getBiome(byte[] biomes, int newIndex, int index) {
|
||||
if (newIndex < 0 || newIndex >= biomes.length) newIndex = index;
|
||||
int biome = biomes[newIndex] & 0xFF;
|
||||
return tu.getBiome(biome).grassCombined;
|
||||
}
|
||||
|
||||
private int getSlope(byte[] heights, int width, int index, int height) {
|
||||
return (
|
||||
+ getHeight(heights, index + 1, height)
|
||||
// + getHeight(heights, index + width, height)
|
||||
+ getHeight(heights, index + width + 1, height)
|
||||
- getHeight(heights, index - 1, height)
|
||||
// - getHeight(heights, index - width, height)
|
||||
- getHeight(heights, index - width - 1, height)
|
||||
);
|
||||
}
|
||||
|
||||
private int getHeight(byte[] heights, int index, int height) {
|
||||
if (index < 0 || index >= heights.length) return height;
|
||||
return heights[index] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -46,17 +47,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
|
||||
private final Int2ObjectOpenHashMap<char[][][]> blocks = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public final byte[] heights;
|
||||
private final byte[] biomes;
|
||||
private final char[] floor;
|
||||
private final char[] main;
|
||||
private char[] overlay;
|
||||
private int waterHeight = 0;
|
||||
private TextureUtil textureUtil;
|
||||
private boolean randomVariation = true;
|
||||
private int biomePriority = 0;
|
||||
private byte waterId = BlockID.STATIONARY_WATER;
|
||||
private boolean modifiedMain = false;
|
||||
protected final byte[] heights;
|
||||
protected final byte[] biomes;
|
||||
protected final char[] floor;
|
||||
protected final char[] main;
|
||||
protected char[] overlay;
|
||||
protected int waterHeight = 0;
|
||||
protected TextureUtil textureUtil;
|
||||
protected boolean randomVariation = true;
|
||||
protected int biomePriority = 0;
|
||||
protected byte waterId = BlockID.STATIONARY_WATER;
|
||||
protected boolean modifiedMain = false;
|
||||
private ImageViewer viewer;
|
||||
|
||||
public HeightMapMCAGenerator(BufferedImage img, File regionFolder) {
|
||||
this(img.getWidth(), img.getHeight(), regionFolder);
|
||||
@ -76,6 +78,28 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
Arrays.fill(floor, grass);
|
||||
}
|
||||
|
||||
public void setImageViewer(ImageViewer viewer) {
|
||||
this.viewer = viewer;
|
||||
update();
|
||||
}
|
||||
|
||||
public ImageViewer getImageViewer() {
|
||||
return viewer;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (viewer != null) {
|
||||
viewer.view(draw());
|
||||
}
|
||||
}
|
||||
|
||||
public TextureUtil getRawTextureUtil() {
|
||||
if (textureUtil == null) {
|
||||
textureUtil = Fawe.get().getTextureUtil();
|
||||
}
|
||||
return this.textureUtil;
|
||||
}
|
||||
|
||||
public TextureUtil getTextureUtil() {
|
||||
if (textureUtil == null) {
|
||||
textureUtil = Fawe.get().getTextureUtil();
|
||||
@ -96,16 +120,22 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
|
||||
public void setWaterHeight(int waterHeight) {
|
||||
this.waterHeight = waterHeight;
|
||||
update();
|
||||
}
|
||||
|
||||
public void setWaterId(int waterId) {
|
||||
this.waterId = (byte) waterId;
|
||||
update();
|
||||
}
|
||||
|
||||
public void setTextureRandomVariation(boolean randomVariation) {
|
||||
this.randomVariation = randomVariation;
|
||||
}
|
||||
|
||||
public boolean getTextureRandomVariation() {
|
||||
return this.randomVariation;
|
||||
}
|
||||
|
||||
public void setTextureUtil(TextureUtil textureUtil) {
|
||||
this.textureUtil = textureUtil;
|
||||
}
|
||||
@ -172,9 +202,24 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
int y = heights[index] & 0xFF;
|
||||
int newHeight = table.average(x, z, index) - 1;
|
||||
int blockHeight = (newHeight) >> 3;
|
||||
int layerHeight = (newHeight) & 0x7;
|
||||
heights[index] = (byte) blockHeight;
|
||||
int id = floor[index] >> 4;
|
||||
if (id == 78 || id == 80) {
|
||||
floor[index] = (char) (snow + layerHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setHeight(BufferedImage img) {
|
||||
int index = 0;
|
||||
@ -183,17 +228,20 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
heights[index] = (byte) (img.getRGB(x, z) >> 8);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void addCaves() throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addCaves(region);
|
||||
update();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addSchems(Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
||||
update();
|
||||
}
|
||||
|
||||
public void addSchems(BufferedImage img, Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
@ -245,6 +293,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void addSchems(Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
@ -294,15 +343,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
update();
|
||||
}
|
||||
|
||||
public void addDefaultOres(Mask mask) throws WorldEditException {
|
||||
addOres(new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength())), mask);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -323,7 +375,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome biome) {
|
||||
int index = position.getBlockZ() * getWidth() + position.getBlockX();
|
||||
if (index < 0 || index >= heights.length) return false;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
biomes[index] = (byte) biome.getId();
|
||||
return true;
|
||||
}
|
||||
@ -331,21 +383,22 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= heights.length) return false;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
int height = heights[index] & 0xFF;
|
||||
char combined = (char) FaweCache.getCombined(block);
|
||||
if (y > height) {
|
||||
if (y == height + 1) {
|
||||
if (overlay == null) {
|
||||
overlay = new char[getArea()];
|
||||
}
|
||||
overlay[index] = combined;
|
||||
return true;
|
||||
}
|
||||
} else if (y == height) {
|
||||
char combined = (char) block.getCombined();
|
||||
switch (y - height) {
|
||||
case 0:
|
||||
floor[index] = combined;
|
||||
return true;
|
||||
}
|
||||
case 1:
|
||||
char mainId = main[index];
|
||||
char floorId = floor[index];
|
||||
floor[index] = combined;
|
||||
heights[index]++;
|
||||
if (mainId == floorId) return true;
|
||||
y--;
|
||||
combined = floorId;
|
||||
default:
|
||||
short chunkX = (short) (x >> 4);
|
||||
short chunkZ = (short) (z >> 4);
|
||||
int pair = MathMan.pair(chunkX, chunkZ);
|
||||
@ -366,11 +419,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
zMap[x & 15] = combined != 0 ? combined : 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBiome getBiome(Vector2D position) {
|
||||
int index = position.getBlockZ() * getWidth() + position.getBlockX();
|
||||
if (index < 0 || index >= heights.length) return EditSession.nullBiome;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
return FaweCache.CACHE_BIOME[biomes[index] & 0xFF];
|
||||
}
|
||||
|
||||
@ -387,7 +441,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
@Override
|
||||
public BaseBlock getLazyBlock(int x, int y, int z) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= heights.length) return EditSession.nullBlock;
|
||||
if (y < 0) return EditSession.nullBlock;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
int height = heights[index] & 0xFF;
|
||||
if (y > height) {
|
||||
if (y == height + 1) {
|
||||
@ -431,14 +486,14 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
@Override
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= heights.length) return y;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
return ((heights[index] & 0xFF) << 3) + (floor[index] & 0xFF) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= heights.length) return y;
|
||||
if (index < 0 || index >= heights.length) index = Math.floorMod(index, heights.length);
|
||||
return heights[index] & 0xFF;
|
||||
}
|
||||
|
||||
@ -454,12 +509,21 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public BufferedImage draw() {
|
||||
return new HeightMapMCADrawer(this).draw();
|
||||
}
|
||||
|
||||
public void setBiomePriority(int value) {
|
||||
this.biomePriority = ((value * 65536) / 100) - 32768;
|
||||
}
|
||||
|
||||
public int getBiomePriority() {
|
||||
return ((biomePriority + 32768) * 100) / 65536;
|
||||
}
|
||||
|
||||
public void setBlockAndBiomeColor(BufferedImage img, Mask mask, BufferedImage imgMask, boolean whiteOnly) {
|
||||
if (mask == null && imgMask == null) {
|
||||
setBlockAndBiomeColor(img);
|
||||
@ -495,6 +559,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
biomes[index] = (byte) buffer[1];
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setBlockAndBiomeColor(BufferedImage img) {
|
||||
@ -519,12 +584,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
biomes[index] = (byte) buffer[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setBiomeIfZero(int index, byte value) {
|
||||
if (biomes[index] == 0) {
|
||||
biomes[index] = value;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setBiomeColor(BufferedImage img) {
|
||||
@ -542,6 +602,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColor(BufferedImage img, BufferedImage mask, boolean white) {
|
||||
@ -566,9 +627,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColor(BufferedImage img, Mask mask, boolean white) {
|
||||
public void setColor(BufferedImage img, Mask mask) {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
modifiedMain = true;
|
||||
@ -590,6 +652,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColor(BufferedImage img) {
|
||||
@ -610,6 +673,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColorWithGlass(BufferedImage img) {
|
||||
@ -628,6 +692,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setBiome(Mask mask, byte biome) {
|
||||
@ -643,13 +708,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setOverlay(BufferedImage img, Pattern pattern, boolean white) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setOverlay(img, (char) ((BaseBlock) pattern).getCombined(), white);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
if (overlay == null) overlay = new char[getArea()];
|
||||
@ -666,12 +731,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setMain(BufferedImage img, Pattern pattern, boolean white) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setMain(img, (char) ((BaseBlock) pattern).getCombined(), white);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
modifiedMain = true;
|
||||
@ -688,12 +754,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setFloor(BufferedImage img, Pattern pattern, boolean white) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setFloor(img, (char) ((BaseBlock) pattern).getCombined(), white);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
int index = 0;
|
||||
@ -709,12 +776,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColumn(BufferedImage img, Pattern pattern, boolean white) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setColumn(img, (char) ((BaseBlock) pattern).getCombined(), white);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
modifiedMain = true;
|
||||
@ -733,12 +801,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setOverlay(Mask mask, Pattern pattern) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setOverlay(mask, (char) ((BaseBlock) pattern).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
if (overlay == null) overlay = new char[getArea()];
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
@ -753,12 +822,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setFloor(Mask mask, Pattern pattern) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setFloor(mask, (char) ((BaseBlock) pattern).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
@ -772,12 +842,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setMain(Mask mask, Pattern pattern) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setMain(mask, (char) ((BaseBlock) pattern).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
modifiedMain = true;
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
@ -792,12 +863,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColumn(Mask mask, Pattern pattern) {
|
||||
if (pattern instanceof BaseBlock) {
|
||||
setColumn(mask, (char) ((BaseBlock) pattern).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
modifiedMain = true;
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
@ -814,16 +886,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setBiome(int biome) {
|
||||
Arrays.fill(biomes, (byte) biome);
|
||||
update();
|
||||
}
|
||||
|
||||
public void setFloor(Pattern value) {
|
||||
if (value instanceof BaseBlock) {
|
||||
setFloor(((BaseBlock) value).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
@ -835,12 +909,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setColumn(Pattern value) {
|
||||
if (value instanceof BaseBlock) {
|
||||
setColumn(((BaseBlock) value).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
@ -854,12 +929,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setMain(Pattern value) {
|
||||
if (value instanceof BaseBlock) {
|
||||
setMain(((BaseBlock) value).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
@ -871,13 +947,14 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setOverlay(Pattern value) {
|
||||
if (overlay == null) overlay = new char[getArea()];
|
||||
if (value instanceof BaseBlock) {
|
||||
setOverlay(((BaseBlock) value).getCombined());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int index = 0;
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
@ -889,9 +966,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public void setHeights(int value) {
|
||||
Arrays.fill(heights, (byte) value);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
public abstract class MCAWriter {
|
||||
private final File folder;
|
||||
private File folder;
|
||||
private final int length;
|
||||
private final int width;
|
||||
private final int area;
|
||||
@ -18,9 +18,6 @@ public abstract class MCAWriter {
|
||||
|
||||
|
||||
public MCAWriter(int width, int length, File regionFolder) {
|
||||
if (!regionFolder.exists()) {
|
||||
regionFolder.mkdirs();
|
||||
}
|
||||
this.folder = regionFolder;
|
||||
this.width = width;
|
||||
this.length = length;
|
||||
@ -31,6 +28,10 @@ public abstract class MCAWriter {
|
||||
return folder;
|
||||
}
|
||||
|
||||
public void setFolder(File folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
public final int getWidth() {
|
||||
return width;
|
||||
}
|
||||
@ -69,6 +70,9 @@ public abstract class MCAWriter {
|
||||
public abstract MCAChunk write(MCAChunk input, int startX, int endX, int startZ, int endZ);
|
||||
|
||||
public void generate() throws IOException {
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
final ForkJoinPool pool = new ForkJoinPool();
|
||||
int bcx = 0;
|
||||
int bcz = 0;
|
||||
|
@ -29,7 +29,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public class HistoryExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final AbstractDelegateExtent extent;
|
||||
private FaweChangeSet changeSet;
|
||||
private final FaweQueue queue;
|
||||
private final EditSession session;
|
||||
@ -43,7 +42,6 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
public HistoryExtent(final EditSession session, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) {
|
||||
super(extent);
|
||||
checkNotNull(changeSet);
|
||||
this.extent = (AbstractDelegateExtent) extent;
|
||||
this.queue = queue;
|
||||
this.changeSet = changeSet;
|
||||
this.session = session;
|
||||
@ -92,12 +90,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
} catch (FaweException ignore) {
|
||||
return false;
|
||||
}
|
||||
return extent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getLazyBlock(int x, int y, int z) {
|
||||
return extent.getLazyBlock(x, y, z);
|
||||
return getExtent().setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,7 +136,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
BaseBiome oldBiome = this.getBiome(position);
|
||||
if (oldBiome.getId() != newBiome.getId()) {
|
||||
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockZ(), oldBiome, newBiome);
|
||||
return extent.setBiome(position, newBiome);
|
||||
return getExtent().setBiome(position, newBiome);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -79,8 +79,8 @@ public class CreateFromImage extends Command {
|
||||
@Override
|
||||
public void run() {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player.getName());
|
||||
HeightMapMCAGenerator generator = player.getMeta("HMGenerator");
|
||||
Plot plot = player.getMeta("HMGeneratorPlot");
|
||||
HeightMapMCAGenerator generator = fp.getMeta("HMGenerator");
|
||||
Plot plot = fp.getMeta("HMGeneratorPlot");
|
||||
if (generator == null) {
|
||||
final Vector2D dimensions;
|
||||
final BufferedImage image;
|
||||
@ -164,7 +164,8 @@ public class CreateFromImage extends Command {
|
||||
} else {
|
||||
generator = new HeightMapMCAGenerator(dimensions.getBlockX(), dimensions.getBlockZ(), folder);
|
||||
}
|
||||
player.setMeta("HMGenerator", generator);
|
||||
generator.setImageViewer(Fawe.imp().getImageViewer(fp));
|
||||
fp.setMeta("HMGenerator", generator);
|
||||
player.setMeta("HMGeneratorPlot", plot);
|
||||
}
|
||||
}, true, false);
|
||||
@ -310,7 +311,7 @@ public class CreateFromImage extends Command {
|
||||
} else {
|
||||
Mask mask = we.getMaskFactory().parseFromInput(argList.get(1), context);
|
||||
boolean whiteOnly = argList.size() < 4 || Boolean.parseBoolean(argList.get(3));
|
||||
generator.setColor(image, mask, whiteOnly);
|
||||
generator.setColor(image, mask);
|
||||
}
|
||||
} else {
|
||||
generator.setColor(image);
|
||||
@ -594,8 +595,8 @@ public class CreateFromImage extends Command {
|
||||
return;
|
||||
case "exit":
|
||||
case "cancel":
|
||||
player.deleteMeta("HMGenerator");
|
||||
player.deleteMeta("HMGeneratorPlot");
|
||||
fp.deleteMeta("HMGenerator");
|
||||
fp.deleteMeta("HMGeneratorPlot");
|
||||
player.sendMessage(BBC.getPrefix() + "Cancelled!");
|
||||
return;
|
||||
default:
|
||||
|
@ -4,8 +4,12 @@ import java.io.FileNotFoundException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CleanTextureUtil extends TextureUtil {
|
||||
private final int min, max;
|
||||
|
||||
public CleanTextureUtil(TextureUtil parent, int minPercent, int maxPercent) throws FileNotFoundException {
|
||||
super(parent.getFolder());
|
||||
this.min = minPercent;
|
||||
this.max = maxPercent;
|
||||
int minIndex = ((parent.distances.length - 1) * minPercent) / 100;
|
||||
int maxIndex = ((parent.distances.length - 1) * maxPercent) / 100;
|
||||
long min = parent.distances[minIndex];
|
||||
@ -30,4 +34,12 @@ public class CleanTextureUtil extends TextureUtil {
|
||||
}
|
||||
this.calculateLayerArrays();
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ public class ExtentTraverser<T extends Extent> {
|
||||
public boolean setNext(T next) {
|
||||
try {
|
||||
Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||
field.setAccessible(true);
|
||||
field.set(root, next);
|
||||
ReflectionUtils.setFailsafeFieldValue(field, root, next);
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -37,6 +36,16 @@ public class ExtentTraverser<T extends Extent> {
|
||||
}
|
||||
}
|
||||
|
||||
public ExtentTraverser<T> last() {
|
||||
ExtentTraverser<T> last = this;
|
||||
ExtentTraverser<T> traverser = this;
|
||||
while (traverser != null && traverser.get() instanceof AbstractDelegateExtent) {
|
||||
last = traverser;
|
||||
traverser = traverser.next();
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
public boolean insert(T extent) {
|
||||
try {
|
||||
Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||
|
@ -6,8 +6,11 @@ import java.io.FileNotFoundException;
|
||||
import java.util.Set;
|
||||
|
||||
public class FilteredTextureUtil extends TextureUtil {
|
||||
private final Set<BaseBlock> blocks;
|
||||
|
||||
public FilteredTextureUtil(TextureUtil parent, Set<BaseBlock> blocks) throws FileNotFoundException {
|
||||
super(parent.getFolder());
|
||||
this.blocks = blocks;
|
||||
this.validMixBiomeColors = parent.validMixBiomeColors;
|
||||
this.validMixBiomeIds = parent.validMixBiomeIds;
|
||||
this.validBiomes = parent.validBiomes;
|
||||
@ -33,4 +36,8 @@ public class FilteredTextureUtil extends TextureUtil {
|
||||
}
|
||||
this.calculateLayerArrays();
|
||||
}
|
||||
|
||||
public Set<BaseBlock> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
}
|
@ -3,18 +3,24 @@ package com.boydti.fawe.util;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum Jars {
|
||||
WE_B_6_1_7_2("https://addons.cursecdn.com/files/2431/372/worldedit-bukkit-6.1.7.2.jar",
|
||||
"711be37301a327aba4e347131875d0564dbfdc2f41053a12db97f0234661778b", 1726340),
|
||||
|
||||
VS_B_5_171_0("https://addons-origin.cursecdn.com/files/912/511/VoxelSniper-5.171.0-SNAPSHOT.jar",
|
||||
"292c3b38238e0d8e5f036381d28bccfeb15df67cae53d28b52d066bc6238208f", 3632776);
|
||||
"292c3b38238e0d8e5f036381d28bccfeb15df67cae53d28b52d066bc6238208f", 3632776),
|
||||
|
||||
MM_v1_4_0("https://github.com/InventivetalentDev/MapManager/releases/download/1.4.0-SNAPSHOT/MapManager_v1.4.0-SNAPSHOT.jar",
|
||||
"004A39B0A06E80DE3226B4BCC6080D2DB9B6411CCFB48D647F4FF55B5B91B600", 163279),
|
||||
|
||||
PL_v3_6_0("https://github.com/InventivetalentDev/PacketListenerAPI/releases/download/3.6.0-SNAPSHOT/PacketListenerAPI_v3.6.0-SNAPSHOT.jar",
|
||||
"3B26C4EF9BE253E9E7C07AD5AC46CB0C047003EFD36DD433D6B739EB6AAE9410", 166508),
|
||||
|
||||
;
|
||||
|
||||
public final String url;
|
||||
public final int filesize;
|
||||
@ -28,9 +34,9 @@ public enum Jars {
|
||||
* @param filesize
|
||||
* Size of this jar in bytes
|
||||
*/
|
||||
private Jars(String url, String digest, int filesize) {
|
||||
Jars(String url, String digest, int filesize) {
|
||||
this.url = url;
|
||||
this.digest = digest;
|
||||
this.digest = digest.toUpperCase();
|
||||
this.filesize = filesize;
|
||||
}
|
||||
|
||||
@ -43,16 +49,14 @@ public enum Jars {
|
||||
if (dis.read() != -1) { // assert that we've read everything
|
||||
throw new IllegalStateException("downloaded jar is longer than expected");
|
||||
}
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
byte[] jarDigestBytes = md.digest(jarBytes);
|
||||
String jarDigest = javax.xml.bind.DatatypeConverter.printHexBinary(jarDigestBytes).toUpperCase();
|
||||
|
||||
MessageDigest md;
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
byte[] thisDigest = md.digest(jarBytes);
|
||||
byte[] realDigest = new BigInteger(this.digest.toUpperCase(), 16).toByteArray();
|
||||
|
||||
if (Arrays.equals(thisDigest, realDigest)) {
|
||||
if (this.digest.equals(jarDigest)) {
|
||||
Fawe.debug("++++ HASH CHECK ++++");
|
||||
Fawe.debug(this.url);
|
||||
Fawe.debug(javax.xml.bind.DatatypeConverter.printHexBinary(thisDigest));
|
||||
Fawe.debug(this.digest);
|
||||
return jarBytes;
|
||||
} else {
|
||||
throw new IllegalStateException("downloaded jar does not match the hash");
|
||||
|
@ -685,6 +685,7 @@ public class TextureUtil {
|
||||
if (biome.grass != 0 && !biome.name.equalsIgnoreCase("Unknown Biome")) {
|
||||
valid.add(biome);
|
||||
}
|
||||
biome.grassCombined = multiplyColor(grass, biome.grass);
|
||||
}
|
||||
this.validBiomes = valid.toArray(new BiomeColor[valid.size()]);
|
||||
|
||||
@ -779,10 +780,10 @@ public class TextureUtil {
|
||||
int red2 = (c2 >> 16) & 0xFF;
|
||||
int green2 = (c2 >> 8) & 0xFF;
|
||||
int blue2 = (c2 >> 0) & 0xFF;
|
||||
int red = ((red1 + red2)) / 2;
|
||||
int green = ((green1 + green2)) / 2;
|
||||
int blue = ((blue1 + blue2)) / 2;
|
||||
int alpha = ((alpha1 + alpha2)) / 2;
|
||||
int red = ((red1 + red2)) >> 1;
|
||||
int green = ((green1 + green2)) >> 1;
|
||||
int blue = ((blue1 + blue2)) >> 1;
|
||||
int alpha = ((alpha1 + alpha2)) >> 1;
|
||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
|
||||
@ -1049,6 +1050,7 @@ public class TextureUtil {
|
||||
public float temperature;
|
||||
public float rainfall;
|
||||
public int grass;
|
||||
public int grassCombined;
|
||||
public int foliage;
|
||||
|
||||
public BiomeColor(int id, String name, float temperature, float rainfall, int grass, int foliage) {
|
||||
@ -1057,7 +1059,12 @@ public class TextureUtil {
|
||||
this.temperature = temperature;
|
||||
this.rainfall = rainfall;
|
||||
this.grass = grass;
|
||||
this.grassCombined = grass;
|
||||
this.foliage = foliage;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getValidBlockIds() {
|
||||
return validBlockIds.clone();
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,19 @@ public class Message {
|
||||
return tooltip(commandAndTooltip).command(commandAndTooltip);
|
||||
}
|
||||
|
||||
public Message linkTip(String linkAndTooltip) {
|
||||
return tooltip(linkAndTooltip).link(linkAndTooltip);
|
||||
}
|
||||
|
||||
public Message cmdOptions(String prefix, String suffix, String... options) {
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
if (i != 0) text(" &8|&7 ");
|
||||
text("&7[&a" + options[i] + "&7]")
|
||||
.cmdTip(prefix + options[i] + suffix);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message suggestTip(String commandAndTooltip) {
|
||||
return tooltip(commandAndTooltip).suggest(commandAndTooltip);
|
||||
}
|
||||
|
18
core/src/main/java/com/boydti/fawe/util/cui/CUI.java
Normal file
18
core/src/main/java/com/boydti/fawe/util/cui/CUI.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.boydti.fawe.util.cui;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
|
||||
public abstract class CUI {
|
||||
private final FawePlayer player;
|
||||
|
||||
public CUI(FawePlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public <T> FawePlayer<T> getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public abstract void dispatchCUIEvent(CUIEvent event);
|
||||
}
|
94
core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java
Normal file
94
core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java
Normal file
@ -0,0 +1,94 @@
|
||||
package com.boydti.fawe.util.image;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
public class ImageUtil {
|
||||
public static BufferedImage getScaledInstance(BufferedImage img,
|
||||
int targetWidth,
|
||||
int targetHeight,
|
||||
Object hint,
|
||||
boolean higherQuality)
|
||||
{
|
||||
if (img.getHeight() == targetHeight && img.getWidth() == targetWidth) {
|
||||
return img;
|
||||
}
|
||||
int type = (img.getTransparency() == Transparency.OPAQUE) ?
|
||||
BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
|
||||
BufferedImage ret = (BufferedImage)img;
|
||||
int w, h;
|
||||
if (higherQuality) {
|
||||
// Use multi-step technique: start with original size, then
|
||||
// scale down in multiple passes with drawImage()
|
||||
// until the target size is reached
|
||||
w = img.getWidth();
|
||||
h = img.getHeight();
|
||||
} else {
|
||||
// Use one-step technique: scale directly from original
|
||||
// size to target size with a single drawImage() call
|
||||
w = targetWidth;
|
||||
h = targetHeight;
|
||||
}
|
||||
|
||||
do {
|
||||
if (higherQuality && w > targetWidth) {
|
||||
w /= 2;
|
||||
if (w < targetWidth) {
|
||||
w = targetWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (higherQuality && h > targetHeight) {
|
||||
h /= 2;
|
||||
if (h < targetHeight) {
|
||||
h = targetHeight;
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage tmp = new BufferedImage(w, h, type);
|
||||
Graphics2D g2 = tmp.createGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
|
||||
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
|
||||
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
||||
g2.drawImage(ret, 0, 0, w, h, null);
|
||||
g2.dispose();
|
||||
|
||||
ret = tmp;
|
||||
} while (w != targetWidth || h != targetHeight);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static BufferedImage getImage(String arg) throws ParameterException {
|
||||
try {
|
||||
if (arg.startsWith("http")) {
|
||||
if (arg.contains("imgur.com") && !arg.contains("i.imgur.com")) {
|
||||
arg = "https://i.imgur.com/" + arg.split("imgur.com/")[1] + ".png";
|
||||
}
|
||||
URL url = new URL(arg);
|
||||
BufferedImage img = MainUtil.readImage(url);
|
||||
if (img == null) {
|
||||
throw new IOException("Failed to read " + url + ", please try again later");
|
||||
}
|
||||
return img;
|
||||
} else if (arg.startsWith("file://")) {
|
||||
arg = arg.substring(7);
|
||||
File file = MainUtil.getFile(MainUtil.getFile(Fawe.imp().getDirectory(), com.boydti.fawe.config.Settings.IMP.PATHS.HEIGHTMAP), arg);
|
||||
return MainUtil.readImage(file);
|
||||
} else {
|
||||
throw new ParameterException("Invalid image " + arg);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ParameterException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.boydti.fawe.util.image;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.Closeable;
|
||||
|
||||
public interface ImageViewer extends Closeable{
|
||||
public void view(BufferedImage image);
|
||||
}
|
@ -34,6 +34,7 @@ import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
import com.sk89q.jchronic.Chronic;
|
||||
import com.sk89q.jchronic.Options;
|
||||
@ -1130,6 +1131,9 @@ public class LocalSession {
|
||||
|
||||
if (hasCUISupport) {
|
||||
actor.dispatchCUIEvent(event);
|
||||
} else {
|
||||
CUI cui = Fawe.get().getCUI(actor);
|
||||
if (cui != null) cui.dispatchCUIEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1151,22 +1155,16 @@ public class LocalSession {
|
||||
*/
|
||||
public void dispatchCUISelection(Actor actor) {
|
||||
checkNotNull(actor);
|
||||
|
||||
if (!hasCUISupport) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selector instanceof CUIRegion) {
|
||||
CUIRegion tempSel = (CUIRegion) selector;
|
||||
|
||||
if (tempSel.getProtocolVersion() > cuiVersion) {
|
||||
actor.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getLegacyTypeID()));
|
||||
dispatchCUIEvent(actor, new SelectionShapeEvent(tempSel.getLegacyTypeID()));
|
||||
tempSel.describeLegacyCUI(this, actor);
|
||||
} else {
|
||||
actor.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getTypeID()));
|
||||
dispatchCUIEvent(actor, new SelectionShapeEvent(tempSel.getTypeID()));
|
||||
tempSel.describeCUI(this, actor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1177,11 +1175,6 @@ public class LocalSession {
|
||||
*/
|
||||
public void describeCUI(Actor actor) {
|
||||
checkNotNull(actor);
|
||||
|
||||
if (!hasCUISupport) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selector instanceof CUIRegion) {
|
||||
CUIRegion tempSel = (CUIRegion) selector;
|
||||
|
||||
|
@ -21,6 +21,8 @@ package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.command.AnvilCommands;
|
||||
import com.boydti.fawe.command.CFICommand;
|
||||
import com.boydti.fawe.command.CFICommands;
|
||||
import com.boydti.fawe.command.MaskBinding;
|
||||
import com.boydti.fawe.command.PatternBinding;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
@ -125,7 +127,7 @@ public final class CommandManager {
|
||||
private final DynamicStreamHandler dynamicHandler = new DynamicStreamHandler();
|
||||
private final ExceptionConverter exceptionConverter;
|
||||
|
||||
|
||||
private ParametricBuilder builder;
|
||||
private Map<Object, String[]> methodMap;
|
||||
|
||||
private static CommandManager INSTANCE;
|
||||
@ -151,7 +153,27 @@ public final class CommandManager {
|
||||
commandLog.addHandler(dynamicHandler);
|
||||
dynamicHandler.setFormatter(new LogFormat());
|
||||
|
||||
builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
|
||||
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
|
||||
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
|
||||
|
||||
builder.addInvokeListener(new LegacyCommandsHandler());
|
||||
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
|
||||
|
||||
this.methodMap = new ConcurrentHashMap<>();
|
||||
|
||||
try {
|
||||
Class.forName("com.intellectualcrafters.plot.PS");
|
||||
CFICommands cfiCmds = new CFICommands(worldEdit);
|
||||
CFICommand cfi = new CFICommand(worldEdit, builder);
|
||||
registerCommands(cfi);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,14 +195,6 @@ public final class CommandManager {
|
||||
*/
|
||||
public void registerCommands(Object clazz, String... aliases) {
|
||||
if (platform != null) {
|
||||
ParametricBuilder builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
|
||||
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
|
||||
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
|
||||
|
||||
DispatcherNode graph = new CommandGraph().builder(builder).commands();
|
||||
if (aliases.length == 0) {
|
||||
graph = graph.registerMethods(clazz);
|
||||
@ -198,16 +212,6 @@ public final class CommandManager {
|
||||
* Initialize the dispatcher
|
||||
*/
|
||||
public void setupDispatcher() {
|
||||
ParametricBuilder builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
|
||||
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
|
||||
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
|
||||
|
||||
builder.addInvokeListener(new LegacyCommandsHandler());
|
||||
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
|
||||
DispatcherNode graph = new CommandGraph().builder(builder).commands();
|
||||
|
||||
for (Map.Entry<Object, String[]> entry : methodMap.entrySet()) {
|
||||
|
@ -244,15 +244,14 @@ public class HeightMap {
|
||||
|
||||
// Skip water/lava
|
||||
if (!FaweCache.isLiquidOrGas(existing.getId())) {
|
||||
session.setBlock(xr, newHeight, zr, existing);
|
||||
++blocksChanged;
|
||||
|
||||
// Grow -- start from 1 below top replacing airblocks
|
||||
for (int y = newHeight - 1 - originY; y >= curHeight; --y) {
|
||||
for (int y = curHeight; y <= newHeight - 1 - originY; y++) {
|
||||
int copyFrom = (int) (y * scale);
|
||||
session.setBlock(xr, originY + y, zr, session.getBlock(xr, originY + copyFrom, zr));
|
||||
++blocksChanged;
|
||||
}
|
||||
|
||||
session.setBlock(xr, newHeight, zr, existing);
|
||||
++blocksChanged;
|
||||
}
|
||||
} else if (curHeight > newHeight) {
|
||||
// Set the top block of the column to be the same type
|
||||
|
@ -51,6 +51,10 @@ public class ClipboardHolder {
|
||||
this.worldData = worldData;
|
||||
}
|
||||
|
||||
protected ClipboardHolder() {
|
||||
worldData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mapping used for blocks, entities, and so on.
|
||||
*
|
||||
|
@ -0,0 +1,45 @@
|
||||
package com.sk89q.worldedit.session;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
|
||||
public class DelegateClipboardHolder extends ClipboardHolder {
|
||||
private final ClipboardHolder parent;
|
||||
|
||||
public DelegateClipboardHolder(ClipboardHolder holder) {
|
||||
super(holder.getClipboard(), holder.getWorldData());
|
||||
this.parent = holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldData getWorldData() {
|
||||
return parent.getWorldData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
return parent.getClipboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(Transform transform) {
|
||||
parent.setTransform(transform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transform getTransform() {
|
||||
return parent.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasteBuilder createPaste(Extent targetExtent, WorldData targetWorldData) {
|
||||
return parent.createPaste(targetExtent, targetWorldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
parent.close();
|
||||
}
|
||||
}
|
@ -20,13 +20,20 @@
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.boydti.fawe.command.FawePrimitiveBinding;
|
||||
import com.boydti.fawe.command.MaskBinding;
|
||||
import com.boydti.fawe.command.PatternBinding;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.MethodCommands;
|
||||
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
|
||||
import com.sk89q.worldedit.internal.command.UserCommandCompleter;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.util.auth.Authorizer;
|
||||
import com.sk89q.worldedit.util.auth.NullAuthorizer;
|
||||
import com.sk89q.worldedit.util.command.CallableProcessor;
|
||||
|
Loading…
Reference in New Issue
Block a user