Initial commit
This commit is contained in:
commit
5dd6cb44e5
51
.gitignore
vendored
Normal file
51
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
.idea
|
||||
run
|
||||
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Eclipse stuff
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
# VSCode stuff
|
||||
.vscode/
|
||||
|
||||
# netbeans
|
||||
nbproject/
|
||||
nbactions.xml
|
||||
|
||||
# we use maven!
|
||||
build.xml
|
||||
|
||||
# maven
|
||||
target/
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# various other potential build files
|
||||
build/
|
||||
bin/
|
||||
dist/
|
||||
manifest.mf
|
||||
|
||||
# Mac filesystem dust
|
||||
.DS_Store/
|
||||
.DS_Store
|
||||
|
||||
# intellij
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
out/
|
||||
|
||||
# Linux temp files
|
||||
*~
|
||||
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
build.bat
|
||||
51
pom.xml
Normal file
51
pom.xml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>VillagerShopUI</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository> <!-- Paper -->
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository> <!-- MiniMessage -->
|
||||
<id>sonatype-oss-snapshots</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository> <!-- Vault -->
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.MilkBowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
20
src/main/java/com/alttd/GUI/GUI.java
Normal file
20
src/main/java/com/alttd/GUI/GUI.java
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
package com.alttd.GUI;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface GUI {
|
||||
HashMap<UUID, GUI> GUIByUUID = new HashMap<>();
|
||||
|
||||
void open(Player player);
|
||||
|
||||
GUIAction getAction(int slot);
|
||||
|
||||
Inventory getInventory();
|
||||
|
||||
Merchant getMerchant();
|
||||
}
|
||||
7
src/main/java/com/alttd/GUI/GUIAction.java
Normal file
7
src/main/java/com/alttd/GUI/GUIAction.java
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package com.alttd.GUI;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface GUIAction {
|
||||
void click(Player player);
|
||||
}
|
||||
50
src/main/java/com/alttd/GUI/GUIInventory.java
Normal file
50
src/main/java/com/alttd/GUI/GUIInventory.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package com.alttd.GUI;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class GUIInventory implements GUI {
|
||||
|
||||
protected final Inventory inventory;
|
||||
protected final HashMap<Integer, GUIAction> actions;
|
||||
|
||||
public GUIInventory(InventoryType type, Component name) {
|
||||
inventory = Bukkit.createInventory(null, type, name);
|
||||
actions = new HashMap<>();
|
||||
}
|
||||
|
||||
public Merchant getMerchant() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void setItem(int slot, ItemStack stack, GUIAction action){
|
||||
inventory.setItem(slot, stack);
|
||||
if (action != null){
|
||||
actions.put(slot, action);
|
||||
}
|
||||
}
|
||||
|
||||
public void setItem(int slot, ItemStack stack){
|
||||
setItem(slot, stack, null);
|
||||
}
|
||||
|
||||
public void open(Player player){
|
||||
player.openInventory(inventory);
|
||||
GUIByUUID.put(player.getUniqueId(), this);
|
||||
}
|
||||
|
||||
public GUIAction getAction(int slot) {
|
||||
return actions.get(slot);
|
||||
}
|
||||
}
|
||||
84
src/main/java/com/alttd/GUI/GUIListener.java
Normal file
84
src/main/java/com/alttd/GUI/GUIListener.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package com.alttd.GUI;
|
||||
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.inventory.TradeSelectEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
|
||||
public class GUIListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onClick(InventoryClickEvent event){
|
||||
if (!(event.getWhoClicked() instanceof Player player)){
|
||||
return;
|
||||
}
|
||||
|
||||
GUI gui = GUI.GUIByUUID.get(player.getUniqueId());
|
||||
if (gui == null || gui.getInventory() == null) {
|
||||
if (event.getSlotType().equals(InventoryType.SlotType.CRAFTING) && event.getRawSlot() < 2)
|
||||
event.setCancelled(true);
|
||||
else if (event.getRawSlot() == 2 && event.getSlotType().equals(InventoryType.SlotType.RESULT)) {
|
||||
event.setCancelled(true);
|
||||
onResultSlotClick(event, gui);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!gui.getInventory().equals(event.getInventory())) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
GUIAction action = gui.getAction(event.getSlot());
|
||||
|
||||
if (action != null){
|
||||
action.click(player);
|
||||
}
|
||||
}
|
||||
|
||||
private void onResultSlotClick(InventoryClickEvent event, GUI gui) {
|
||||
ItemStack currentItem = event.getCurrentItem();
|
||||
if (currentItem == null)
|
||||
return;
|
||||
if (event.getClick().isShiftClick())
|
||||
event.getWhoClicked().sendMessage(MiniMessage.get().parse(currentItem.getType().name() + ": " + event.getCurrentItem().getType().getMaxStackSize()));
|
||||
else
|
||||
event.getWhoClicked().sendMessage(MiniMessage.get().parse(currentItem.getType().name() + ": " + event.getCurrentItem().getAmount()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTradeSelect(TradeSelectEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player player)){
|
||||
return;
|
||||
}
|
||||
|
||||
GUI gui = GUI.GUIByUUID.get(player.getUniqueId());
|
||||
if ((!(gui instanceof GUIMerchant guiMerchant)))
|
||||
return;
|
||||
if (!gui.getMerchant().equals(event.getMerchant())) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
GUIAction action = guiMerchant.getAction(event.getIndex());
|
||||
|
||||
if (action != null){
|
||||
action.click(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onClose(InventoryCloseEvent event) {
|
||||
GUI.GUIByUUID.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event){
|
||||
GUI.GUIByUUID.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
}
|
||||
61
src/main/java/com/alttd/GUI/GUIMerchant.java
Normal file
61
src/main/java/com/alttd/GUI/GUIMerchant.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package com.alttd.GUI;
|
||||
|
||||
import com.alttd.objects.VillagerType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class GUIMerchant implements GUI{
|
||||
|
||||
protected final Merchant merchant;
|
||||
protected final HashMap<Integer, GUIAction> actions;
|
||||
private final VillagerType villagerType;
|
||||
|
||||
public GUIMerchant(Component name, VillagerType villagerType) {
|
||||
merchant = Bukkit.createMerchant(name);
|
||||
actions = new HashMap<>();
|
||||
this.villagerType = villagerType;
|
||||
}
|
||||
|
||||
public Merchant getMerchant() {
|
||||
return merchant;
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addItem(@NotNull ItemStack result, @NotNull ItemStack one, @Nullable ItemStack two, @Nullable GUIAction action){
|
||||
MerchantRecipe merchantRecipe = new MerchantRecipe(result, 0, 10000, false, 0, 0);
|
||||
merchantRecipe.addIngredient(one);
|
||||
if (two != null)
|
||||
merchantRecipe.addIngredient(two);
|
||||
merchantRecipe.setPriceMultiplier(0);
|
||||
ArrayList<MerchantRecipe> recipes = new ArrayList<>(merchant.getRecipes());
|
||||
recipes.add(merchantRecipe);
|
||||
merchant.setRecipes(recipes);
|
||||
|
||||
if (action != null){
|
||||
actions.put(recipes.size() - 1, action);
|
||||
}
|
||||
}
|
||||
|
||||
public void open(Player player){
|
||||
player.openMerchant(merchant, false);
|
||||
GUIByUUID.put(player.getUniqueId(), this);
|
||||
}
|
||||
|
||||
public GUIAction getAction(int slot) {
|
||||
return actions.get(slot);
|
||||
}
|
||||
|
||||
public VillagerType getVillagerType() {
|
||||
return villagerType;
|
||||
}
|
||||
}
|
||||
45
src/main/java/com/alttd/GUI/windows/BuyGUI.java
Normal file
45
src/main/java/com/alttd/GUI/windows/BuyGUI.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package com.alttd.GUI.windows;
|
||||
|
||||
import com.alttd.GUI.GUIMerchant;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.economy.Calculation;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class BuyGUI extends GUIMerchant {
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.get();
|
||||
|
||||
public BuyGUI(VillagerType villagerType) {
|
||||
super(MiniMessage.get().parse(Config.BUY_WINDOW,
|
||||
Template.of("trader", villagerType.getDisplayName()),
|
||||
Template.of("percentage", "100")), villagerType); //TODO get percentage from player somehow
|
||||
for (ItemStack itemStack : villagerType.getBuying()) {
|
||||
double price = Calculation.price(itemStack);
|
||||
addItem(itemStack,
|
||||
getPriceItem(price),
|
||||
null,
|
||||
player -> player.sendMessage(MiniMessage.get().parse("Hi! you bought: " + itemStack.getAmount() + " " + itemStack.getType().name() + " for " + price + "."))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getPriceItem(double price) {
|
||||
if (price < 0) return nameItem(new ItemStack(Material.BARRIER), -1);
|
||||
else if (price <= 10) return nameItem(new ItemStack(Material.IRON_INGOT), price);
|
||||
else if (price <= 100) return nameItem(new ItemStack(Material.GOLD_INGOT), price);
|
||||
else if (price <= 500) return nameItem(new ItemStack(Material.DIAMOND), price);
|
||||
else return nameItem(new ItemStack(Material.NETHERITE_INGOT), price);
|
||||
}
|
||||
|
||||
private ItemStack nameItem(ItemStack itemStack, double price) {
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
itemMeta.displayName(miniMessage.parse("<green>" + price + "</green>")); //TODO configurable
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
return itemStack;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/alttd/GUI/windows/OpenGUI.java
Normal file
40
src/main/java/com/alttd/GUI/windows/OpenGUI.java
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package com.alttd.GUI.windows;
|
||||
|
||||
import com.alttd.GUI.GUIInventory;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class OpenGUI extends GUIInventory {
|
||||
|
||||
private static final ItemStack BUY = new ItemStack(Material.GOLD_INGOT);
|
||||
private static final ItemStack SELL = new ItemStack(Material.BUCKET);
|
||||
|
||||
static {
|
||||
MiniMessage miniMessage = MiniMessage.get();
|
||||
ItemMeta itemMeta;
|
||||
{
|
||||
itemMeta = BUY.getItemMeta();
|
||||
itemMeta.displayName(miniMessage.parse("<green>Buy</green>"));
|
||||
BUY.setItemMeta(itemMeta);
|
||||
}
|
||||
{
|
||||
itemMeta = SELL.getItemMeta();
|
||||
itemMeta.displayName(miniMessage.parse("<green>Sell</green>"));
|
||||
SELL.setItemMeta(itemMeta);
|
||||
}
|
||||
}
|
||||
|
||||
public OpenGUI(VillagerType villagerType) {
|
||||
super(InventoryType.HOPPER, MiniMessage.get().parse(Config.INITIAL_VILLAGER_WINDOW,
|
||||
Template.of("trader", villagerType.getDisplayName()),
|
||||
Template.of("percentage", "100"))); //TODO get percentage from player somehow
|
||||
setItem(1, BUY, player -> new BuyGUI(villagerType).open(player));
|
||||
setItem(3, SELL, player -> new SellGUI(villagerType).open(player));
|
||||
}
|
||||
}
|
||||
45
src/main/java/com/alttd/GUI/windows/SellGUI.java
Normal file
45
src/main/java/com/alttd/GUI/windows/SellGUI.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package com.alttd.GUI.windows;
|
||||
|
||||
import com.alttd.GUI.GUIMerchant;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.economy.Calculation;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class SellGUI extends GUIMerchant {
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.get();
|
||||
|
||||
public SellGUI(VillagerType villagerType) {
|
||||
super(MiniMessage.get().parse(Config.SELL_WINDOW,
|
||||
Template.of("trader", villagerType.getDisplayName()),
|
||||
Template.of("percentage", "100")), villagerType); //TODO get percentage from player somehow
|
||||
for (ItemStack itemStack : villagerType.getSelling()) {
|
||||
double price = Calculation.price(itemStack);
|
||||
addItem(itemStack,
|
||||
getPriceItem(price),
|
||||
null,
|
||||
player -> player.sendMessage(MiniMessage.get().parse("Hi! you sold: " + itemStack.getAmount() + " " + itemStack.getType().name() + " for " + price + "."))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getPriceItem(double price) {
|
||||
if (price < 0) return nameItem(new ItemStack(Material.BARRIER), -1);
|
||||
else if (price <= 10) return nameItem(new ItemStack(Material.IRON_INGOT), price);
|
||||
else if (price <= 100) return nameItem(new ItemStack(Material.GOLD_INGOT), price);
|
||||
else if (price <= 500) return nameItem(new ItemStack(Material.DIAMOND), price);
|
||||
else return nameItem(new ItemStack(Material.NETHERITE_INGOT), price);
|
||||
}
|
||||
|
||||
private ItemStack nameItem(ItemStack itemStack, double price) {
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
itemMeta.displayName(miniMessage.parse("<red>" + price * -1 + "</red>")); //TODO configurable
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
return itemStack;
|
||||
}
|
||||
}
|
||||
41
src/main/java/com/alttd/VillagerUI.java
Normal file
41
src/main/java/com/alttd/VillagerUI.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package com.alttd;
|
||||
|
||||
import com.alttd.GUI.GUIListener;
|
||||
import com.alttd.commands.CommandManager;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.config.VillagerConfig;
|
||||
import com.alttd.config.WorthConfig;
|
||||
import com.alttd.events.VillagerInteract;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class VillagerUI extends JavaPlugin {
|
||||
|
||||
public static VillagerUI instance;
|
||||
|
||||
public static VillagerUI getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
registerEvents();
|
||||
new CommandManager();
|
||||
Config.reload();
|
||||
VillagerConfig.reload();
|
||||
WorthConfig.reload();
|
||||
getLogger().info("--------------------------------------------------");
|
||||
getLogger().info("Villager UI started");
|
||||
getLogger().info("--------------------------------------------------");
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
getServer().getPluginManager().registerEvents(new GUIListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new VillagerInteract(), this);
|
||||
}
|
||||
|
||||
}
|
||||
92
src/main/java/com/alttd/commands/CommandManager.java
Normal file
92
src/main/java/com/alttd/commands/CommandManager.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package com.alttd.commands;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.alttd.commands.subcommands.CommandCreateVillager;
|
||||
import com.alttd.commands.subcommands.CommandHelp;
|
||||
import com.alttd.commands.subcommands.CommandReload;
|
||||
import com.alttd.config.Config;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.command.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandManager implements CommandExecutor, TabExecutor {
|
||||
private final List<SubCommand> subCommands;
|
||||
private final MiniMessage miniMessage;
|
||||
|
||||
public CommandManager() {
|
||||
VillagerUI villagerUI = VillagerUI.getInstance();
|
||||
|
||||
PluginCommand command = villagerUI.getCommand("villagerui");
|
||||
if (command == null) {
|
||||
subCommands = null;
|
||||
miniMessage = null;
|
||||
villagerUI.getLogger().severe("Unable to find villager ui command.");
|
||||
return;
|
||||
}
|
||||
command.setExecutor(this);
|
||||
command.setTabCompleter(this);
|
||||
|
||||
subCommands = Arrays.asList(
|
||||
new CommandHelp(this),
|
||||
new CommandCreateVillager(),
|
||||
new CommandReload());
|
||||
miniMessage = MiniMessage.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String cmd, @NotNull String[] args) {
|
||||
if (args.length == 0) {
|
||||
commandSender.sendMessage(miniMessage.parse(Config.HELP_MESSAGE_WRAPPER, Template.of("commands", subCommands.stream()
|
||||
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
|
||||
.map(SubCommand::getHelpMessage)
|
||||
.collect(Collectors.joining("\n")))));
|
||||
return true;
|
||||
}
|
||||
|
||||
SubCommand subCommand = getSubCommand(args[0]);
|
||||
|
||||
if (!commandSender.hasPermission(subCommand.getPermission())) {
|
||||
commandSender.sendMessage(miniMessage.parse(Config.NO_PERMISSION));
|
||||
return true;
|
||||
}
|
||||
|
||||
return subCommand.onCommand(commandSender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String cmd, @NotNull String[] args) {
|
||||
List<String> res = new ArrayList<>();
|
||||
|
||||
if (args.length <= 1) {
|
||||
res.addAll(subCommands.stream()
|
||||
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
|
||||
.map(SubCommand::getName)
|
||||
.filter(name -> args.length == 0 || name.startsWith(args[0]))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
} else {
|
||||
SubCommand subCommand = getSubCommand(args[0]);
|
||||
if (subCommand != null && commandSender.hasPermission(subCommand.getPermission()))
|
||||
res.addAll(subCommand.getTabComplete(commandSender, args));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<SubCommand> getSubCommands() {
|
||||
return subCommands;
|
||||
}
|
||||
|
||||
private SubCommand getSubCommand(String cmdName) {
|
||||
return subCommands.stream()
|
||||
.filter(subCommand -> subCommand.getName().equals(cmdName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
31
src/main/java/com/alttd/commands/SubCommand.java
Normal file
31
src/main/java/com/alttd/commands/SubCommand.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package com.alttd.commands;
|
||||
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SubCommand {
|
||||
|
||||
private final MiniMessage miniMessage;
|
||||
|
||||
public SubCommand() {
|
||||
miniMessage = MiniMessage.get();
|
||||
}
|
||||
|
||||
public abstract boolean onCommand(CommandSender commandSender, String[] args);
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
public String getPermission() {
|
||||
return "villagerui." + getName();
|
||||
}
|
||||
|
||||
public abstract List<String> getTabComplete(CommandSender commandSender, String[] args);
|
||||
|
||||
public abstract String getHelpMessage();
|
||||
|
||||
protected MiniMessage getMiniMessage() {
|
||||
return miniMessage;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package com.alttd.commands.subcommands;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.alttd.commands.SubCommand;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.config.VillagerConfig;
|
||||
import com.alttd.objects.LoadedVillagers;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import com.alttd.util.Utilities;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandCreateVillager extends SubCommand {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
if (args.length < 8) {
|
||||
commandSender.sendMessage(getMiniMessage().parse(getHelpMessage()));
|
||||
return true;
|
||||
}
|
||||
|
||||
Optional<VillagerType> first = VillagerType.getVillagerTypes().stream().filter(villagerType -> villagerType.getName().equalsIgnoreCase(args[1])).findFirst();
|
||||
if (first.isEmpty()) {
|
||||
commandSender.sendMessage(getMiniMessage().parse(getHelpMessage()));
|
||||
return true;
|
||||
}
|
||||
VillagerType villagerType = first.get();
|
||||
|
||||
World world = Bukkit.getServer().getWorld(args[7]);
|
||||
if (world == null) {
|
||||
commandSender.sendMessage(getMiniMessage().parse(getHelpMessage()));
|
||||
return true;
|
||||
}
|
||||
Location location = new Location(world, Double.parseDouble(args[2]),Double.parseDouble(args[3]),Double.parseDouble(args[4]), Float.parseFloat(args[5]), Float.parseFloat(args[6]));
|
||||
Villager villager = (Villager) world.spawnEntity(location, EntityType.VILLAGER, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
villager.setPersistent(true);
|
||||
villager.setInvulnerable(true);
|
||||
// villager.setVillagerType(Villager.Type.); TODO choose villager type?
|
||||
villager.setRemoveWhenFarAway(false);
|
||||
villager.customName(getMiniMessage().parse(Config.VILLAGER_NAME, Template.of("name", villagerType.getDisplayName())));
|
||||
villager.setCustomNameVisible(true);
|
||||
villager.setAI(false);
|
||||
|
||||
UUID uuid = villager.getUniqueId();
|
||||
|
||||
LoadedVillagers.addLoadedVillager(uuid, villagerType);
|
||||
VillagerConfig.addVillager(uuid, villagerType);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "createvillager";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||
List<String> res = new ArrayList<>();
|
||||
switch (args.length) {
|
||||
case 2 -> res.addAll(VillagerType.getVillagerTypes().stream()
|
||||
.map(VillagerType::getName)
|
||||
.collect(Collectors.toList()));
|
||||
case 3 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(String.valueOf(Utilities.round(player.getLocation().getX(), 2)));
|
||||
}
|
||||
}
|
||||
case 4 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(String.valueOf(Utilities.round(player.getLocation().getY(), 1)));
|
||||
}
|
||||
}
|
||||
case 5 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(String.valueOf(Utilities.round(player.getLocation().getZ(), 2)));
|
||||
}
|
||||
}
|
||||
case 6 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(String.valueOf(Utilities.round(player.getLocation().getYaw(), 2)));
|
||||
}
|
||||
}
|
||||
case 7 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(String.valueOf(Utilities.round(player.getLocation().getPitch(), 2)));
|
||||
}
|
||||
}
|
||||
case 8 -> {
|
||||
if (commandSender instanceof Player player) {
|
||||
res.add(player.getLocation().getWorld().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpMessage() {
|
||||
return Config.CREATE_VILLAGER_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.alttd.commands.subcommands;
|
||||
|
||||
import com.alttd.commands.CommandManager;
|
||||
import com.alttd.commands.SubCommand;
|
||||
import com.alttd.config.Config;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandHelp extends SubCommand {
|
||||
|
||||
private final CommandManager commandManager;
|
||||
|
||||
public CommandHelp(CommandManager commandManager) {
|
||||
super();
|
||||
this.commandManager = commandManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
commandSender.sendMessage(getMiniMessage().parse(Config.HELP_MESSAGE_WRAPPER, Template.of("commands", commandManager.getSubCommands().stream()
|
||||
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
|
||||
.map(SubCommand::getHelpMessage)
|
||||
.collect(Collectors.joining("\n")))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
return "villagerui.use";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpMessage() {
|
||||
return Config.HELP_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.alttd.commands.subcommands;
|
||||
|
||||
import com.alttd.commands.SubCommand;
|
||||
import com.alttd.config.Config;
|
||||
import com.alttd.config.VillagerConfig;
|
||||
import com.alttd.config.WorthConfig;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandReload extends SubCommand {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
Config.reload();
|
||||
VillagerConfig.reload();
|
||||
WorthConfig.reload();
|
||||
commandSender.sendMessage(getMiniMessage().parse("<green>Reloaded VillagerShopUI config.</green>"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpMessage() {
|
||||
return Config.RELOAD_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.alttd.commands.subcommands;
|
||||
|
||||
public class CommandRemoveVillager {
|
||||
}
|
||||
132
src/main/java/com/alttd/config/AbstractConfig.java
Normal file
132
src/main/java/com/alttd/config/AbstractConfig.java
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
package com.alttd.config;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@SuppressWarnings({"unused", "SameParameterValue"})
|
||||
abstract class AbstractConfig {
|
||||
File file;
|
||||
YamlConfiguration yaml;
|
||||
Logger logger;
|
||||
|
||||
AbstractConfig(String filename) {
|
||||
init(new File(VillagerUI.getInstance().getDataFolder(), filename), filename);
|
||||
}
|
||||
|
||||
AbstractConfig(File file, String filename) {
|
||||
init(new File(file.getPath() + File.separator + filename), filename);
|
||||
}
|
||||
|
||||
private void init(File file, String filename) {
|
||||
this.file = file;
|
||||
this.yaml = new YamlConfiguration();
|
||||
this.logger = VillagerUI.getInstance().getLogger();
|
||||
try {
|
||||
yaml.load(file);
|
||||
} catch (IOException ignore) {
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
logger.severe(String.format("Could not load %s, please correct your syntax errors", filename));
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
yaml.options().copyDefaults(true);
|
||||
}
|
||||
|
||||
void readConfig(Class<?> clazz, Object instance) {
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
if (Modifier.isPrivate(method.getModifiers())) {
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
method.invoke(instance);
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
logger.severe("Error invoking " + method);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
private void save() {
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException ex) {
|
||||
logger.severe("Could not save " + file);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void set(String path, Object val) {
|
||||
yaml.addDefault(path, val);
|
||||
yaml.set(path, val);
|
||||
save();
|
||||
}
|
||||
|
||||
String getString(String path, String def) {
|
||||
yaml.addDefault(path, def);
|
||||
return yaml.getString(path, yaml.getString(path));
|
||||
}
|
||||
|
||||
boolean getBoolean(String path, boolean def) {
|
||||
yaml.addDefault(path, def);
|
||||
return yaml.getBoolean(path, yaml.getBoolean(path));
|
||||
}
|
||||
|
||||
int getInt(String path, int def) {
|
||||
yaml.addDefault(path, def);
|
||||
return yaml.getInt(path, yaml.getInt(path));
|
||||
}
|
||||
|
||||
double getDouble(String path, double def) {
|
||||
yaml.addDefault(path, def);
|
||||
return yaml.getDouble(path, yaml.getDouble(path));
|
||||
}
|
||||
|
||||
<T> List<?> getList(String path, T def) {
|
||||
yaml.addDefault(path, def);
|
||||
return yaml.getList(path, yaml.getList(path));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
<T> Map<String, T> getMap(final @NonNull String path, final @Nullable Map<String, T> def) {
|
||||
final ImmutableMap.Builder<String, T> builder = ImmutableMap.builder();
|
||||
if (def != null && yaml.getConfigurationSection(path) == null) {
|
||||
yaml.addDefault(path, def.isEmpty() ? new HashMap<>() : def);
|
||||
return def;
|
||||
}
|
||||
final ConfigurationSection section = yaml.getConfigurationSection(path);
|
||||
if (section != null) {
|
||||
for (String key : section.getKeys(false)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final T val = (T) section.get(key);
|
||||
if (val != null) {
|
||||
builder.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
ConfigurationSection getConfigurationSection(String path) {
|
||||
return yaml.getConfigurationSection(path);
|
||||
}
|
||||
}
|
||||
110
src/main/java/com/alttd/config/Config.java
Normal file
110
src/main/java/com/alttd/config/Config.java
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package com.alttd.config;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class Config extends AbstractConfig {
|
||||
|
||||
static Config config;
|
||||
static int version;
|
||||
|
||||
public Config() {
|
||||
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "VillagerShopUI"), "config.yml");
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
config = new Config();
|
||||
|
||||
version = config.getInt("config-version", 1);
|
||||
config.set("config-version", 1);
|
||||
|
||||
config.readConfig(Config.class, null);
|
||||
}
|
||||
|
||||
public static String INITIAL_VILLAGER_WINDOW = "<trader> price: <percentage>%";
|
||||
public static String BUY_WINDOW = "<trader> price: <percentage>%";
|
||||
public static String SELL_WINDOW = "<trader> price: <percentage>%";
|
||||
|
||||
private static void loadUI() {
|
||||
INITIAL_VILLAGER_WINDOW = config.getString("ui.initial-window-name", INITIAL_VILLAGER_WINDOW);
|
||||
BUY_WINDOW = config.getString("ui.buy-window-name", BUY_WINDOW);
|
||||
SELL_WINDOW = config.getString("ui.sell-window-name", SELL_WINDOW);
|
||||
}
|
||||
|
||||
public static String HELP_MESSAGE_WRAPPER = "<gold>VillagerShopUI help:\n<commands></gold>";
|
||||
public static String HELP_MESSAGE = "<green>Show this menu: <gold>/villagerui help</gold></green>";
|
||||
public static String RELOAD_MESSAGE = "<green>Reload configs: <gold>/villagerui reload</gold></green>";
|
||||
public static String CREATE_VILLAGER_MESSAGE = "<green>Create a new trading villager: <gold>/villagerui createvillager <type> <x> <y> <z> <yaw> <pitch> <world></gold></green>";
|
||||
|
||||
private static void loadHelp() {
|
||||
HELP_MESSAGE_WRAPPER = config.getString("help.help-wrapper", HELP_MESSAGE_WRAPPER);
|
||||
HELP_MESSAGE = config.getString("help.help", HELP_MESSAGE);
|
||||
RELOAD_MESSAGE = config.getString("help.reload", RELOAD_MESSAGE);
|
||||
CREATE_VILLAGER_MESSAGE = config.getString("help.create-villager", CREATE_VILLAGER_MESSAGE);
|
||||
}
|
||||
|
||||
public static String NO_PERMISSION = "<red>You do not have permission to do that.</red>";
|
||||
public static String NO_CONSOLE = "<red>You cannot use this command from console.</red>";
|
||||
|
||||
private static void loadGeneric() {
|
||||
NO_PERMISSION = config.getString("generic.no-permission", NO_PERMISSION);
|
||||
NO_CONSOLE = config.getString("generic.no-console", NO_CONSOLE);
|
||||
}
|
||||
|
||||
public static String VILLAGER_NAME = "<green><name></green>";
|
||||
|
||||
private static void loadIDKYET() {//TODO rename
|
||||
VILLAGER_NAME = config.getString("idkyet.villager-name", VILLAGER_NAME); //TODO change path
|
||||
}
|
||||
|
||||
private static void loadVillagerTypes() {
|
||||
VillagerType.clearVillagerTypes();
|
||||
ConfigurationSection configurationSection = config.getConfigurationSection("villager-types");
|
||||
if (configurationSection == null) {
|
||||
VillagerUI.getInstance().getLogger().warning("No villager types found in config.");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> keys = configurationSection.getKeys(false);
|
||||
if (keys.isEmpty())
|
||||
VillagerUI.getInstance().getLogger().warning("No villager types found in config.");
|
||||
|
||||
keys.forEach(key -> {
|
||||
ConfigurationSection villagerType = configurationSection.getConfigurationSection(key);
|
||||
if (villagerType == null)
|
||||
return;
|
||||
|
||||
VillagerType.addVillagerType(new VillagerType(
|
||||
key,
|
||||
villagerType.getString("name"),
|
||||
loadProducts(villagerType.getConfigurationSection("buying")),
|
||||
loadProducts(villagerType.getConfigurationSection("selling")),
|
||||
villagerType.getDouble("price-modifier"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private static HashSet<ItemStack> loadProducts(ConfigurationSection productsSection) {
|
||||
HashSet<ItemStack> products = new HashSet<>();
|
||||
if (productsSection == null)
|
||||
return products;
|
||||
|
||||
productsSection.getKeys(false).forEach(item -> {
|
||||
Material material = Material.getMaterial(item);
|
||||
if (material == null) {
|
||||
VillagerUI.getInstance().getLogger().warning("Invalid key in products -> " + item);
|
||||
return;
|
||||
}
|
||||
products.add(new ItemStack(material, productsSection.getInt(item)));
|
||||
});
|
||||
|
||||
return products;
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/alttd/config/VillagerConfig.java
Normal file
44
src/main/java/com/alttd/config/VillagerConfig.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package com.alttd.config;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.alttd.objects.LoadedVillagers;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VillagerConfig extends AbstractConfig {
|
||||
|
||||
static VillagerConfig config;
|
||||
static int version;
|
||||
|
||||
public VillagerConfig() {
|
||||
super("villagerConfig.yml");
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
config = new VillagerConfig();
|
||||
|
||||
version = config.getInt("config-version", 1);
|
||||
config.set("config-version", 1);
|
||||
|
||||
config.readConfig(VillagerConfig.class, null);
|
||||
}
|
||||
|
||||
private static void loadVillagers() {
|
||||
LoadedVillagers.clearLoadedVillagers();
|
||||
config.getConfigurationSection("").getKeys(false).forEach(key -> {
|
||||
VillagerType villagerType = VillagerType.getVillagerType(config.getString(key, ""));
|
||||
if (villagerType != null)
|
||||
LoadedVillagers.addLoadedVillager(UUID.fromString(key), villagerType);
|
||||
else
|
||||
VillagerUI.getInstance().getLogger().warning("Invalid config entry " + key + ".");
|
||||
});
|
||||
}
|
||||
|
||||
public static void addVillager(UUID uuid, VillagerType villagerType) {
|
||||
config.set(uuid.toString(), villagerType.getName());
|
||||
}
|
||||
|
||||
}
|
||||
47
src/main/java/com/alttd/config/WorthConfig.java
Normal file
47
src/main/java/com/alttd/config/WorthConfig.java
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package com.alttd.config;
|
||||
|
||||
import com.alttd.VillagerUI;
|
||||
import com.alttd.util.Utilities;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
public class WorthConfig extends AbstractConfig {
|
||||
static WorthConfig config;
|
||||
static int version;
|
||||
|
||||
public WorthConfig() {
|
||||
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "VillagerShopUI"), "worth.yml");
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
config = new WorthConfig();
|
||||
|
||||
version = config.getInt("config-version", 1);
|
||||
config.set("config-version", 1);
|
||||
|
||||
config.readConfig(WorthConfig.class, null);
|
||||
}
|
||||
|
||||
public static Object2DoubleMap<Material> prices = new Object2DoubleOpenHashMap<>();
|
||||
|
||||
private static void loadWorth() {
|
||||
prices.clear();
|
||||
ConfigurationSection worth = config.getConfigurationSection("worth");
|
||||
Set<String> keys = worth.getKeys(false);
|
||||
for (String key : keys) {
|
||||
Material material = Material.getMaterial(key);
|
||||
if (material == null) {
|
||||
VillagerUI.getInstance().getLogger().warning("Invalid key in worth.yml -> " + key);
|
||||
continue;
|
||||
}
|
||||
|
||||
int price = (int) (worth.getDouble(key) * 100);
|
||||
prices.put(Material.getMaterial(key), Utilities.round(price, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/main/java/com/alttd/economy/Calculation.java
Normal file
67
src/main/java/com/alttd/economy/Calculation.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
package com.alttd.economy;
|
||||
|
||||
import com.alttd.config.WorthConfig;
|
||||
import com.alttd.util.Utilities;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class Calculation {
|
||||
|
||||
/**
|
||||
* Calculate the price for an item
|
||||
* @param item to calculate price for
|
||||
* @return price or int < 0 for error
|
||||
*/
|
||||
public static double price(ItemStack item) {
|
||||
if (WorthConfig.prices.containsKey(item.getType()))
|
||||
return Utilities.round(WorthConfig.prices.getDouble(item.getType()) * item.getAmount(), 2);
|
||||
|
||||
WorthConfig.prices.put(item.getType(), Utilities.round(getPrice(item, null), 2));
|
||||
|
||||
return WorthConfig.prices.getDouble(item.getType()) * item.getAmount();
|
||||
}
|
||||
|
||||
private static double getPrice(ItemStack item, Material blockedMaterial) {
|
||||
if (WorthConfig.prices.containsKey(item.getType()))
|
||||
return WorthConfig.prices.getDouble(item.getType());
|
||||
double price = -1;
|
||||
List<Recipe> recipes = Bukkit.getRecipesFor(item);
|
||||
for (Recipe recipe : recipes) {
|
||||
double possiblePrice;
|
||||
if (recipe instanceof ShapedRecipe shapedRecipe) {
|
||||
Collection<ItemStack> values = shapedRecipe.getIngredientMap().values();
|
||||
if (values.stream().anyMatch(itemStack -> itemStack.getType().equals(blockedMaterial)))
|
||||
continue;
|
||||
possiblePrice = getPrice(values.stream().toList(), item.getType());
|
||||
if (price == -1 || price > possiblePrice)
|
||||
price = possiblePrice;
|
||||
} else if (recipe instanceof ShapelessRecipe shapelessRecipe) {
|
||||
if (shapelessRecipe.getIngredientList().stream().anyMatch(itemStack -> itemStack.getType().equals(blockedMaterial)))
|
||||
continue;
|
||||
possiblePrice = getPrice(shapelessRecipe.getIngredientList(), item.getType());
|
||||
if (price == -1 || price > possiblePrice)
|
||||
price = possiblePrice;
|
||||
} else if (recipe instanceof FurnaceRecipe furnaceRecipe) {
|
||||
possiblePrice = getPrice(furnaceRecipe.getInput(), item.getType());
|
||||
if (price == -1 || price > possiblePrice)
|
||||
price = possiblePrice;
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
private static double getPrice(List<ItemStack> items, Material blockedMaterial) {
|
||||
double price = 0;
|
||||
for (ItemStack item : items) {
|
||||
double tmp = getPrice(item, blockedMaterial);
|
||||
if (tmp == -1)
|
||||
return -1;
|
||||
price += tmp;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/alttd/events/VillagerInteract.java
Normal file
24
src/main/java/com/alttd/events/VillagerInteract.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package com.alttd.events;
|
||||
|
||||
import com.alttd.GUI.windows.OpenGUI;
|
||||
import com.alttd.objects.LoadedVillagers;
|
||||
import com.alttd.objects.VillagerType;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class VillagerInteract implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!(event.getRightClicked() instanceof Villager villager))
|
||||
return;
|
||||
|
||||
VillagerType loadedVillager = LoadedVillagers.getLoadedVillager(villager.getUniqueId());
|
||||
if (loadedVillager == null)
|
||||
return;
|
||||
|
||||
new OpenGUI(loadedVillager).open(event.getPlayer());
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/alttd/objects/LoadedVillagers.java
Normal file
25
src/main/java/com/alttd/objects/LoadedVillagers.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package com.alttd.objects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LoadedVillagers {
|
||||
private final static Map<UUID, VillagerType> loadedVillagers = new HashMap<>();
|
||||
|
||||
public static VillagerType getLoadedVillager(UUID uuid) {
|
||||
return loadedVillagers.get(uuid);
|
||||
}
|
||||
|
||||
public static void addLoadedVillager(UUID uuid, VillagerType villagerType) {
|
||||
loadedVillagers.put(uuid, villagerType);
|
||||
}
|
||||
|
||||
public static void removeLoadedVillager(UUID uuid) {
|
||||
loadedVillagers.remove(uuid);
|
||||
}
|
||||
|
||||
public static void clearLoadedVillagers() {
|
||||
loadedVillagers.clear();
|
||||
}
|
||||
}
|
||||
59
src/main/java/com/alttd/objects/VillagerType.java
Normal file
59
src/main/java/com/alttd/objects/VillagerType.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package com.alttd.objects;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class VillagerType {
|
||||
private static final Set<VillagerType> villagerTypes = new HashSet<>();
|
||||
|
||||
public static Set<VillagerType> getVillagerTypes() {
|
||||
return villagerTypes;
|
||||
}
|
||||
|
||||
public static VillagerType getVillagerType(String name) {
|
||||
return villagerTypes.stream().filter(villagerType -> villagerType.getName().equals(name)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static void addVillagerType(VillagerType villagerType) {
|
||||
villagerTypes.add(villagerType);
|
||||
}
|
||||
|
||||
public static void clearVillagerTypes() {
|
||||
villagerTypes.clear();
|
||||
}
|
||||
private final String name;
|
||||
private final String displayName;
|
||||
private final Set<ItemStack> buying;
|
||||
private final Set<ItemStack> selling;
|
||||
private final double priceModifier;
|
||||
|
||||
public VillagerType(String name, String displayName, Set<ItemStack> buying, Set<ItemStack> selling, double priceModifier) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.buying = buying;
|
||||
this.selling = selling;
|
||||
this.priceModifier = priceModifier;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public Set<ItemStack> getBuying() {
|
||||
return buying;
|
||||
}
|
||||
|
||||
public Set<ItemStack> getSelling() {
|
||||
return selling;
|
||||
}
|
||||
|
||||
public double getPriceModifier() {
|
||||
return priceModifier;
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/alttd/util/Utilities.java
Normal file
25
src/main/java/com/alttd/util/Utilities.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package com.alttd.util;
|
||||
|
||||
public class Utilities {
|
||||
/**
|
||||
* Rounds num down to precision (rounds up if last cut off decimal is bigger than 4)
|
||||
*
|
||||
* @param num value to be rounded
|
||||
* @param precision length to round to
|
||||
* @return num rounded
|
||||
*/
|
||||
public static double round(double num, int precision) {
|
||||
double scale = Math.pow(10, precision);
|
||||
double total = (double) (Math.round(num * scale)) / scale;
|
||||
|
||||
scale = (int) Math.pow(10, precision + 1);
|
||||
long tmp = (Math.round(num * scale));
|
||||
|
||||
while (tmp > 10)
|
||||
tmp /= 10;
|
||||
if (tmp > 4)
|
||||
total += 0.01;
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
9
src/main/resources/plugin.yml
Normal file
9
src/main/resources/plugin.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
name: VillagerShopUI
|
||||
version: ${project.version}
|
||||
main: com.alttd.VillagerUI
|
||||
api-version: 1.17
|
||||
commands:
|
||||
villagerui:
|
||||
permission: villagerui.use
|
||||
description: Handles all villagerui commands
|
||||
usage: /villagerui
|
||||
Loading…
Reference in New Issue
Block a user