mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 02:22:32 +00:00
Implement structure storage format (to be moved to Gaea in the future)
This commit is contained in:
parent
53a82470da
commit
aa326d95e9
10
.idea/jarRepositories.xml
generated
10
.idea/jarRepositories.xml
generated
@ -11,6 +11,11 @@
|
||||
<option name="name" value="aikar" />
|
||||
<option name="url" value="https://repo.aikar.co/content/groups/aikar/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="enginehub-maven" />
|
||||
<option name="name" value="enginehub-maven" />
|
||||
<option name="url" value="http://maven.enginehub.org/repo/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="spigotmc-repo" />
|
||||
<option name="name" value="spigotmc-repo" />
|
||||
@ -26,6 +31,11 @@
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="enginehub" />
|
||||
<option name="name" value="enginehub" />
|
||||
<option name="url" value="https://maven.enginehub.org/repo/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="minecraft-repo" />
|
||||
<option name="name" value="minecraft-repo" />
|
||||
|
10
pom.xml
10
pom.xml
@ -68,6 +68,10 @@
|
||||
<name>gaea</name>
|
||||
<url>file:/home/dfsek/Documents/Gaea/repo</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>enginehub-maven</id>
|
||||
<url>http://maven.enginehub.org/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@ -110,6 +114,12 @@
|
||||
<artifactId>commons-imaging</artifactId>
|
||||
<version>1.0-alpha2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -2,23 +2,29 @@ package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.ConfigUtil;
|
||||
import com.dfsek.terra.config.WorldConfig;
|
||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||
import com.dfsek.terra.config.ConfigUtil;
|
||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||
import com.dfsek.terra.image.WorldImageGenerator;
|
||||
import com.dfsek.terra.structure.GaeaStructure;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.profiler.WorldProfiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@ -26,90 +32,148 @@ import java.util.Random;
|
||||
public class TerraCommand implements CommandExecutor, TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
switch(args[0]) {
|
||||
case "reload":
|
||||
ConfigUtil.loadConfig(Terra.getInstance());
|
||||
sender.sendMessage("Reloaded Terra config.");
|
||||
return true;
|
||||
case "biome":
|
||||
if(!(sender instanceof Player)) return false;
|
||||
sender.sendMessage("You are in " + BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getFriendlyName());
|
||||
return true;
|
||||
case "profile":
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
try {
|
||||
switch(args[0]) {
|
||||
case "reload":
|
||||
ConfigUtil.loadConfig(Terra.getInstance());
|
||||
sender.sendMessage("Reloaded Terra config.");
|
||||
return true;
|
||||
}
|
||||
Player p = (Player) sender;
|
||||
if(p.getWorld().getGenerator() instanceof TerraChunkGenerator) {
|
||||
WorldProfiler profile = TerraProfiler.fromWorld(p.getWorld());
|
||||
if(args.length > 1 && "query".equals(args[1])) {
|
||||
sender.sendMessage(profile.getResultsFormatted());
|
||||
return true;
|
||||
} else if(args.length > 1 && "reset".equals(args[1])) {
|
||||
profile.reset();
|
||||
sender.sendMessage("Profiler has been reset.");
|
||||
return true;
|
||||
} else if(args.length > 1 && "start".equals(args[1])) {
|
||||
profile.setProfiling(true);
|
||||
sender.sendMessage("Profiler has started.");
|
||||
return true;
|
||||
} else if(args.length > 1 && "stop".equals(args[1])) {
|
||||
profile.setProfiling(false);
|
||||
sender.sendMessage("Profiler has stopped.");
|
||||
return true;
|
||||
}
|
||||
} else sender.sendMessage("World is not a Terra world!");
|
||||
break;
|
||||
case "ore":
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
case "biome":
|
||||
if(! (sender instanceof Player)) return false;
|
||||
sender.sendMessage("You are in " + BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(((Player) sender).getWorld()).getBiome(((Player) sender).getLocation())).getFriendlyName());
|
||||
return true;
|
||||
}
|
||||
Block bl = ((Player) sender).getTargetBlockExact(25);
|
||||
OreConfig ore = OreConfig.fromID(args[1]);
|
||||
if(ore == null) {
|
||||
sender.sendMessage("Unable to find Ore");
|
||||
return true;
|
||||
}
|
||||
ore.doVein(bl.getLocation(), new Random());
|
||||
return true;
|
||||
case "image":
|
||||
if("render".equals(args[1])) {
|
||||
case "profile":
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
return true;
|
||||
}
|
||||
Player pl = (Player) sender;
|
||||
if(args.length != 4) return false;
|
||||
try {
|
||||
WorldImageGenerator g = new WorldImageGenerator(pl.getWorld(), Integer.parseInt(args[2]), Integer.parseInt(args[3]));
|
||||
g.drawWorld(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ());
|
||||
File file = new File(Terra.getInstance().getDataFolder() + File.separator + "map_export" + File.separator + "map_" + System.currentTimeMillis() + ".png");
|
||||
file.mkdirs();
|
||||
file.createNewFile();
|
||||
g.save(file);
|
||||
sender.sendMessage("Saved image to " + file.getPath());
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
} else if("gui".equals(args[1])) {
|
||||
Player p = (Player) sender;
|
||||
if(p.getWorld().getGenerator() instanceof TerraChunkGenerator) {
|
||||
WorldProfiler profile = TerraProfiler.fromWorld(p.getWorld());
|
||||
if(args.length > 1 && "query".equals(args[1])) {
|
||||
sender.sendMessage(profile.getResultsFormatted());
|
||||
return true;
|
||||
} else if(args.length > 1 && "reset".equals(args[1])) {
|
||||
profile.reset();
|
||||
sender.sendMessage("Profiler has been reset.");
|
||||
return true;
|
||||
} else if(args.length > 1 && "start".equals(args[1])) {
|
||||
profile.setProfiling(true);
|
||||
sender.sendMessage("Profiler has started.");
|
||||
return true;
|
||||
} else if(args.length > 1 && "stop".equals(args[1])) {
|
||||
profile.setProfiling(false);
|
||||
sender.sendMessage("Profiler has stopped.");
|
||||
return true;
|
||||
}
|
||||
} else sender.sendMessage("World is not a Terra world!");
|
||||
break;
|
||||
case "ore":
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
return true;
|
||||
}
|
||||
Player pl = (Player) sender;
|
||||
try {
|
||||
if("raw".equals(args[2])) WorldConfig.fromWorld(pl.getWorld()).imageLoader.debug(false, pl.getWorld());
|
||||
else if("step".equals(args[2])) WorldConfig.fromWorld(pl.getWorld()).imageLoader.debug(true, pl.getWorld());
|
||||
else return false;
|
||||
Block bl = ((Player) sender).getTargetBlockExact(25);
|
||||
OreConfig ore = OreConfig.fromID(args[1]);
|
||||
if(ore == null) {
|
||||
sender.sendMessage("Unable to find Ore");
|
||||
return true;
|
||||
} catch(NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ore.doVein(bl.getLocation(), new Random());
|
||||
return true;
|
||||
case "image":
|
||||
if("render".equals(args[1])) {
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
return true;
|
||||
}
|
||||
Player pl = (Player) sender;
|
||||
if(args.length != 4) return false;
|
||||
try {
|
||||
WorldImageGenerator g = new WorldImageGenerator(pl.getWorld(), Integer.parseInt(args[2]), Integer.parseInt(args[3]));
|
||||
g.drawWorld(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ());
|
||||
File file = new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "map" + File.separator + "map_" + System.currentTimeMillis() + ".png");
|
||||
file.mkdirs();
|
||||
file.createNewFile();
|
||||
g.save(file);
|
||||
sender.sendMessage("Saved image to " + file.getPath());
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
} else if("gui".equals(args[1])) {
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
return true;
|
||||
}
|
||||
Player pl = (Player) sender;
|
||||
try {
|
||||
if("raw".equals(args[2]))
|
||||
WorldConfig.fromWorld(pl.getWorld()).imageLoader.debug(false, pl.getWorld());
|
||||
else if("step".equals(args[2]))
|
||||
WorldConfig.fromWorld(pl.getWorld()).imageLoader.debug(true, pl.getWorld());
|
||||
else return false;
|
||||
return true;
|
||||
} catch(NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "structure":
|
||||
if(! (sender instanceof Player)) {
|
||||
sender.sendMessage("Command is for players only.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Player pl = (Player) sender;
|
||||
if("export".equals(args[1])) {
|
||||
WorldEditPlugin we = WorldEditUtil.getWorldEdit();
|
||||
if(we == null) {
|
||||
sender.sendMessage("WorldEdit is not installed! Please install WorldEdit before attempting to export structures.");
|
||||
return true;
|
||||
}
|
||||
Region selection;
|
||||
try {
|
||||
selection = we.getSession(pl).getSelection(BukkitAdapter.adapt(pl.getWorld()));
|
||||
} catch(IncompleteRegionException e) {
|
||||
sender.sendMessage("Invalid/incomplete selection!");
|
||||
return true;
|
||||
}
|
||||
BukkitAdapter.adapt(pl);
|
||||
if(selection == null) {
|
||||
sender.sendMessage("Please make a selection before attempting to export!");
|
||||
return true;
|
||||
}
|
||||
BlockVector3 min = selection.getMinimumPoint();
|
||||
BlockVector3 max = selection.getMaximumPoint();
|
||||
Location l1 = new Location(pl.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
|
||||
Location l2 = new Location(pl.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
|
||||
GaeaStructure structure = new GaeaStructure(l1, l2);
|
||||
try {
|
||||
File file = new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", args[2] + ".tstructure");
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
structure.save(file);
|
||||
sender.sendMessage("Saved to " + file.getPath());
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
} else if("load".equals(args[1])) {
|
||||
try {
|
||||
GaeaStructure struc = GaeaStructure.load(new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", args[2] + ".tstructure"));
|
||||
if("true".equals(args[3])) struc.paste(pl.getLocation());
|
||||
else struc.paste(pl.getLocation(), pl.getLocation().getChunk());
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
sender.sendMessage("Structure not found.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
14
src/main/java/com/dfsek/terra/WorldEditUtil.java
Normal file
14
src/main/java/com/dfsek/terra/WorldEditUtil.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class WorldEditUtil {
|
||||
public static WorldEditPlugin getWorldEdit() {
|
||||
Plugin p = Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
|
||||
if (p instanceof WorldEditPlugin) return (WorldEditPlugin) p;
|
||||
Bukkit.getLogger().severe("[Terra] a command requiring WorldEdit was executed, but WorldEdit was not detected!");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ public class ConfigLoader {
|
||||
}
|
||||
|
||||
public <T extends TerraConfigObject> void load(JavaPlugin main, Class<T> clazz) {
|
||||
File folder = new File(main.getDataFolder() + File.separator + path);
|
||||
File folder = new File(main.getDataFolder() + File.separator + "config" + File.separator + path);
|
||||
folder.mkdirs();
|
||||
try (Stream<Path> paths = Files.walk(folder.toPath())) {
|
||||
paths
|
||||
|
@ -73,19 +73,25 @@ public class WorldConfig {
|
||||
freq1 = 1f/config.getInt("frequencies.grid-1", 256);
|
||||
freq2 = 1f/config.getInt("frequencies.grid-2", 512);
|
||||
fromImage = config.getBoolean("image.use-image", false);
|
||||
biomeXChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-x", "red")).toUpperCase());
|
||||
biomeZChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-z", "green")).toUpperCase());
|
||||
if(biomeZChannel.equals(biomeXChannel)) throw new InvalidConfigurationException("2 objects share the same image channels: biome-x and biome-z");
|
||||
zoneChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.zone", "blue")).toUpperCase());
|
||||
if(zoneChannel.equals(biomeXChannel) || zoneChannel.equals(biomeZChannel)) throw new InvalidConfigurationException("2 objects share the same image channels: zone and biome-x/z");
|
||||
if(fromImage) {
|
||||
try {
|
||||
imageLoader = new ImageLoader(new File(Objects.requireNonNull(config.getString("image.image-location"))));
|
||||
Bukkit.getLogger().info("[Terra] Loading world from image.");
|
||||
} catch(IOException | NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
fromImage = false;
|
||||
try {
|
||||
biomeXChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-x", "red")).toUpperCase());
|
||||
biomeZChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-z", "green")).toUpperCase());
|
||||
if(biomeZChannel.equals(biomeXChannel))
|
||||
throw new InvalidConfigurationException("2 objects share the same image channels: biome-x and biome-z");
|
||||
zoneChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.zone", "blue")).toUpperCase());
|
||||
if(zoneChannel.equals(biomeXChannel) || zoneChannel.equals(biomeZChannel))
|
||||
throw new InvalidConfigurationException("2 objects share the same image channels: zone and biome-x/z");
|
||||
if(fromImage) {
|
||||
try {
|
||||
imageLoader = new ImageLoader(new File(Objects.requireNonNull(config.getString("image.image-location"))), ImageLoader.Align.valueOf(config.getString("image.align", "center").toUpperCase()));
|
||||
Bukkit.getLogger().info("[Terra] Loading world from image.");
|
||||
} catch(IOException | NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
fromImage = false;
|
||||
}
|
||||
}
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new InvalidConfigurationException(e.getCause());
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfigObject;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StructureConfig extends TerraConfigObject {
|
||||
public StructureConfig(File file) throws IOException, InvalidConfigurationException {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InvalidConfigurationException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package com.dfsek.terra.image;
|
||||
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraChunkGenerator;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.WorldConfig;
|
||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -29,17 +31,22 @@ public class DebugFrame extends JFrame implements ActionListener {
|
||||
public void paint(Graphics g) {
|
||||
super.paintComponents(g);
|
||||
for(Player p : Bukkit.getOnlinePlayers()) {
|
||||
int xp = (int) (((double) Math.floorMod(p.getLocation().getBlockX(), x)/x)*getWidth());
|
||||
int zp = (int) (((double) Math.floorMod(p.getLocation().getBlockZ(), z)/z)*getHeight());
|
||||
if(! (p.getWorld().getGenerator() instanceof TerraChunkGenerator)) break;
|
||||
int xp = (int) (((double) Math.floorMod(p.getLocation().getBlockX(), x) / x) * getWidth());
|
||||
int zp = (int) (((double) Math.floorMod(p.getLocation().getBlockZ(), z) / z) * getHeight());
|
||||
if(WorldConfig.fromWorld(p.getWorld()).imageLoader.getAlign().equals(ImageLoader.Align.CENTER)) {
|
||||
xp = (int) (((double) Math.floorMod(p.getLocation().getBlockX() - (img.getWidth() / 2), x) / x) * getWidth());
|
||||
zp = (int) (((double) Math.floorMod(p.getLocation().getBlockZ() - (img.getHeight() / 2), z) / z) * getHeight());
|
||||
}
|
||||
String str = BiomeConfig.fromBiome((UserDefinedBiome) TerraBiomeGrid.fromWorld(p.getWorld()).getBiome(p.getLocation())).getID();
|
||||
g.setColor(new Color(255, 255, 255, 128));
|
||||
g.fillRect(xp+13, zp-13, (int) (8 + 8.25*str.length()), 33);
|
||||
g.fillRect(xp + 13, zp - 13, (int) (8 + 8.25 * str.length()), 33);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString(p.getName(), xp+15, zp);
|
||||
g.drawString(str, xp+15, zp+15);
|
||||
g.drawString(p.getName(), xp + 15, zp);
|
||||
g.drawString(str, xp + 15, zp + 15);
|
||||
g.fillOval(xp, zp, 10, 10);
|
||||
g.setColor(Color.RED);
|
||||
g.fillOval(xp+3, zp+3, 5, 5);
|
||||
g.fillOval(xp + 3, zp + 3, 5, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,20 +18,17 @@ import javax.imageio.ImageIO;
|
||||
|
||||
public class ImageLoader {
|
||||
private final BufferedImage image;
|
||||
private final Align align;
|
||||
double inverseRoot2 = 0.7071067811865475;
|
||||
public ImageLoader(File file) throws IOException {
|
||||
public ImageLoader(File file, Align align) throws IOException {
|
||||
image = ImageIO.read(file);
|
||||
this.align = align;
|
||||
}
|
||||
|
||||
|
||||
public int getChannel(int x, int y, Channel channel) {
|
||||
int rgb;
|
||||
try {
|
||||
rgb = image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(y, image.getHeight()));
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("Index " + x + "/" + x + "out of bounds for size " + image.getWidth() + "/" + image.getHeight());
|
||||
}
|
||||
rgb = align.getRGB(image, x, y);
|
||||
switch(channel) {
|
||||
case RED: return rgb >> 16 & 0xff;
|
||||
case GREEN: return rgb >> 8 & 0xff;
|
||||
@ -63,7 +60,7 @@ public class ImageLoader {
|
||||
public double getNoiseVal(int x, int y, Channel channel) {
|
||||
return ((double) (getChannel(x, y, channel) - 128)/128)*inverseRoot2;
|
||||
}
|
||||
private static BufferedImage copyImage(BufferedImage source){
|
||||
private static BufferedImage copyImage(BufferedImage source) {
|
||||
BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(source, 0, 0, null);
|
||||
@ -71,7 +68,29 @@ public class ImageLoader {
|
||||
return b;
|
||||
}
|
||||
|
||||
public Align getAlign() {
|
||||
return align;
|
||||
}
|
||||
|
||||
public enum Channel {
|
||||
RED, GREEN, BLUE, ALPHA
|
||||
}
|
||||
public enum Align {
|
||||
CENTER {
|
||||
@Override
|
||||
public int getRGB(BufferedImage image, int x, int y) {
|
||||
return Align.getRGBNoAlign(image, x-(image.getWidth()/2), y-(image.getHeight()/2));
|
||||
}
|
||||
},
|
||||
NONE {
|
||||
@Override
|
||||
public int getRGB(BufferedImage image, int x, int y) {
|
||||
return image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(y, image.getHeight()));
|
||||
}
|
||||
};
|
||||
public abstract int getRGB(BufferedImage image, int x, int y);
|
||||
private static int getRGBNoAlign(BufferedImage image, int x, int y) {
|
||||
return image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(y, image.getHeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
src/main/java/com/dfsek/terra/structure/GaeaStructure.java
Normal file
90
src/main/java/com/dfsek/terra/structure/GaeaStructure.java
Normal file
@ -0,0 +1,90 @@
|
||||
package com.dfsek.terra.structure;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class GaeaStructure implements Serializable {
|
||||
public static final long serialVersionUID = -6664585217063842034L;
|
||||
private final StructureContainedBlock[][][] structure;
|
||||
|
||||
public static GaeaStructure load(File f) throws IOException {
|
||||
try {
|
||||
return fromFile(f);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException("Provided file does not contain a GaeaStructure.");
|
||||
}
|
||||
}
|
||||
|
||||
public GaeaStructure(Location l1, Location l2) {
|
||||
if(l1.getX() > l2.getX() || l1.getY() > l2.getY() || l1.getZ() > l2.getZ()) throw new IllegalArgumentException("Invalid locations provided!");
|
||||
structure = new StructureContainedBlock[l2.getBlockX()-l1.getBlockX()+1][l2.getBlockY()-l1.getBlockY()+1][l2.getBlockZ()-l1.getBlockZ()+1];
|
||||
for(int x = 0; x <= l2.getBlockX()-l1.getBlockX(); x++) {
|
||||
for(int y = 0; y <= l2.getBlockY()-l1.getBlockY(); y++) {
|
||||
for(int z = 0; z <= l2.getBlockZ()-l1.getBlockZ(); z++) {
|
||||
structure[x][y][z] = new StructureContainedBlock(x, y, z, Objects.requireNonNull(l1.getWorld()).getBlockAt(l1.clone().add(x, y, z)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paste(Location origin) {
|
||||
for(StructureContainedBlock[][] bList2 : structure) {
|
||||
for(StructureContainedBlock[] bList1 : bList2) {
|
||||
for(StructureContainedBlock block : bList1) {
|
||||
BlockData data = block.getBlockData();
|
||||
Block worldBlock = origin.clone().add(block.getX(), block.getY(), block.getZ()).getBlock();
|
||||
if(!data.getMaterial().equals(Material.STRUCTURE_VOID)) worldBlock.setBlockData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paste(Location origin, Chunk c) {
|
||||
for(StructureContainedBlock[][] bList2 : structure) {
|
||||
for(StructureContainedBlock[] bList1 : bList2) {
|
||||
for(StructureContainedBlock block : bList1) {
|
||||
Location newLoc = origin.clone().add(block.getX(), block.getY(), block.getZ());
|
||||
BlockData data = block.getBlockData();
|
||||
if(newLoc.getChunk().equals(c) && !data.getMaterial().equals(Material.STRUCTURE_VOID)) newLoc.getBlock().setBlockData(block.getBlockData());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save(File f) throws IOException {
|
||||
toFile(this, f);
|
||||
}
|
||||
|
||||
private static GaeaStructure fromFile(File f) throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
|
||||
Object o = ois.readObject();
|
||||
ois.close();
|
||||
return (GaeaStructure) o;
|
||||
}
|
||||
|
||||
public static GaeaStructure fromStream(InputStream f) throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream ois = new ObjectInputStream(f);
|
||||
Object o = ois.readObject();
|
||||
ois.close();
|
||||
return (GaeaStructure) o;
|
||||
}
|
||||
|
||||
private static void toFile(Serializable o, File f) throws IOException {
|
||||
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
|
||||
oos.writeObject(o);
|
||||
oos.close();
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.dfsek.terra.structure;
|
||||
|
||||
public class MultiPartStructure {
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.dfsek.terra.structure;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class StructureContainedBlock implements Serializable {
|
||||
public static final long serialVersionUID = 6143969483382710947L;
|
||||
private final transient BlockData bl;
|
||||
private final String dataString;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
public StructureContainedBlock(int x, int y, int z, Block block) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.bl = block.getBlockData();
|
||||
dataString = bl.getAsString(false);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public BlockData getBlockData() {
|
||||
return bl == null ? Bukkit.createBlockData(dataString) : bl;
|
||||
}
|
||||
|
||||
public String getDataAsString() {
|
||||
return dataString;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ main: com.dfsek.terra.Terra
|
||||
version: 1.0.0
|
||||
load: STARTUP
|
||||
api-version: "1.15"
|
||||
softdepend: ["WorldEdit"]
|
||||
commands:
|
||||
terra:
|
||||
description: Terra base command
|
||||
|
@ -24,4 +24,14 @@ terra {
|
||||
step;
|
||||
}
|
||||
}
|
||||
structure {
|
||||
export {
|
||||
structure brigadier:string single_word;
|
||||
}
|
||||
load {
|
||||
structure brigadier:string single_word {
|
||||
respect_chunk brigadier:bool;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user