Merge pull request #15 from Altitude-Devs/dev/shopcommand
Dev/shopcommand
This commit is contained in:
commit
da367ae179
|
|
@ -106,14 +106,6 @@ bukkit {
|
|||
authors = listOf("destro174")
|
||||
depend = listOf("Vault")
|
||||
|
||||
commands {
|
||||
register("playershop") {
|
||||
description = "This is a test command!"
|
||||
aliases = listOf("shop")
|
||||
permission = "playershops.command.playershop"
|
||||
}
|
||||
}
|
||||
|
||||
permissions {
|
||||
register("playershops.admin") {
|
||||
description = "Admin permission for the ${rootProject.name} plugin."
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.alttd.playershops;
|
||||
|
||||
import com.alttd.playershops.commands.ShopCommand;
|
||||
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||
import com.alttd.playershops.config.Config;
|
||||
import com.alttd.playershops.config.DatabaseConfig;
|
||||
import com.alttd.playershops.config.MessageConfig;
|
||||
|
|
@ -102,7 +102,7 @@ public class PlayerShops extends JavaPlugin {
|
|||
}
|
||||
|
||||
private void registerCommands() {
|
||||
getCommand("playershop").setExecutor(new ShopCommand());
|
||||
PlayerShopCommands.registerCommands();
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
|
|||
|
|
@ -1,97 +0,0 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CheckStockCommand {
|
||||
private int playerX;
|
||||
private int playerZ;
|
||||
private int radius;
|
||||
private int minimumStock = -1;
|
||||
private final PlayerShops plugin;
|
||||
public CheckStockCommand(PlayerShops plugin, Player player, String[] args) {
|
||||
this.plugin = plugin;
|
||||
if (args.length != 2 && args.length != 3) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>Invalid command syntax, use /checkstock <radius> [minimum stock]"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
radius = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>radius has to be a valid number, use /checkstock <radius> [minimum stock]"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (radius > 100 || radius <= 0) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>Please keep the radius between 1 and 100"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
minimumStock = Integer.parseInt(args[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>minium stock has to be a valid number, use /checkstock <radius> [minimum stock]"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
playerX = player.getLocation().getBlockX();
|
||||
playerZ = player.getLocation().getBlockZ();
|
||||
List<Stock> stockList = checkStock();
|
||||
sendStockMessage(player, stockList);
|
||||
}
|
||||
|
||||
private List<Stock> checkStock() {
|
||||
List<PlayerShop> shops = plugin.getShopHandler().getShopsInRadius(playerX, playerZ, radius);
|
||||
if (minimumStock != -1)
|
||||
shops = shops.stream().filter(shop -> shop.getRemainingStock() < minimumStock).collect(Collectors.toList());
|
||||
return shops.stream().map(shop -> {
|
||||
Location signLocation = shop.getSignLocation();
|
||||
return new Stock(shop.getRemainingStock(),
|
||||
signLocation.getBlockX(),
|
||||
signLocation.getBlockY(),
|
||||
signLocation.getBlockZ(),
|
||||
ShopUtil.itemNameComponent(shop.getItemStack()));
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static final String putInConfig = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
||||
private void sendStockMessage(Player player, List<Stock> stockList) {
|
||||
Component component = null;
|
||||
for (Stock stock : stockList) {
|
||||
TagResolver resolver = TagResolver.resolver(
|
||||
Placeholder.component("item_component", stock.itemNameComponent),
|
||||
Placeholder.parsed("x", stock.x + ""),
|
||||
Placeholder.parsed("y", stock.y + ""),
|
||||
Placeholder.parsed("z", stock.z + ""),
|
||||
Placeholder.parsed("amount", stock.stock + "")
|
||||
);
|
||||
if (component == null)
|
||||
component = Util.parseMiniMessage(putInConfig, resolver);
|
||||
else
|
||||
component = component.append(Component.newline()).append(Util.parseMiniMessage(putInConfig, resolver));
|
||||
}
|
||||
if (component == null)
|
||||
if (minimumStock == -1)
|
||||
player.sendMessage(Util.parseMiniMessage("<yellow>No shops found in specified radius.<yellow>"));
|
||||
else
|
||||
player.sendMessage(Util.parseMiniMessage(
|
||||
"<yellow>No shops with less than <minimum_stock> stock found.</yellow>",
|
||||
TagResolver.resolver(Placeholder.parsed("minimum_stock", minimumStock + ""))));
|
||||
else
|
||||
player.sendMessage(component);
|
||||
}
|
||||
|
||||
private record Stock(int stock, int x, int y, int z, Component itemNameComponent) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.alttd.playershops.commands.subcommands.CheckStockCommand;
|
||||
import com.alttd.playershops.commands.subcommands.OpenCommand;
|
||||
import com.alttd.playershops.commands.subcommands.ReloadCommand;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
|
||||
public class PlayerShopCommand extends Command {
|
||||
|
||||
public static final String BASE_PERM = "playershops.command"; // TODO load from config
|
||||
|
||||
// subcommand label -> subcommand
|
||||
private static final Map<String, Subcommand> SUBCOMMANDS = PlayerShopCommands.make(() -> {
|
||||
final Map<Set<String>, Subcommand> commands = new HashMap<>();
|
||||
|
||||
commands.put(Set.of("reload"), new ReloadCommand());
|
||||
commands.put(Set.of("checkstock"), new CheckStockCommand());
|
||||
commands.put(Set.of("open"), new OpenCommand());
|
||||
|
||||
return commands.entrySet().stream()
|
||||
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
});
|
||||
// alias -> subcommand label
|
||||
private static final Map<String, String> ALIASES = PlayerShopCommands.make(() -> {
|
||||
final Map<String, Set<String>> aliases = new HashMap<>();
|
||||
|
||||
aliases.put("reload", Set.of("reloadconfig"));
|
||||
|
||||
return aliases.entrySet().stream()
|
||||
.flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey())))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
});
|
||||
|
||||
public PlayerShopCommand() {
|
||||
super("playershop");
|
||||
this.description = "PlayerShop related commands";
|
||||
this.usageMessage = "/playershop [" + String.join(" | ", SUBCOMMANDS.keySet()) + "]";
|
||||
final List<String> permissions = new ArrayList<>();
|
||||
permissions.add(BASE_PERM);
|
||||
permissions.addAll(SUBCOMMANDS.keySet().stream().map(s -> BASE_PERM + "." + s).toList());
|
||||
this.setPermission(String.join(";", permissions));
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
for (final String perm : permissions) {
|
||||
pluginManager.addPermission(new Permission(perm, PermissionDefault.OP));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean testPermission(final CommandSender sender, final String permission) {
|
||||
if (sender.hasPermission(BASE_PERM + "." + permission)) {
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(Bukkit.permissionMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> tabComplete(
|
||||
final @NotNull CommandSender sender,
|
||||
final @NotNull String alias,
|
||||
final String[] args,
|
||||
final @Nullable Location location
|
||||
) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
return PlayerShopCommands.getListMatchingLast(sender, args, SUBCOMMANDS.keySet(), BASE_PERM);
|
||||
}
|
||||
|
||||
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(
|
||||
final @NotNull CommandSender sender,
|
||||
final @NotNull String commandLabel,
|
||||
final String[] args
|
||||
) {
|
||||
if (!testPermission(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(text("Usage: " + this.usageMessage, RED));
|
||||
return false;
|
||||
}
|
||||
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||
|
||||
if (subCommand == null) {
|
||||
sender.sendMessage(text("Usage: " + this.usageMessage, RED));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!testPermission(sender, subCommand.first())) {
|
||||
return true;
|
||||
}
|
||||
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||
}
|
||||
|
||||
private static @Nullable Pair<String, Subcommand> resolveCommand(String label) {
|
||||
label = label.toLowerCase(Locale.ENGLISH);
|
||||
@Nullable Subcommand subCommand = SUBCOMMANDS.get(label);
|
||||
if (subCommand == null) {
|
||||
final @Nullable String command = ALIASES.get(label);
|
||||
if (command != null) {
|
||||
label = command;
|
||||
subCommand = SUBCOMMANDS.get(command);
|
||||
}
|
||||
}
|
||||
|
||||
if (subCommand != null) {
|
||||
return Pair.of(label, subCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PlayerShopCommands {
|
||||
|
||||
private PlayerShopCommands() {
|
||||
}
|
||||
|
||||
private static final Map<String, Command> COMMANDS = new HashMap<>();
|
||||
static {
|
||||
COMMANDS.put("playershop", new PlayerShopCommand());
|
||||
}
|
||||
|
||||
public static void registerCommands() {
|
||||
COMMANDS.forEach((s, command) -> {
|
||||
Bukkit.getCommandMap().register(s, command.getName(), command);
|
||||
});
|
||||
}
|
||||
|
||||
// Code from Mojang - copyright them | Altered to fit our needs
|
||||
public static List<String> getListMatchingLast(final CommandSender sender, final String[] args, final String basePermission, final String... matches) {
|
||||
return getListMatchingLast(sender, args, Arrays.asList(matches), basePermission);
|
||||
}
|
||||
|
||||
public static boolean matches(final String s, final String s1) {
|
||||
return s1.regionMatches(true, 0, s, 0, s.length());
|
||||
}
|
||||
|
||||
public static List<String> getListMatchingLast(final CommandSender sender, final String[] strings, final Collection<?> collection, final String basePermission) {
|
||||
String last = strings[strings.length - 1];
|
||||
ArrayList<String> results = Lists.newArrayList();
|
||||
|
||||
if (!collection.isEmpty()) {
|
||||
|
||||
for (String s1 : collection.stream().map(Functions.toStringFunction()).toList()) {
|
||||
if (matches(last, s1) && (sender.hasPermission(basePermission + "." + s1))) {
|
||||
results.add(s1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static <T> T make(Supplier<T> factory) {
|
||||
return factory.get();
|
||||
}
|
||||
// end copy stuff
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.gui.HomeGui;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
// expose brig in Galaxy?
|
||||
public class ShopCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) return true;
|
||||
if (args.length == 0) {
|
||||
return true;
|
||||
}
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "reload":
|
||||
PlayerShops.getInstance().reloadConfigs();
|
||||
break;
|
||||
case "open":
|
||||
HomeGui gui = new HomeGui(player.getUniqueId());
|
||||
gui.open();
|
||||
break;
|
||||
case "checkstock":
|
||||
if (!player.hasPermission("playershops.command.playershop.checkstock")) {
|
||||
sender.sendMessage(Util.parseMiniMessage("<red><hover:show_text:'<red>playershops.command.playershop.checkstock'>You do not have permission for this command</hover></red>"));
|
||||
break;
|
||||
}
|
||||
new CheckStockCommand(PlayerShops.getInstance(), player, args);
|
||||
break;
|
||||
default:
|
||||
sender.sendMessage("invalid command useage");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Stream.of("reload", "open")
|
||||
.filter(arg -> arg.startsWith(args[0].toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
19
src/main/java/com/alttd/playershops/commands/Subcommand.java
Normal file
19
src/main/java/com/alttd/playershops/commands/Subcommand.java
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public interface Subcommand {
|
||||
|
||||
boolean execute(CommandSender sender, String subCommand, String[] args);
|
||||
|
||||
default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
package com.alttd.playershops.commands.subcommands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
||||
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import com.destroystokyo.paper.ParticleBuilder;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class CheckStockCommand implements Subcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
return this.doStockCheck(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
// TODO give some default tab completions
|
||||
if (args.length == 1) {
|
||||
return PlayerShopCommands.getListMatchingLast(sender, args, PlayerShopCommand.BASE_PERM + ".checkstock", "help");
|
||||
} else if (args.length == 2) {
|
||||
// return PlayerShopCommands.getListMatchingLast(sender, args, "radius");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private int minimumStock = -1;
|
||||
|
||||
public boolean doStockCheck(final CommandSender sender, final String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(Util.parseMiniMessage("<red>Only players can use this command."));
|
||||
return false;
|
||||
}
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>Invalid command syntax, use /checkstock <radius> [minimum stock]"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int radius;
|
||||
try {
|
||||
radius = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>radius has to be a valid number, use /checkstock <radius> [minimum stock]"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (radius > 100 || radius <= 0) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>Please keep the radius between 1 and 100"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length == 2) {
|
||||
try {
|
||||
minimumStock = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(Util.parseMiniMessage("<red>minimum stock has to be a valid number, use /checkstock <radius> [minimum stock]"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player);
|
||||
sendStockMessage(player, stockList);
|
||||
highlightLowStock(player, stockList);
|
||||
return true;
|
||||
}
|
||||
|
||||
//Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly
|
||||
private void highlightLowStock(Player player, List<Stock> stockList) {
|
||||
ParticleBuilder particleBuilder = new ParticleBuilder(Particle.REDSTONE);
|
||||
particleBuilder.color(255, 255, 255);
|
||||
particleBuilder.receivers(player);
|
||||
particleBuilder.count(3);
|
||||
|
||||
List<Location[]> collect = stockList.stream().map(stock -> {
|
||||
Location centerOfBlock = stock.shopCenter;
|
||||
Location[] cornersOfBlock = new Location[8];
|
||||
cornersOfBlock[0] = centerOfBlock.clone().add(0.5, 0.5, 0.5);
|
||||
cornersOfBlock[1] = centerOfBlock.clone().add(0.5, 0.5, -0.5);
|
||||
cornersOfBlock[2] = centerOfBlock.clone().add(-0.5, 0.5, 0.5);
|
||||
cornersOfBlock[3] = centerOfBlock.clone().add(-0.5, 0.5, -0.5);
|
||||
cornersOfBlock[4] = centerOfBlock.clone().add(0.5, -0.5, 0.5);
|
||||
cornersOfBlock[5] = centerOfBlock.clone().add(0.5, -0.5, -0.5);
|
||||
cornersOfBlock[6] = centerOfBlock.clone().add(-0.5, -0.5, 0.5);
|
||||
cornersOfBlock[7] = centerOfBlock.clone().add(-0.5, -0.5, -0.5);
|
||||
return cornersOfBlock;
|
||||
}).toList();
|
||||
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
new ParticleSpawnTask(collect, particleBuilder).runTaskLater(PlayerShops.getInstance(), i * 10);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ParticleSpawnTask extends BukkitRunnable {
|
||||
|
||||
private final List<Location[]> chestLocations;
|
||||
private final ParticleBuilder particleBuilder;
|
||||
|
||||
public ParticleSpawnTask(List<Location[]> chestLocations, ParticleBuilder particleBuilder) {
|
||||
this.chestLocations = chestLocations;
|
||||
this.particleBuilder = particleBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (Location[] particleLocations : chestLocations) {
|
||||
for (Location location : particleLocations) {
|
||||
particleBuilder.location(location);
|
||||
particleBuilder.spawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//End stolen code
|
||||
|
||||
/**
|
||||
* @param x Coordinate to shopCenter search on
|
||||
* @param z Coordinate to shopCenter search on
|
||||
* @param radius Range to check in
|
||||
* @param caller Player who is checking for stock, can only see the stock from their shops unless they have base_perm.checkstock.bypass
|
||||
* @return A list of Stock that the player is allowed to see
|
||||
*/
|
||||
private List<Stock> checkStock(int x, int z, int radius, Player caller) {
|
||||
List<PlayerShop> shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius);
|
||||
Stream<PlayerShop> playerShopStream = shops.stream();
|
||||
if (minimumStock != -1)
|
||||
playerShopStream = playerShopStream.filter(shop -> shop.getRemainingStock() < minimumStock);
|
||||
if (!caller.hasPermission(PlayerShopCommand.BASE_PERM + ".checkstock.any"))
|
||||
playerShopStream = playerShopStream.filter(shop -> shop.getOwnerUUID().equals(caller.getUniqueId()));
|
||||
return playerShopStream.map(shop -> {
|
||||
Location signLocation = shop.getSignLocation();
|
||||
return new Stock(shop.getRemainingStock(),
|
||||
shop.getShopLocation().toCenterLocation(),
|
||||
signLocation.getBlockX(),
|
||||
signLocation.getBlockY(),
|
||||
signLocation.getBlockZ(),
|
||||
ShopUtil.itemNameComponent(shop.getItemStack()));
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static final String putInConfig = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
||||
private void sendStockMessage(Player player, List<Stock> stockList) {
|
||||
Component component = null;
|
||||
for (Stock stock : stockList) {
|
||||
TagResolver resolver = TagResolver.resolver(
|
||||
Placeholder.component("item_component", stock.itemNameComponent),
|
||||
Placeholder.parsed("x", stock.x + ""),
|
||||
Placeholder.parsed("y", stock.y + ""),
|
||||
Placeholder.parsed("z", stock.z + ""),
|
||||
Placeholder.parsed("amount", stock.stock + "")
|
||||
);
|
||||
if (component == null)
|
||||
component = Util.parseMiniMessage(putInConfig, resolver);
|
||||
else
|
||||
component = component.append(Component.newline()).append(Util.parseMiniMessage(putInConfig, resolver));
|
||||
}
|
||||
if (component == null)
|
||||
if (minimumStock == -1)
|
||||
player.sendMessage(Util.parseMiniMessage("<yellow>No shops that you have permission to view found in specified radius.<yellow>"));
|
||||
else
|
||||
player.sendMessage(Util.parseMiniMessage(
|
||||
"<yellow>No shops with less than <minimum_stock> stock found.</yellow>",
|
||||
TagResolver.resolver(Placeholder.parsed("minimum_stock", minimumStock + ""))));
|
||||
else
|
||||
player.sendMessage(component);
|
||||
}
|
||||
|
||||
private record Stock(int stock, Location shopCenter, int x, int y, int z, Component itemNameComponent) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.alttd.playershops.commands.subcommands;
|
||||
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import com.alttd.playershops.gui.HomeGui;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class OpenCommand implements Subcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(Util.parseMiniMessage("<red>Only players can use this command."));
|
||||
return false;
|
||||
}
|
||||
HomeGui gui = new HomeGui(player.getUniqueId());
|
||||
gui.open();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.alttd.playershops.commands.subcommands;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.commands.Subcommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class ReloadCommand implements Subcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
PlayerShops.getInstance().reloadConfigs();
|
||||
// Todo message when config is reloaded
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,14 +11,10 @@ import com.alttd.playershops.shop.TransactionError;
|
|||
import com.alttd.playershops.utils.Logger;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -26,7 +22,6 @@ import org.bukkit.event.EventHandler;
|
|||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Dedicated class to listen to transactions for shops.
|
||||
|
|
@ -85,7 +80,7 @@ public class TransactionListener extends EventListener {
|
|||
}
|
||||
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
if (event.getPlayer().isSneaking() && player.hasPermission("playershop.shop.check-stock"))
|
||||
if (event.getPlayer().isSneaking() && (player.hasPermission("playershop.shop.check-stock") || playerShop.getOwnerUUID().equals(player.getUniqueId())))
|
||||
giveStockInfo(playerShop, player);
|
||||
else
|
||||
giveInfo(playerShop, player);
|
||||
|
|
@ -116,7 +111,7 @@ public class TransactionListener extends EventListener {
|
|||
switch (playerShop.getType()) {
|
||||
case SELL -> {
|
||||
type = Placeholder.unparsed("type", "Sell");
|
||||
stock = Placeholder.parsed("stock", "" + (playerShop.getRemainingStock() / playerShop.getAmount()));
|
||||
stock = Placeholder.parsed("stock", "" + (playerShop.getRemainingStock()));
|
||||
}
|
||||
case BUY -> {
|
||||
type = Placeholder.unparsed("type", "Buy");
|
||||
|
|
@ -124,7 +119,7 @@ public class TransactionListener extends EventListener {
|
|||
}
|
||||
case GAMBLE -> {
|
||||
type = Placeholder.unparsed("type", "Gamble");
|
||||
stock = Placeholder.parsed("stock", "" + (playerShop.getRemainingStock() / playerShop.getAmount()));
|
||||
stock = Placeholder.parsed("stock", "" + (playerShop.getRemainingStock()));
|
||||
}
|
||||
default -> {
|
||||
type = Placeholder.unparsed("type", "UNKNOWN");
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@ package com.alttd.playershops.shop;
|
|||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.events.*;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.InventoryUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import com.alttd.playershops.utils.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
|
@ -84,8 +81,30 @@ public class PlayerShop {
|
|||
return playerShop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return total amount of purchases left until the shop can't sell/buy anymore
|
||||
*/
|
||||
public int getRemainingStock() {
|
||||
return InventoryUtils.countItems(getInventory(), getItemStack());
|
||||
switch (type) {
|
||||
case SELL -> {
|
||||
int totalItems = InventoryUtils.countItems(getInventory(), getItemStack());
|
||||
if (totalItems == 0 || getAmount() == 0)
|
||||
return 0;
|
||||
return totalItems / getAmount();
|
||||
}
|
||||
case BUY -> {
|
||||
if (balance == 0 || getAmount() == 0)
|
||||
return 0;
|
||||
return (int) (balance / getPrice());
|
||||
}
|
||||
case GAMBLE -> {
|
||||
Logger.warn("Tried to call getRemainingStock on unimplemented GAMBLE type");
|
||||
return 0; //not implemented since gamble shops don't exist yet
|
||||
}
|
||||
default -> {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getRemainingSpace() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user