diff --git a/api/src/main/java/net/thenextlvl/gopaint/api/brush/setting/PlayerBrushSettings.java b/api/src/main/java/net/thenextlvl/gopaint/api/brush/setting/PlayerBrushSettings.java index 432e6baf..6ebbfaf9 100644 --- a/api/src/main/java/net/thenextlvl/gopaint/api/brush/setting/PlayerBrushSettings.java +++ b/api/src/main/java/net/thenextlvl/gopaint/api/brush/setting/PlayerBrushSettings.java @@ -43,8 +43,9 @@ public interface PlayerBrushSettings extends BrushSettings { * Exports the brush settings visually onto the given ItemStack. * * @param itemStack The ItemStack to export the brush settings to. + * @return whether the settings could be exported to the item */ - void exportSettings(ItemStack itemStack); + boolean exportSettings(ItemStack itemStack); /** * Imports the item brush settings. diff --git a/build.gradle.kts b/build.gradle.kts index 3c340fdb..fee3c9cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,6 +40,7 @@ paper { main = "net.thenextlvl.gopaint.GoPaintPlugin" authors = listOf("Arcaniax", "TheMeinerLP", "NonSwag") apiVersion = "1.20" + foliaSupported = true serverDependencies { register("FastAsyncWorldEdit") { diff --git a/src/main/java/net/thenextlvl/gopaint/brush/CraftBrushRegistry.java b/src/main/java/net/thenextlvl/gopaint/brush/CraftBrushRegistry.java index 9a380c55..248f75aa 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/CraftBrushRegistry.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/CraftBrushRegistry.java @@ -19,7 +19,7 @@ public CraftBrushRegistry(GoPaintPlugin plugin) { registerBrush(new SphereBrush(plugin)); registerBrush(new SprayBrush(plugin)); registerBrush(new SplatterBrush(plugin)); - registerBrush(new DiscBrush(plugin)); + registerBrush(new DiskBrush(plugin)); registerBrush(new BucketBrush(plugin)); registerBrush(new AngleBrush(plugin)); registerBrush(new OverlayBrush(plugin)); diff --git a/src/main/java/net/thenextlvl/gopaint/brush/pattern/SplatterPattern.java b/src/main/java/net/thenextlvl/gopaint/brush/pattern/SplatterPattern.java index d7dacb38..ca87de7c 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/pattern/SplatterPattern.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/pattern/SplatterPattern.java @@ -22,8 +22,8 @@ public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws W } private double getRate(BlockVector3 position) { - var size = (double) settings().getBrushSize(); - var falloff = (100.0 - (double) settings().getFalloffStrength()) / 100.0; + var size = settings().getBrushSize() / 2; + var falloff = (100 - settings().getFalloffStrength()) / 100d; return (position.distance(position()) - size * falloff) / (size - size * falloff); } } diff --git a/src/main/java/net/thenextlvl/gopaint/brush/pattern/SprayPattern.java b/src/main/java/net/thenextlvl/gopaint/brush/pattern/SprayPattern.java index 54cec33a..1dd9781f 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/pattern/SprayPattern.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/pattern/SprayPattern.java @@ -17,7 +17,7 @@ public record SprayPattern( @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - if (settings.getRandom().nextInt(100) < settings.getChance()) return false; + if (settings.getRandom().nextInt(100) >= settings.getChance()) return false; return set.setBlock(extent, getRandomBlockState()); } } diff --git a/src/main/java/net/thenextlvl/gopaint/brush/setting/CraftPlayerBrushSettings.java b/src/main/java/net/thenextlvl/gopaint/brush/setting/CraftPlayerBrushSettings.java index a3c3b2df..dbc0db82 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/setting/CraftPlayerBrushSettings.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/setting/CraftPlayerBrushSettings.java @@ -234,58 +234,59 @@ public PatternBrush getPreviousBrush(@Nullable PatternBrush brush) { } @Override - public void exportSettings(ItemStack itemStack) { - var lore = new ArrayList(); - lore.add(Component.empty()); - lore.add(plugin.bundle().component(player, "brush.exported.size", - Placeholder.parsed("size", String.valueOf(getBrushSize())))); - if (getBrush() instanceof SprayBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.chance", - Placeholder.parsed("chance", String.valueOf(getChance())))); - } else if (getBrush() instanceof OverlayBrush || getBrush() instanceof UnderlayBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.thickness", - Placeholder.parsed("thickness", String.valueOf(getThickness())))); - } else if (getBrush() instanceof DiscBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.axis", - Placeholder.parsed("axis", getAxis().name()))); - } else if (getBrush() instanceof AngleBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.angle.distance", - Placeholder.parsed("distance", String.valueOf(getAngleDistance())))); - lore.add(plugin.bundle().component(player, "brush.exported.angle.height", - Placeholder.parsed("height", String.valueOf(getAngleHeightDifference())))); - } else if (getBrush() instanceof SplatterBrush || getBrush() instanceof PaintBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.falloff", - Placeholder.parsed("falloff", String.valueOf(getFalloffStrength())))); - } else if (getBrush() instanceof GradientBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.mixing", - Placeholder.parsed("mixing", String.valueOf(getMixingStrength())))); - lore.add(plugin.bundle().component(player, "brush.exported.falloff", - Placeholder.parsed("falloff", String.valueOf(getFalloffStrength())))); - } else if (getBrush() instanceof FractureBrush) { - lore.add(plugin.bundle().component(player, "brush.exported.fracture", - Placeholder.parsed("fracture", String.valueOf(getFractureStrength())))); - } - if (!blocks.isEmpty()) { - var blocks = getBlocks().stream() - .map(Material::translationKey) - .map(Component::translatable) - .toList(); - lore.add(plugin.bundle().component(player, "brush.exported.blocks", - Placeholder.component("blocks", Component.join(JoinConfiguration.commas(true), blocks)))); - } - - if (isMaskEnabled()) { - lore.add(plugin.bundle().component(player, "brush.exported.mask", - Placeholder.component("mask", Component.translatable(getMask().translationKey())))); - } - - if (!getSurfaceMode().equals(SurfaceMode.DISABLED)) { - var mode = plugin.bundle().component(player, getSurfaceMode().translationKey()); - lore.add(plugin.bundle().component(player, "brush.exported.surface-mode", - Placeholder.component("mode", mode))); - } - - itemStack.editMeta(itemMeta -> { + public boolean exportSettings(ItemStack itemStack) { + if (itemStack.getType().equals(plugin.config().brushConfig().defaultBrushType())) return false; + return !itemStack.getType().isBlock() && itemStack.editMeta(itemMeta -> { + var lore = new ArrayList(); + lore.add(Component.empty()); + lore.add(plugin.bundle().component(player, "brush.exported.size", + Placeholder.parsed("size", String.valueOf(getBrushSize())))); + if (getBrush() instanceof SprayBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.chance", + Placeholder.parsed("chance", String.valueOf(getChance())))); + } else if (getBrush() instanceof OverlayBrush || getBrush() instanceof UnderlayBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.thickness", + Placeholder.parsed("thickness", String.valueOf(getThickness())))); + } else if (getBrush() instanceof DiskBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.axis", + Placeholder.parsed("axis", getAxis().name()))); + } else if (getBrush() instanceof AngleBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.angle.distance", + Placeholder.parsed("distance", String.valueOf(getAngleDistance())))); + lore.add(plugin.bundle().component(player, "brush.exported.angle.height", + Placeholder.parsed("height", String.valueOf(getAngleHeightDifference())))); + } else if (getBrush() instanceof SplatterBrush || getBrush() instanceof PaintBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.falloff", + Placeholder.parsed("falloff", String.valueOf(getFalloffStrength())))); + } else if (getBrush() instanceof GradientBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.mixing", + Placeholder.parsed("mixing", String.valueOf(getMixingStrength())))); + lore.add(plugin.bundle().component(player, "brush.exported.falloff", + Placeholder.parsed("falloff", String.valueOf(getFalloffStrength())))); + } else if (getBrush() instanceof FractureBrush) { + lore.add(plugin.bundle().component(player, "brush.exported.fracture", + Placeholder.parsed("fracture", String.valueOf(getFractureStrength())))); + } + if (!blocks.isEmpty()) { + var blocks = getBlocks().stream() + .map(Material::translationKey) + .map(Component::translatable) + .toList(); + lore.add(plugin.bundle().component(player, "brush.exported.blocks", + Placeholder.component("blocks", Component.join(JoinConfiguration.commas(true), blocks)))); + } + + if (isMaskEnabled()) { + lore.add(plugin.bundle().component(player, "brush.exported.mask", + Placeholder.component("mask", Component.translatable(getMask().translationKey())))); + } + + if (!getSurfaceMode().equals(SurfaceMode.DISABLED)) { + var mode = plugin.bundle().component(player, getSurfaceMode().translationKey()); + lore.add(plugin.bundle().component(player, "brush.exported.surface-mode", + Placeholder.component("mode", mode))); + } + itemMeta.itemName(plugin.bundle().component(player, "brush.exported.name", Placeholder.component("brush", getBrush().getName(player)))); itemMeta.lore(lore); diff --git a/src/main/java/net/thenextlvl/gopaint/brush/standard/DiscBrush.java b/src/main/java/net/thenextlvl/gopaint/brush/standard/DiskBrush.java similarity index 94% rename from src/main/java/net/thenextlvl/gopaint/brush/standard/DiscBrush.java rename to src/main/java/net/thenextlvl/gopaint/brush/standard/DiskBrush.java index d68d67a0..ec3bf9a2 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/standard/DiscBrush.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/standard/DiskBrush.java @@ -32,25 +32,25 @@ import net.thenextlvl.gopaint.brush.pattern.ShufflePattern; import org.bukkit.NamespacedKey; -public class DiscBrush extends PatternBrush { +public class DiskBrush extends PatternBrush { private final GoPaintProvider provider; - public DiscBrush(GoPaintProvider provider) { + public DiskBrush(GoPaintProvider provider) { super( "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjFmMjgyNTBkMWU0MjBhNjUxMWIwMzk2NDg2OGZjYTJmNTYzN2UzYWJhNzlmNGExNjNmNGE4ZDYxM2JlIn19fQ==", - new NamespacedKey("gopaint", "disc_brush") + new NamespacedKey("gopaint", "disk_brush") ); this.provider = provider; } @Override public Component getName(Audience audience) { - return provider.bundle().component(audience, "brush.name.disc"); + return provider.bundle().component(audience, "brush.name.disk"); } @Override public Component[] getDescription(Audience audience) { - return provider.bundle().components(audience, "brush.description.disc"); + return provider.bundle().components(audience, "brush.description.disk"); } @Override diff --git a/src/main/java/net/thenextlvl/gopaint/brush/standard/UnderlayBrush.java b/src/main/java/net/thenextlvl/gopaint/brush/standard/UnderlayBrush.java index 5e8237d2..7e6bad63 100644 --- a/src/main/java/net/thenextlvl/gopaint/brush/standard/UnderlayBrush.java +++ b/src/main/java/net/thenextlvl/gopaint/brush/standard/UnderlayBrush.java @@ -17,7 +17,7 @@ public class UnderlayBrush extends SpherePatternBrush { public UnderlayBrush(GoPaintProvider provider) { super( - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzIzNDQ2OTkwZjU4YjY1M2FiNWYwZTdhZjNmZGM3NTYwOTEyNzVmNGMzYzJkZDQxYzdkODYyZGQzZjkyZTg0YSJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzFlNTY1YzFlMDVhODIzZDgxNjMwMjY4N2E5OGQ1ZmUyZDA2NmFhMTkxNDMzNjg4NDRhMGM0MzAyNzYyNDljMyJ9fX0=", new NamespacedKey("gopaint", "underlay_brush") ); this.provider = provider; diff --git a/src/main/java/net/thenextlvl/gopaint/command/GoPaintCommand.java b/src/main/java/net/thenextlvl/gopaint/command/GoPaintCommand.java index f5929321..c44086ed 100644 --- a/src/main/java/net/thenextlvl/gopaint/command/GoPaintCommand.java +++ b/src/main/java/net/thenextlvl/gopaint/command/GoPaintCommand.java @@ -3,6 +3,7 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.context.CommandContext; +import core.paper.item.ItemBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; import io.papermc.paper.command.brigadier.argument.ArgumentTypes; @@ -44,6 +45,15 @@ public void register() { }) .requires(stack -> stack.getSender() instanceof Player) .executes(this::brush))) + .then(Commands.literal("wand") + .requires(stack -> stack.getSender() instanceof Player) + .executes(this::wand)) + .then(Commands.literal("export") + .requires(stack -> stack.getSender() instanceof Player) + .executes(this::exportSettings)) + .then(Commands.literal("import") + .requires(stack -> stack.getSender() instanceof Player) + .executes(this::importSettings)) .then(Commands.literal("toggle") .requires(stack -> stack.getSender() instanceof Player) .executes(this::toggle)) @@ -55,6 +65,33 @@ public void register() { event.registrar().register(command, List.of("gp")))); } + private int exportSettings(CommandContext context) { + var player = (Player) context.getSource().getSender(); + + var mainHand = player.getInventory().getItemInMainHand(); + var settings = plugin.brushController().getBrushSettings(player); + + plugin.bundle().sendMessage(player, settings.exportSettings(mainHand) ? + "command.gopaint.export.success" : "command.gopaint.export.failed"); + + return Command.SINGLE_SUCCESS; + } + + private int importSettings(CommandContext context) { + var player = (Player) context.getSource().getSender(); + + var mainHand = player.getInventory().getItemInMainHand(); + var settings = plugin.brushController().getBrushSettings(player); + var parsed = plugin.brushController().parseBrushSettings(mainHand); + + parsed.ifPresent(settings::importSettings); + + plugin.bundle().sendMessage(player, parsed.isPresent() ? + "command.gopaint.import.success" : "command.gopaint.import.failed"); + + return Command.SINGLE_SUCCESS; + } + private int brush(CommandContext context) { var player = (Player) context.getSource().getSender(); var settings = plugin.brushController().getBrushSettings(player); @@ -100,4 +137,47 @@ private int reload(CommandContext context) { plugin.bundle().sendMessage(sender, "command.gopaint.reloaded"); return Command.SINGLE_SUCCESS; } + + private int wand(CommandContext context) { + var player = (Player) context.getSource().getSender(); + plugin.bundle().sendMessage(player, giveWand(player) + ? "command.gopaint.wand.success" + : "command.gopaint.wand.failed"); + return Command.SINGLE_SUCCESS; + } + + private boolean giveWand(Player player) { + var type = plugin.config().brushConfig().defaultBrushType(); + + var inventory = player.getInventory(); + var first = inventory.first(type); + + if (first != -1) { + if (inventory.getHeldItemSlot() == first) return true; + + if (first >= 0 && first <= 8) { + inventory.setHeldItemSlot(first); + return true; + } + + var item = inventory.getItem(first); + + inventory.setItem(first, inventory.getItemInMainHand()); + inventory.setItemInMainHand(item); + + return true; + } + + if (inventory.getItemInMainHand().isEmpty()) { + inventory.setItemInMainHand(new ItemBuilder(type)); + return true; + } + + var empty = inventory.firstEmpty(); + if (empty == -1) return false; + + inventory.setItem(empty, inventory.getItemInMainHand()); + inventory.setItemInMainHand(new ItemBuilder(type)); + return true; + } } diff --git a/src/main/java/net/thenextlvl/gopaint/listener/InventoryListener.java b/src/main/java/net/thenextlvl/gopaint/listener/InventoryListener.java index c46253ad..3cd7408c 100644 --- a/src/main/java/net/thenextlvl/gopaint/listener/InventoryListener.java +++ b/src/main/java/net/thenextlvl/gopaint/listener/InventoryListener.java @@ -66,10 +66,7 @@ public void menuClick(InventoryClickEvent event) { plugin.brushController().parseBrushSettings(event.getCursor()) - .ifPresentOrElse(settings::importSettings, () -> { - if (itemType.equals(plugin.config().brushConfig().defaultBrushType())) return; - if (!itemType.isBlock()) settings.exportSettings(event.getCursor()); - }); + .ifPresentOrElse(settings::importSettings, () -> settings.exportSettings(event.getCursor())); } else if (event.getRawSlot() == 11 || event.getRawSlot() == 2 || event.getRawSlot() == 20) { if (event.getClick().equals(ClickType.LEFT)) { @@ -112,7 +109,7 @@ public void menuClick(InventoryClickEvent event) { } else if (event.getClick().isRightClick()) { settings.setFalloffStrength(settings.getFalloffStrength() - 10); } - } else if (brush instanceof DiscBrush) { + } else if (brush instanceof DiskBrush) { settings.setAxis(switch (settings.getAxis()) { case X -> Axis.Y; case Y -> Axis.Z; diff --git a/src/main/java/net/thenextlvl/gopaint/menu/MainMenu.java b/src/main/java/net/thenextlvl/gopaint/menu/MainMenu.java index 99a4dad8..de1e0a66 100644 --- a/src/main/java/net/thenextlvl/gopaint/menu/MainMenu.java +++ b/src/main/java/net/thenextlvl/gopaint/menu/MainMenu.java @@ -175,7 +175,7 @@ public void updateThickness() { } public void updateAxis() { - if (!(settings.getBrush() instanceof DiscBrush)) return; + if (!(settings.getBrush() instanceof DiskBrush)) return; inventory.setItem(12, new ItemBuilder(Material.COMPASS) .itemName(plugin.bundle().component(owner, "brush.axis", diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 809439c5..57b65800 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -2,7 +2,13 @@ prefix=goPaint > command.gopaint.brush.disabled= Disabled brush command.gopaint.brush.enabled= Enabled brush command.gopaint.brush.size= Brush size set to: -command.gopaint.reloaded= Reloaded +command.gopaint.reloaded= Reloaded the configuration. +command.gopaint.wand.success= Left click: open menu; Right click: use brush +command.gopaint.wand.failed= Your inventory is full. +command.gopaint.export.success= Exported current brush to your item. +command.gopaint.export.failed= Failed to export current brush to your item. +command.gopaint.import.success= Imported settings from your current item. +command.gopaint.import.failed= Found no brush settings on your current item. brush.block.sight= There is no block in sight. brush.disabled= Your brush is disabled, left click to enable the brush or type /gp toggle. brush.paint.point.set= Paint brush point # set. @@ -112,8 +118,8 @@ brush.description.bucket=\ \ Paints connected blocks\ with the same block type -brush.name.disc=Disc Brush -brush.description.disc=\ +brush.name.disk=Disk Brush +brush.description.disk=\ Click to select\ \ Paints blocks in the\ diff --git a/src/main/resources/messages_german.properties b/src/main/resources/messages_german.properties index 498468db..5b010d7f 100644 --- a/src/main/resources/messages_german.properties +++ b/src/main/resources/messages_german.properties @@ -1,7 +1,13 @@ command.gopaint.brush.disabled= Der Pinsel wurde deaktiviert command.gopaint.brush.enabled= Der Pinsel wurde aktiviert command.gopaint.brush.size= Die Pinselgröße wurde geändert: -command.gopaint.reloaded= Die Konfiguration wurde neu geladen +command.gopaint.reloaded= Die Konfiguration wurde neu geladen. +command.gopaint.wand.success= Linksklick: Öffne Menü; Rechtsklick: Benutze Pinsel +command.gopaint.wand.failed= Dein Inventar ist voll. +command.gopaint.export.success= Der aktuelle Pinsel wurde auf dein Item exportiert. +command.gopaint.export.failed= Der aktuelle Pinsel konnte nicht auf dein Item exportiert werden. +command.gopaint.import.success= Die Einstellungen wurden von deinem Item importiert. +command.gopaint.import.failed= Es konnten keine Einstellungen auf deinem Item gefunden werden. brush.block.sight= Es ist kein Block in Sicht. brush.disabled= Dein Pinsel ist deaktiviert, linksklick um den Pinsel zu aktivieren oder nutze /gp toggle. brush.paint.point.set= Der Pinselstrich # wurde gesetzt. @@ -110,8 +116,8 @@ brush.description.bucket=\ \ Malt verbundene Blöcke\ mit demselben Blocktyp -brush.name.disc=Scheibenpinsel -brush.description.disc=\ +brush.name.disk=Scheibenpinsel +brush.description.disk=\ Klicke zum Auswählen\ \ Malt Blöcke auf der\