cleanup and introducing plugin structure
This commit is contained in:
parent
0103a654c3
commit
ddbe59a5ac
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@ -3,6 +3,7 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/PixelPic.main.iml" filepath="$PROJECT_DIR$/.idea/modules/PixelPic.main.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
4
.idea/modules/PixelPic.main.iml
generated
4
.idea/modules/PixelPic.main.iml
generated
@ -11,4 +11,8 @@
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
14
.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml
generated
Normal file
14
.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>PAPER</platformType>
|
||||
<platformType>ADVENTURE</platformType>
|
||||
</autoDetectTypes>
|
||||
<projectReimportVersion>1</projectReimportVersion>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
</module>
|
@ -1,6 +1,5 @@
|
||||
package eu.mhsl.minecraft.pixelpic;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.map.MapCanvas;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
@ -10,23 +9,19 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageMapRenderer extends MapRenderer {
|
||||
public final int IMAGE_SIZE = 128;
|
||||
|
||||
private BufferedImage image;
|
||||
private final int x;
|
||||
private final int y;
|
||||
public static final int IMAGE_SIZE = 128;
|
||||
private final BufferedImage image;
|
||||
private boolean alreadyRendered = false;
|
||||
|
||||
public ImageMapRenderer(BufferedImage image) {
|
||||
this(image, 0, 0);
|
||||
}
|
||||
|
||||
public ImageMapRenderer(BufferedImage image, int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
recalculateInput(image);
|
||||
this.image = recalculateInput(image, x, y);
|
||||
}
|
||||
|
||||
public void recalculateInput(BufferedImage input) {
|
||||
public static BufferedImage recalculateInput(BufferedImage input, int x, int y) {
|
||||
if (x * IMAGE_SIZE > input.getWidth() || y * IMAGE_SIZE > input.getHeight())
|
||||
throw new RuntimeException(String.format("Input image mus match a multiple of x and y with %d", IMAGE_SIZE));
|
||||
|
||||
@ -37,14 +32,15 @@ public class ImageMapRenderer extends MapRenderer {
|
||||
int y2 = (int) (double) Math.min(input.getHeight(), ((y + 1) * IMAGE_SIZE));
|
||||
|
||||
if (x2 - x1 <= 0 || y2 - y1 <= 0)
|
||||
return;
|
||||
throw new RuntimeException("Invalid Image dimensions!");
|
||||
|
||||
this.image = input.getSubimage(x1, y1, x2 - x1, y2 - y1);
|
||||
return input.getSubimage(x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@NotNull MapView map, @NotNull MapCanvas canvas, @NotNull Player player) {
|
||||
if(image == null) return;
|
||||
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> canvas.drawImage(0, 0, image), 2L);
|
||||
if(this.alreadyRendered) return;
|
||||
canvas.drawImage(0, 0, this.image);
|
||||
this.alreadyRendered = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,120 +1,83 @@
|
||||
package eu.mhsl.minecraft.pixelpic;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpic.commands.PixelPicCommand;
|
||||
import eu.mhsl.minecraft.pixelpic.render.render.DefaultScreenRenderer;
|
||||
import eu.mhsl.minecraft.pixelpic.render.render.Renderer;
|
||||
import eu.mhsl.minecraft.pixelpic.render.render.Resolution;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
||||
public final class Main extends JavaPlugin {
|
||||
private static Main instance;
|
||||
private Renderer screenRenderer;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
this.instance = this;
|
||||
this.screenRenderer = new DefaultScreenRenderer();
|
||||
Bukkit.getPluginCommand("test").setExecutor((sender, command, label, args) -> {
|
||||
if(!(sender instanceof Player player)) return false;
|
||||
|
||||
Resolution.Pixels pixels = Resolution.Pixels._128P;
|
||||
Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
|
||||
Resolution resolution = new Resolution(pixels, aspectRatio);
|
||||
BufferedImage image = screenRenderer.render((Player) sender, resolution);
|
||||
Bukkit.broadcast(Component.text(image.toString()));
|
||||
|
||||
File file = new File(getDataFolder(), "Bild" + ".png");
|
||||
try {
|
||||
getDataFolder().mkdir();
|
||||
ImageIO.write(image, "png", file);
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta = (MapMeta) map.getItemMeta();
|
||||
|
||||
MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView.addRenderer(new ImageMapRenderer(image));
|
||||
|
||||
meta.setMapView(mapView);
|
||||
map.setItemMeta(meta);
|
||||
|
||||
player.getInventory().addItem(map);
|
||||
player.updateInventory();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
Bukkit.getPluginCommand("test2").setExecutor((sender, command, label, args) -> {
|
||||
if(!(sender instanceof Player player)) return false;
|
||||
Bukkit.broadcast(Component.text("HI"));
|
||||
|
||||
Resolution.Pixels pixels = Resolution.Pixels._256P;
|
||||
Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
|
||||
Resolution resolution = new Resolution(pixels, aspectRatio);
|
||||
BufferedImage image = screenRenderer.render((Player) sender, resolution);
|
||||
Bukkit.broadcast(Component.text(image.toString()));
|
||||
|
||||
File file = new File(getDataFolder(), "Bild" + ".png");
|
||||
try {
|
||||
getDataFolder().mkdir();
|
||||
ImageIO.write(image, "png", file);
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta = (MapMeta) map.getItemMeta();
|
||||
MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView.addRenderer(new ImageMapRenderer(image, 0, 0));
|
||||
meta.setMapView(mapView);
|
||||
map.setItemMeta(meta);
|
||||
player.getInventory().addItem(map);
|
||||
|
||||
ItemStack map2 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta1 = (MapMeta) map2.getItemMeta();
|
||||
MapView mapView4 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView4.addRenderer(new ImageMapRenderer(image, 1, 0));
|
||||
meta1.setMapView(mapView4);
|
||||
map2.setItemMeta(meta1);
|
||||
player.getInventory().addItem(map2);
|
||||
|
||||
ItemStack map3 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta2 = (MapMeta) map3.getItemMeta();
|
||||
MapView mapView3 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView3.addRenderer(new ImageMapRenderer(image, 0, 1));
|
||||
meta2.setMapView(mapView3);
|
||||
map3.setItemMeta(meta2);
|
||||
player.getInventory().addItem(map3);
|
||||
|
||||
ItemStack map4 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta3 = (MapMeta) map4.getItemMeta();
|
||||
MapView mapView2 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView2.addRenderer(new ImageMapRenderer(image, 1, 1));
|
||||
meta3.setMapView(mapView2);
|
||||
map4.setItemMeta(meta3);
|
||||
player.getInventory().addItem(map4);
|
||||
|
||||
player.updateInventory();
|
||||
|
||||
return true;
|
||||
});
|
||||
instance = this;
|
||||
Bukkit.getPluginCommand("pixelPic").setExecutor(new PixelPicCommand());
|
||||
//
|
||||
// Bukkit.getPluginCommand("test2").setExecutor((sender, command, label, args) -> {
|
||||
// if(!(sender instanceof Player player)) return false;
|
||||
// Bukkit.broadcast(Component.text("HI"));
|
||||
//
|
||||
// Resolution.Pixels pixels = Resolution.Pixels._256P;
|
||||
// Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
|
||||
// Resolution resolution = new Resolution(pixels, aspectRatio);
|
||||
// BufferedImage image = screenRenderer.render((Player) sender, resolution);
|
||||
// Bukkit.broadcast(Component.text(image.toString()));
|
||||
//
|
||||
// File file = new File(getDataFolder(), "Bild" + ".png");
|
||||
// try {
|
||||
// getDataFolder().mkdir();
|
||||
// ImageIO.write(image, "png", file);
|
||||
// } catch (Exception e) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
|
||||
// MapMeta meta = (MapMeta) map.getItemMeta();
|
||||
// MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
// mapView.addRenderer(new ImageMapRenderer(image, 0, 0));
|
||||
// meta.setMapView(mapView);
|
||||
// map.setItemMeta(meta);
|
||||
// player.getInventory().addItem(map);
|
||||
//
|
||||
// ItemStack map2 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
// MapMeta meta1 = (MapMeta) map2.getItemMeta();
|
||||
// MapView mapView4 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
// mapView4.addRenderer(new ImageMapRenderer(image, 1, 0));
|
||||
// meta1.setMapView(mapView4);
|
||||
// map2.setItemMeta(meta1);
|
||||
// player.getInventory().addItem(map2);
|
||||
//
|
||||
// ItemStack map3 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
// MapMeta meta2 = (MapMeta) map3.getItemMeta();
|
||||
// MapView mapView3 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
// mapView3.addRenderer(new ImageMapRenderer(image, 0, 1));
|
||||
// meta2.setMapView(mapView3);
|
||||
// map3.setItemMeta(meta2);
|
||||
// player.getInventory().addItem(map3);
|
||||
//
|
||||
// ItemStack map4 = new ItemStack(Material.FILLED_MAP, 1);
|
||||
// MapMeta meta3 = (MapMeta) map4.getItemMeta();
|
||||
// MapView mapView2 = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
// mapView2.addRenderer(new ImageMapRenderer(image, 1, 1));
|
||||
// meta3.setMapView(mapView2);
|
||||
// map4.setItemMeta(meta3);
|
||||
// player.getInventory().addItem(map4);
|
||||
//
|
||||
// player.updateInventory();
|
||||
//
|
||||
// return true;
|
||||
// });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
}
|
||||
|
||||
public Renderer getScreenRenderer() {
|
||||
if(this.screenRenderer == null) this.screenRenderer = new DefaultScreenRenderer();
|
||||
return this.screenRenderer;
|
||||
}
|
||||
|
||||
public static Main getInstance() {
|
||||
|
@ -0,0 +1,56 @@
|
||||
package eu.mhsl.minecraft.pixelpic.commands;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpic.ImageMapRenderer;
|
||||
import eu.mhsl.minecraft.pixelpic.Main;
|
||||
import eu.mhsl.minecraft.pixelpic.render.render.Resolution;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
||||
public class PixelPicCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||
if(!(sender instanceof Player player))
|
||||
throw new IllegalStateException("Dieser Command kann nur von einem Spieler ausgeführt werden!");
|
||||
|
||||
Resolution.Pixels pixels = Resolution.Pixels._128P;
|
||||
Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
|
||||
Resolution resolution = new Resolution(pixels, aspectRatio);
|
||||
|
||||
BufferedImage image = Main.getInstance().getScreenRenderer().render(player, resolution);
|
||||
|
||||
File file = new File(Main.getInstance().getDataFolder(), "Bild" + ".png");
|
||||
try {
|
||||
Main.getInstance().getDataFolder().mkdir();
|
||||
ImageIO.write(image, "png", file);
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta = (MapMeta) map.getItemMeta();
|
||||
|
||||
MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView.getRenderers().forEach(mapView::removeRenderer);
|
||||
mapView.addRenderer(new ImageMapRenderer(image));
|
||||
|
||||
meta.setMapView(mapView);
|
||||
map.setItemMeta(meta);
|
||||
|
||||
player.getInventory().addItem(map);
|
||||
player.updateInventory();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -15,14 +15,20 @@ import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class DefaultRaytracer implements Raytracer {
|
||||
|
||||
private static final int MAX_DISTANCE = 300;
|
||||
private static final int REFLECTION_DEPTH = 10;
|
||||
private final int maxDistance;
|
||||
private final int reflectionDepth;
|
||||
|
||||
private final ModelRegistry textureRegistry;
|
||||
private Block reflectedBlock;
|
||||
|
||||
public DefaultRaytracer() {
|
||||
this(300, 10);
|
||||
}
|
||||
|
||||
public DefaultRaytracer(int maxDistance, int reflectionDepth) {
|
||||
this.maxDistance = maxDistance;
|
||||
this.reflectionDepth = reflectionDepth;
|
||||
|
||||
this.textureRegistry = new DefaultModelRegistry();
|
||||
this.textureRegistry.initialize();
|
||||
|
||||
@ -31,7 +37,7 @@ public class DefaultRaytracer implements Raytracer {
|
||||
|
||||
@Override
|
||||
public int trace(World world, Vector point, Vector direction) {
|
||||
return trace(world, point, direction, REFLECTION_DEPTH);
|
||||
return trace(world, point, direction, reflectionDepth);
|
||||
}
|
||||
|
||||
private int trace(World world, Vector point, Vector direction, int reflectionDepth) {
|
||||
@ -52,19 +58,10 @@ public class DefaultRaytracer implements Raytracer {
|
||||
Material occlusionMaterial = null;
|
||||
BlockData occlusionData = null;
|
||||
|
||||
for (int i = 0; i < MAX_DISTANCE; i++) {
|
||||
if (!iterator.hasNext()) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxDistance; i++) {
|
||||
if (!iterator.hasNext()) break;
|
||||
Block block = iterator.next();
|
||||
if (block == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reflectedBlock != null && reflectedBlock.equals(block)) {
|
||||
continue;
|
||||
}
|
||||
if (reflectedBlock != null && reflectedBlock.equals(block)) continue;
|
||||
reflectedBlock = null;
|
||||
|
||||
Material material = block.getType();
|
||||
@ -75,20 +72,30 @@ public class DefaultRaytracer implements Raytracer {
|
||||
}
|
||||
|
||||
Model textureModel = textureRegistry.getModel(block);
|
||||
Intersection currentIntersection = Intersection.of(MathUtil.toVector(iterator.getIntersectionFace()),
|
||||
i == 0 ? point : iterator.getIntersectionPoint(), direction);
|
||||
Intersection currentIntersection = Intersection.of(
|
||||
MathUtil.toVector(iterator.getIntersectionFace()),
|
||||
i == 0 ? point : iterator.getIntersectionPoint(),
|
||||
direction
|
||||
);
|
||||
Intersection newIntersection = textureModel.intersect(block, currentIntersection);
|
||||
|
||||
if (newIntersection == null) {
|
||||
continue;
|
||||
}
|
||||
if (newIntersection == null) continue;
|
||||
|
||||
int color = newIntersection.getColor();
|
||||
|
||||
if (!reflected && textureModel.getReflectionFactor() > 0 && reflectionDepth > 0 && (color >> 24) != 0) {
|
||||
reflectedBlock = block;
|
||||
reflectionColor = trace(world, newIntersection.getPoint(), MathUtil.reflectVector(point, direction,
|
||||
newIntersection.getPoint(), newIntersection.getNormal()), reflectionDepth - 1);
|
||||
reflectionColor = trace(
|
||||
world,
|
||||
newIntersection.getPoint(),
|
||||
MathUtil.reflectVector(
|
||||
point,
|
||||
direction,
|
||||
newIntersection.getPoint(),
|
||||
newIntersection.getNormal()
|
||||
),
|
||||
reflectionDepth - 1
|
||||
);
|
||||
reflectionFactor = textureModel.getReflectionFactor();
|
||||
reflected = true;
|
||||
}
|
||||
@ -102,9 +109,7 @@ public class DefaultRaytracer implements Raytracer {
|
||||
if (textureModel.isOccluding()) {
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
if (material == occlusionMaterial && data.equals(occlusionData)) {
|
||||
continue;
|
||||
}
|
||||
if (material == occlusionMaterial && data.equals(occlusionData)) continue;
|
||||
|
||||
occlusionMaterial = material;
|
||||
occlusionData = data;
|
||||
@ -113,13 +118,8 @@ public class DefaultRaytracer implements Raytracer {
|
||||
occlusionData = null;
|
||||
}
|
||||
|
||||
if (transparencyStart != null && textureModel.getTransparencyFactor() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((color >> 24) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (transparencyStart != null && textureModel.getTransparencyFactor() > 0) continue;
|
||||
if ((color >> 24) == 0) continue;
|
||||
|
||||
baseColor = color;
|
||||
finalIntersection = newIntersection.getPoint();
|
||||
@ -127,13 +127,22 @@ public class DefaultRaytracer implements Raytracer {
|
||||
}
|
||||
|
||||
if (transparencyStart != null) {
|
||||
baseColor = MathUtil.weightedColorSum(baseColor, transparencyColor, transparencyFactor, (1
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
transparencyColor,
|
||||
transparencyFactor,
|
||||
(1
|
||||
- transparencyFactor)
|
||||
* (1 + transparencyStart.distance(finalIntersection == null ? transparencyStart : finalIntersection)
|
||||
/ 5.0));
|
||||
}
|
||||
if (reflected) {
|
||||
baseColor = MathUtil.weightedColorSum(baseColor, reflectionColor, 1 - reflectionFactor, reflectionFactor);
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
reflectionColor,
|
||||
1 - reflectionFactor,
|
||||
reflectionFactor
|
||||
);
|
||||
}
|
||||
|
||||
return baseColor & 0xFFFFFF;
|
||||
|
@ -5,6 +5,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BlockRaytracer extends BlockIterator {
|
||||
|
||||
@ -32,14 +33,16 @@ public class BlockRaytracer extends BlockIterator {
|
||||
public Vector getIntersectionPoint() {
|
||||
BlockFace lastFace = getIntersectionFace();
|
||||
Vector planeNormal = new Vector(lastFace.getModX(), lastFace.getModY(), lastFace.getModZ());
|
||||
Vector planePoint = lastBlock.getLocation().add(0.5, 0.5, 0.5).toVector()
|
||||
Vector planePoint = lastBlock.getLocation()
|
||||
.add(0.5, 0.5, 0.5)
|
||||
.toVector()
|
||||
.add(planeNormal.clone().multiply(0.5));
|
||||
|
||||
return MathUtil.getLinePlaneIntersection(position, direction, planePoint, planeNormal, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block next() {
|
||||
public @NotNull Block next() {
|
||||
Block currentBlock = super.next();
|
||||
currentFace = lastBlock == null ? BlockFace.SELF : currentBlock.getFace(lastBlock);
|
||||
|
||||
|
@ -3,5 +3,6 @@ version: '1.0-SNAPSHOT'
|
||||
main: eu.mhsl.minecraft.pixelpic.Main
|
||||
api-version: '1.21'
|
||||
commands:
|
||||
test:
|
||||
test2:
|
||||
pixelPic:
|
||||
permission: "pixelpic.use"
|
||||
usage: "pixelpic take"
|
||||
|
Loading…
x
Reference in New Issue
Block a user