diff --git a/jitpack.yml b/jitpack.yml
new file mode 100644
index 0000000..73eeaa5
--- /dev/null
+++ b/jitpack.yml
@@ -0,0 +1,11 @@
+jdk:
+ - openjdk16
+
+before_install:
+ - sdk install java 16.0.1-open
+ - sdk use java 16.0.1-open
+ - sdk install maven
+ - mvn -v
+
+install:
+ - mvn install -DskipTests
diff --git a/pom.xml b/pom.xml
index 120ef52..ef01ef9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
Shops
Shops is the ultimate solution for server shops
- 4.0.0
+ 4.11.0
jar
@@ -16,7 +16,7 @@
${project.name}
${project.groupId}.${project.artifactId}.${project.name}
16
- 3.18.0
+ 3.30.0
ca.tweetzy
UTF-8
@@ -47,6 +47,10 @@
opencollab-snapshot
https://repo.opencollab.dev/maven-snapshots/
+
+ auxilor-plugins
+ https://repo.auxilor.io/repository/maven-public/
+
@@ -59,7 +63,7 @@
org.spigotmc
spigot
- 1.20.4-R0.1-SNAPSHOT
+ 1.21.4-R0.1-SNAPSHOT
provided
@@ -70,7 +74,7 @@
${flight.path}
funds
- 1.7.0
+ 1.10.0
*
@@ -78,6 +82,12 @@
+
+ com.willfp
+ EcoBits
+ 1.8.4
+ provided
+
com.github.MilkBowl
VaultAPI
@@ -195,50 +205,68 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ copy-files-on-build
+ package
+
+ copy-resources
+
+
+ D:\Development\Spigot Servers\Latest Version\plugins
+
+
+ ${project.build.directory}
+ ${project.name}.jar
+ false
+
+
+
+
+
+
+
+ com.coderplus.maven.plugins
+ copy-rename-maven-plugin
+ 1.0.1
+
+
+ copy-named-jar
+ package
+
+ copy
+
+
+ ${project.build.directory}/${project.name}.jar
+ D:\Development\Spigot Plugins\Ready Jars\${project.name}\${project.name} - v${project.version}.jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.7
+
+
+ test
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/ca/tweetzy/shops/Shops.java b/src/main/java/ca/tweetzy/shops/Shops.java
index fff9dfa..d4e5f64 100644
--- a/src/main/java/ca/tweetzy/shops/Shops.java
+++ b/src/main/java/ca/tweetzy/shops/Shops.java
@@ -80,6 +80,7 @@ protected void onFlight() {
new DeleteCommand(),
new CartCommand(),
new AdminCommand(),
+ new PrefillCommand(),
new ReloadCommand()
);
}
diff --git a/src/main/java/ca/tweetzy/shops/api/cart/CartContent.java b/src/main/java/ca/tweetzy/shops/api/cart/CartContent.java
index 9e140a3..89715d4 100644
--- a/src/main/java/ca/tweetzy/shops/api/cart/CartContent.java
+++ b/src/main/java/ca/tweetzy/shops/api/cart/CartContent.java
@@ -59,6 +59,7 @@ default TransactionResult executeSell(@NonNull final Player player) {
if (totalFoundInInventory == 0)
return TransactionResult.PLAYER_DOES_NOT_HAVE_ITEM;
+
final int amountToSell = Math.min(getQuantity(), totalFoundInInventory);
final double subTotal = getSellSubtotal(amountToSell);
diff --git a/src/main/java/ca/tweetzy/shops/api/shop/ShopDisplay.java b/src/main/java/ca/tweetzy/shops/api/shop/ShopDisplay.java
index 48df606..bee0976 100644
--- a/src/main/java/ca/tweetzy/shops/api/shop/ShopDisplay.java
+++ b/src/main/java/ca/tweetzy/shops/api/shop/ShopDisplay.java
@@ -37,6 +37,10 @@ public interface ShopDisplay extends Jsonable {
void setCartButtonSlot(final int slot);
+ int getSellButtonSlot();
+
+ void setSellButtonSlot(final int slot);
+
List getFillSlots();
void setFillSlots(final List slots);
diff --git a/src/main/java/ca/tweetzy/shops/api/shop/ShopLayoutControl.java b/src/main/java/ca/tweetzy/shops/api/shop/ShopLayoutControl.java
index e31c8ea..70feff9 100644
--- a/src/main/java/ca/tweetzy/shops/api/shop/ShopLayoutControl.java
+++ b/src/main/java/ca/tweetzy/shops/api/shop/ShopLayoutControl.java
@@ -7,5 +7,6 @@ public enum ShopLayoutControl {
NEXT_PAGE_BUTTON,
SEARCH_BUTTON,
FILTER_BUTTON,
- CART_BUTTON
+ CART_BUTTON,
+ SELL_BUTTON
}
diff --git a/src/main/java/ca/tweetzy/shops/commands/PrefillCommand.java b/src/main/java/ca/tweetzy/shops/commands/PrefillCommand.java
new file mode 100644
index 0000000..3861b48
--- /dev/null
+++ b/src/main/java/ca/tweetzy/shops/commands/PrefillCommand.java
@@ -0,0 +1,223 @@
+package ca.tweetzy.shops.commands;
+
+import ca.tweetzy.flight.command.AllowedExecutor;
+import ca.tweetzy.flight.command.Command;
+import ca.tweetzy.flight.command.ReturnType;
+import ca.tweetzy.flight.comp.enums.CompMaterial;
+import ca.tweetzy.flight.gui.helper.InventorySafeMaterials;
+import ca.tweetzy.flight.utils.QuickItem;
+import ca.tweetzy.shops.Shops;
+import ca.tweetzy.shops.api.shop.Shop;
+import ca.tweetzy.shops.impl.shop.ItemShopContent;
+import ca.tweetzy.shops.impl.shop.ServerShop;
+import org.bukkit.Material;
+import org.bukkit.command.CommandSender;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.List;
+import java.util.UUID;
+
+public final class PrefillCommand extends Command {
+
+ public PrefillCommand() {
+ super(AllowedExecutor.BOTH, "prefill");
+ }
+
+ @Override
+ protected ReturnType execute(CommandSender sender, String... args) {
+ if (args.length < 1) {
+ tellNoPrefix(sender, "&4Please use &c/shops prefill confirm &4to execute");
+ tellNoPrefix(sender, "&eBy doing this you acknowledge that any existing shop will either be deleted/cleared and re-populated with template items. The items that go into the shop &4MAY NOT BE &ecorrectly categorized. All prices and minimum quantities are also set to the same values regardless of what it is.");
+ return ReturnType.FAIL;
+ }
+
+
+ final boolean confirmed = args[0].equalsIgnoreCase("confirm");
+
+ if (!confirmed) return ReturnType.FAIL;
+
+ if (!Shops.getShopManager().getValues().isEmpty()) {
+ // yeet shops
+ for (Shop shop : Shops.getShopManager().getValues()) {
+ shop.unStore(result -> {
+ });
+ }
+ }
+
+ // create base shops
+
+ // FOOD
+ Shop foodShop = new ServerShop("food");
+ foodShop.getShopOptions().setDisplayIcon(new ItemStack(Material.CAKE, 1));
+
+ Shops.getShopManager().create(foodShop, created -> {
+ if (created) {
+ for (Material material : Material.values()) {
+ if (material == null || material == Material.AIR || !material.isEdible()) continue;
+ foodShop.addContent(new ItemShopContent(UUID.randomUUID(), foodShop.getId(), new ItemStack(material, 1), 1, 1, 0.5));
+ }
+ }
+ });
+
+ // BLOCKS
+ Shop blockShop = new ServerShop("blocks");
+ blockShop.getShopOptions().setDisplayIcon(new ItemStack(Material.GRASS_BLOCK, 1));
+
+ Shops.getShopManager().create(blockShop, created -> {
+ if (created) {
+ for (CompMaterial safe : InventorySafeMaterials.get()) {
+ if (safe.parseMaterial().isEdible() || !safe.parseMaterial().isBlock()) continue;
+ blockShop.addContent(new ItemShopContent(UUID.randomUUID(), blockShop.getId(), safe.parseItem(), 1, 1, 0.5));
+ }
+ }
+ });
+
+ // ARMOR
+ Shop armorShop = new ServerShop("armor");
+ armorShop.getShopOptions().setDisplayIcon(new ItemStack(Material.DIAMOND_HELMET, 1));
+
+ Shops.getShopManager().create(armorShop, created -> {
+ if (created) {
+ for (Material material : Material.values()) {
+ if (material == null || material == Material.AIR || material.isEdible() || !isArmor(material)) continue;
+ armorShop.addContent(new ItemShopContent(UUID.randomUUID(), armorShop.getId(), new ItemStack(material, 1), 1, 1, 0.5));
+ }
+ }
+ });
+
+ Shop weaponsShop = new ServerShop("weapons");
+ weaponsShop.getShopOptions().setDisplayIcon(new ItemStack(Material.IRON_SWORD, 1));
+
+ Shops.getShopManager().create(weaponsShop, created -> {
+ if (created) {
+ for (Material material : Material.values()) {
+ if (material == null || material == Material.AIR || !isWeapon(material)) continue;
+ weaponsShop.addContent(new ItemShopContent(UUID.randomUUID(), weaponsShop.getId(), new ItemStack(material, 1), 1, 1, 0.5));
+ }
+ }
+ });
+
+ Shop toolShop = new ServerShop("tools");
+ toolShop.getShopOptions().setDisplayIcon(new ItemStack(Material.NETHERITE_PICKAXE, 1));
+
+ Shops.getShopManager().create(toolShop, created -> {
+ if (created) {
+ for (Material material : Material.values()) {
+
+ if (material == null || material == Material.AIR || !isTool(material)) continue;
+ toolShop.addContent(new ItemShopContent(UUID.randomUUID(), toolShop.getId(), new ItemStack(material, 1), 1, 1, 0.5));
+ }
+ }
+ });
+
+ Shop potionsShop = new ServerShop("potions");
+ potionsShop.getShopOptions().setDisplayIcon(new ItemStack(Material.LINGERING_POTION, 1));
+
+ Shops.getShopManager().create(potionsShop, created -> {
+ if (created) {
+ potionsShop.addContent(new ItemShopContent(UUID.randomUUID(), toolShop.getId(), QuickItem.of(CompMaterial.POTION).name("&ePotions Are Weird").lore("&7Since there are a bunch of variants, you will", "&7have to add them in manually.").make(), 1, 1, 0.5));
+ }
+ });
+
+ Shop raidingShop = new ServerShop("raiding");
+ raidingShop.getShopOptions().setDisplayIcon(new ItemStack(Material.TNT, 1));
+
+ Shops.getShopManager().create(raidingShop, created -> {
+ if (created) {
+ raidingShop.addContent(new ItemShopContent(UUID.randomUUID(), raidingShop.getId(), new ItemStack(Material.TNT, 1), 1, 1, 0.5));
+ raidingShop.addContent(new ItemShopContent(UUID.randomUUID(), raidingShop.getId(), new ItemStack(Material.TNT_MINECART, 1), 1, 1, 0.5));
+ }
+ });
+
+ Shop redstoneShop = new ServerShop("redstone");
+ redstoneShop.getShopOptions().setDisplayIcon(new ItemStack(Material.REDSTONE, 1));
+
+ Shops.getShopManager().create(redstoneShop, created -> {
+ if (created) {
+ for (Material material : Material.values()) {
+ if (material == null || material == Material.AIR || !isRedstone(material)) continue;
+ redstoneShop.addContent(new ItemShopContent(UUID.randomUUID(), redstoneShop.getId(), new ItemStack(material, 1), 1, 1, 0.5));
+ }
+ }
+ });
+
+ return ReturnType.SUCCESS;
+ }
+
+ @Override
+ protected List tab(CommandSender sender, String... args) {
+ return null;
+ }
+
+ @Override
+ public String getPermissionNode() {
+ return "shops.command.prefill";
+ }
+
+ @Override
+ public String getSyntax() {
+ return "prefill ";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Used quickly create template categories and populate";
+ }
+
+ private boolean isArmor(final Material material) {
+ final String typeNameString = material.name();
+ return typeNameString.endsWith("_HELMET")
+ || typeNameString.endsWith("_CHESTPLATE")
+ || typeNameString.endsWith("_LEGGINGS")
+ || typeNameString.endsWith("_BOOTS");
+ }
+
+ private boolean isWeapon(final Material material) {
+ final String typeNameString = material.name();
+ return typeNameString.endsWith("_SWORD")
+ || typeNameString.endsWith("_AXE")
+ || material == Material.BOW
+ || material == Material.CROSSBOW
+ || material == Material.TRIDENT
+ || material == Material.ARROW
+ || material == Material.SHIELD;
+ }
+
+ private boolean isTool(final Material material) {
+ final String typeNameString = material.name();
+ return typeNameString.endsWith("_HOE")
+ || typeNameString.endsWith("_SHOVEL")
+ || typeNameString.endsWith("_PICKAXE")
+ || material == Material.FISHING_ROD
+ || material == Material.COMPASS
+ || material == Material.CLOCK
+ || material == Material.LEAD
+ || material == Material.SHEARS
+ || typeNameString.contains("BUCKET");
+ }
+
+ private boolean isRedstone(final Material material) {
+ final String typeNameString = material.name();
+ return material == Material.REDSTONE
+ || typeNameString.endsWith("_PLATE")
+ || typeNameString.endsWith("_BUTTON")
+ || material == Material.REDSTONE_BLOCK
+ || material == Material.REDSTONE_LAMP
+ || material == Material.REDSTONE_TORCH
+ || material == Material.REPEATER
+ || material == Material.COMPARATOR
+ || material == Material.LEVER
+ || material == Material.HOPPER
+ || material == Material.OBSERVER
+ || material == Material.STICKY_PISTON
+ || material == Material.PISTON
+ || material == Material.SLIME_BLOCK
+ || material == Material.HONEY_BLOCK
+ || material == Material.ACTIVATOR_RAIL
+ || material == Material.POWERED_RAIL
+ || material == Material.DETECTOR_RAIL
+ || material == Material.DROPPER
+ || material == Material.DISPENSER
+ || material == Material.SHIELD;
+ }
+}
diff --git a/src/main/java/ca/tweetzy/shops/gui/ShopsBaseGUI.java b/src/main/java/ca/tweetzy/shops/gui/ShopsBaseGUI.java
index b9ffa8e..46d9cad 100644
--- a/src/main/java/ca/tweetzy/shops/gui/ShopsBaseGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/ShopsBaseGUI.java
@@ -3,6 +3,7 @@
import ca.tweetzy.flight.gui.Gui;
import ca.tweetzy.flight.gui.template.BaseGUI;
import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.shops.settings.Settings;
import ca.tweetzy.shops.settings.Translations;
@@ -19,16 +20,22 @@ public abstract class ShopsBaseGUI extends BaseGUI {
public ShopsBaseGUI(Gui parent, @NonNull final Player player, @NonNull String title, int rows) {
super(parent, title, rows);
this.player = player;
+
+
+ setGlobalClickDelay(Settings.GLOBAL_GUI_CLICK_DELAY.getInt());
+
+ if (Settings.SEND_CLICK_DELAY_MSG.getBoolean())
+ setClickDelayAction(click -> Common.tell(click.player, TranslationManager.string(Translations.CLICKING_TOO_FAST)));
}
public ShopsBaseGUI(Gui parent, @NonNull final Player player, @NonNull String title) {
super(parent, title);
this.player = player;
- }
- public ShopsBaseGUI(@NonNull final Player player, @NonNull String title) {
- super(title);
- this.player = player;
+ setGlobalClickDelay(Settings.GLOBAL_GUI_CLICK_DELAY.getInt());
+
+ if (Settings.SEND_CLICK_DELAY_MSG.getBoolean())
+ setClickDelayAction(click -> Common.tell(click.player, TranslationManager.string(Translations.CLICKING_TOO_FAST)));
}
@Override
diff --git a/src/main/java/ca/tweetzy/shops/gui/ShopsPagedGUI.java b/src/main/java/ca/tweetzy/shops/gui/ShopsPagedGUI.java
index 018c361..d192bab 100644
--- a/src/main/java/ca/tweetzy/shops/gui/ShopsPagedGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/ShopsPagedGUI.java
@@ -4,6 +4,7 @@
import ca.tweetzy.flight.gui.events.GuiClickEvent;
import ca.tweetzy.flight.gui.template.BaseGUI;
import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.shops.settings.Settings;
import ca.tweetzy.shops.settings.Translations;
@@ -27,10 +28,11 @@ public ShopsPagedGUI(Gui parent, @NonNull final Player player, @NonNull String t
this.parent = parent;
this.player = player;
this.items = items;
- }
- public ShopsPagedGUI(@NonNull final Player player, @NonNull String title, int rows, @NonNull List items) {
- this(null, player, title, rows, items);
+ setGlobalClickDelay(Settings.GLOBAL_GUI_CLICK_DELAY.getInt());
+
+ if (Settings.SEND_CLICK_DELAY_MSG.getBoolean())
+ setClickDelayAction(click -> Common.tell(click.player, TranslationManager.string(Translations.CLICKING_TOO_FAST)));
}
@Override
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/ShopEditGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/ShopEditGUI.java
index b26281f..74903f7 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/ShopEditGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/ShopEditGUI.java
@@ -65,7 +65,7 @@ protected void drawFixed() {
// quick selector
if (click.clickType == ClickType.RIGHT)
click.manager.showGUI(click.player, new MaterialPickerGUI(this, null, "", (event, selected) -> {
- click.manager.showGUI(click.player, new ShopAddContentItemGUI(click.player, this.shop, ItemShopContent.blank(this.shop.getId(), selected), false));
+ click.manager.showGUI(click.player, new ShopAddContentItemGUI(click.player, this.shop, ItemShopContent.blank(this.shop.getId(), CompMaterial.matchCompMaterial(selected)), false));
}));
});
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/ShopSettingsGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/ShopSettingsGUI.java
index febb4bf..d8a3289 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/ShopSettingsGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/ShopSettingsGUI.java
@@ -4,6 +4,7 @@
import ca.tweetzy.flight.comp.enums.CompMaterial;
import ca.tweetzy.flight.gui.template.MaterialPickerGUI;
import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.flight.utils.input.TitleInput;
import ca.tweetzy.shops.Shops;
@@ -12,6 +13,7 @@
import ca.tweetzy.shops.commands.DynamicShopCommand;
import ca.tweetzy.shops.gui.ShopsBaseGUI;
import ca.tweetzy.shops.gui.admin.layout.ShopLayoutEditorGUI;
+import ca.tweetzy.shops.impl.currency.ItemCurrency;
import ca.tweetzy.shops.settings.Translations;
import lombok.NonNull;
import org.bukkit.ChatColor;
@@ -29,6 +31,7 @@ public final class ShopSettingsGUI extends ShopsBaseGUI {
public ShopSettingsGUI(@NonNull Player player, @NonNull final Shop shop) {
super(new ShopEditGUI(player, shop), player, TranslationManager.string(Translations.GUI_SHOP_SETTINGS_TITLE, "shop_id", shop.getId()), 6);
this.shop = shop;
+ setAcceptsItems(true);
draw();
}
@@ -48,7 +51,7 @@ protected void draw() {
if (material == null) return;
final ItemStack oldIcon = this.shop.getShopOptions().getDisplayIcon();
- final ItemStack newIcon = material.parseItem();
+ final ItemStack newIcon = material;
assert newIcon != null;
this.shop.getShopOptions().setDisplayIcon(newIcon);
@@ -129,8 +132,33 @@ public boolean onResult(String string) {
setButton(3, 4, QuickItem
.of(CompMaterial.CARTOGRAPHY_TABLE)
.name(TranslationManager.string(Translations.GUI_SHOP_SETTINGS_ITEMS_DECO_NAME))
- .lore(TranslationManager.list(Translations.GUI_SHOP_SETTINGS_ITEMS_DECO_LORE))
- .make(), click -> click.manager.showGUI(click.player, new ShopLayoutEditorGUI(click.player, this.shop)));
+ .lore(TranslationManager.list(Translations.GUI_SHOP_SETTINGS_ITEMS_DECO_LORE,
+ "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK),
+ "right_click", TranslationManager.string(this.player, Translations.MOUSE_RIGHT_CLICK)))
+ .make(), click -> {
+
+ if (click.clickType == ClickType.LEFT) {
+ click.manager.showGUI(click.player, new ShopLayoutEditorGUI(click.player, this.shop));
+ return;
+ }
+
+ if (click.clickType == ClickType.RIGHT) {
+ final ItemStack cursor = click.cursor;
+ if (cursor != null && cursor.getType() != CompMaterial.AIR.parseMaterial()) {
+ final ItemStack newBG = cursor.clone();
+ newBG.setAmount(1);
+ this.shop.getShopOptions().getShopDisplay().setBackgroundItem(newBG);
+ } else {
+ this.shop.getShopOptions().getShopDisplay().setBackgroundItem(QuickItem.of(CompMaterial.AIR).make());
+ }
+
+ this.shop.sync(result -> {
+ if (result == SynchronizeResult.SUCCESS)
+ Common.tell(click.player, TranslationManager.string(click.player, Translations.UPDATED_SHOP_BG));
+ });
+
+ }
+ });
// permission
setButton(3, 2, QuickItem
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentCmdGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentCmdGUI.java
index 7d9c9c6..8a5adb9 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentCmdGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentCmdGUI.java
@@ -104,7 +104,7 @@ private void drawIcon() {
if (click.clickType == ClickType.LEFT) {
click.manager.showGUI(click.player, new MaterialPickerGUI(this, null, "", (event, selected) -> {
- this.commandShopContent.setIcon(selected.parseItem());
+ this.commandShopContent.setIcon(selected);
click.manager.showGUI(click.player, new ShopAddContentCmdGUI(click.player, ShopAddContentCmdGUI.this.shop, ShopAddContentCmdGUI.this.commandShopContent, ShopAddContentCmdGUI.this.isEditing));
}));
}
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentItemGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentItemGUI.java
index f3d70c7..0128e84 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentItemGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/content/ShopAddContentItemGUI.java
@@ -101,7 +101,7 @@ private void drawSellItem() {
if (click.clickType == ClickType.LEFT) {
click.manager.showGUI(click.player, new MaterialPickerGUI(this, null, "", (event, selected) -> {
- this.itemContent.setItem(selected.parseItem());
+ this.itemContent.setItem(selected);
click.manager.showGUI(click.player, new ShopAddContentItemGUI(click.player, ShopAddContentItemGUI.this.shop, ShopAddContentItemGUI.this.itemContent, ShopAddContentItemGUI.this.isEditing));
}));
}
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutControlPickerGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutControlPickerGUI.java
index 924bd93..f1eb14f 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutControlPickerGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutControlPickerGUI.java
@@ -71,6 +71,11 @@ protected ItemStack makeDisplayItem(ShopLayoutControl layoutControl) {
.name(TranslationManager.string(this.player, Translations.GUI_LAYOUT_CONTROL_PICKER_ITEMS_CART_NAME))
.lore(TranslationManager.list(this.player, Translations.GUI_LAYOUT_CONTROL_PICKER_ITEMS_CART_LORE, "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK)))
.make();
+ case SELL_BUTTON -> QuickItem
+ .of(Settings.GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL.getItemStack())
+ .name(TranslationManager.string(this.player, Translations.GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL_LORE, "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK)))
+ .make();
};
}
diff --git a/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutEditorGUI.java b/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutEditorGUI.java
index d2ef6a6..6632894 100644
--- a/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutEditorGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/admin/layout/ShopLayoutEditorGUI.java
@@ -66,6 +66,12 @@ protected void drawFixed() {
.lore(TranslationManager.list(this.player, Translations.GUI_LAYOUT_EDITOR_ITEMS_CART_LORE))
.make());
+ setItem(layout.getSellButtonSlot(), QuickItem
+ .of(CompMaterial.ENDER_CHEST)
+ .name(TranslationManager.string(this.player, Translations.GUI_LAYOUT_EDITOR_ITEMS_SELL_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_LAYOUT_EDITOR_ITEMS_SELL_LORE))
+ .make());
+
}
@Override
@@ -136,6 +142,7 @@ else if (isEmptySlot(slot)) {
case SEARCH_BUTTON -> layout.setSearchButtonSlot(slot);
case FILTER_BUTTON -> layout.setFilterButtonSlot(slot);
case CART_BUTTON -> layout.setCartButtonSlot(slot);
+ case SELL_BUTTON -> layout.setSellButtonSlot(slot);
}
layout.getFillSlots().remove(slot);
@@ -178,7 +185,8 @@ private boolean isEmptySlot(final int slot) {
&& layout.getPrevPageButtonSlot() != slot
&& layout.getSearchButtonSlot() != slot
&& layout.getFilterButtonSlot() != slot
- && layout.getCartButtonSlot() != slot;
+ && layout.getCartButtonSlot() != slot
+ && layout.getSellButtonSlot() != slot;
}
private ItemStack emptySlotItem() {
diff --git a/src/main/java/ca/tweetzy/shops/gui/selector/CurrencyPickerGUI.java b/src/main/java/ca/tweetzy/shops/gui/selector/CurrencyPickerGUI.java
index b8faf19..9373785 100644
--- a/src/main/java/ca/tweetzy/shops/gui/selector/CurrencyPickerGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/selector/CurrencyPickerGUI.java
@@ -53,7 +53,7 @@ protected void drawFixed() {
if (click.clickType == ClickType.RIGHT) {
click.manager.showGUI(click.player, new MaterialPickerGUI(this, null, null, (event, selected) -> {
if (selected != null) {
- this.selectedCurrency.accept(new ItemCurrency(), selected.parseItem());
+ this.selectedCurrency.accept(new ItemCurrency(), selected);
}
}));
}
diff --git a/src/main/java/ca/tweetzy/shops/gui/user/ShopCheckoutGUI.java b/src/main/java/ca/tweetzy/shops/gui/user/ShopCheckoutGUI.java
index e9b69c9..13e175f 100644
--- a/src/main/java/ca/tweetzy/shops/gui/user/ShopCheckoutGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/user/ShopCheckoutGUI.java
@@ -1,7 +1,9 @@
package ca.tweetzy.shops.gui.user;
+import ca.tweetzy.flight.comp.enums.CompMaterial;
import ca.tweetzy.flight.gui.Gui;
import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.shops.Shops;
import ca.tweetzy.shops.api.cart.CartContent;
@@ -26,14 +28,21 @@ public final class ShopCheckoutGUI extends ShopsBaseGUI {
private final Shop shop;
private final CartContent checkoutItem;
+ private boolean isSelling = false;
+ private boolean fromSpawners;
- public ShopCheckoutGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, @NonNull CartContent checkoutItem) {
+ public ShopCheckoutGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, @NonNull CartContent checkoutItem, boolean fromSpawners) {
super(parent, player, TranslationManager.string(player, Translations.GUI_CHECKOUT_TITLE));
this.shop = shop;
this.checkoutItem = checkoutItem;
+ this.fromSpawners = fromSpawners;
draw();
}
+ public ShopCheckoutGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, @NonNull CartContent checkoutItem) {
+ this(parent, player, shop, checkoutItem, false);
+ }
+
@Override
protected void draw() {
drawSelectedItem();
@@ -73,16 +82,31 @@ protected void draw() {
});
});
+ drawBuySellButton();
+
+ if (this.checkoutItem.getItem().isAllowSell() && !this.fromSpawners)
+ drawSellToggleButton();
+
+ drawPriceBreakdown();
+
+ applyBackExit();
+ }
+
+ private void drawSelectedItem() {
+ setItem(1, 4, this.checkoutItem.getItem().generateDisplayItem(ShopContentDisplayType.CHECKOUT, this.checkoutItem.getQuantity()));
+ }
+
+ private void drawBuySellButton() {
setButton(getRows() - 1, 4, QuickItem
.of(Settings.GUI_CHECKOUT_ITEMS_CHECKOUT.getItemStack())
- .name(TranslationManager.string(this.player, Translations.GUI_CHECKOUT_ITEMS_PURCHASE_NAME))
- .lore(TranslationManager.list(this.player, Translations.GUI_CHECKOUT_ITEMS_PURCHASE_LORE,
+ .name(TranslationManager.string(this.player, this.isSelling ? Translations.GUI_CHECKOUT_ITEMS_SELL_NAME : Translations.GUI_CHECKOUT_ITEMS_PURCHASE_NAME))
+ .lore(TranslationManager.list(this.player, this.isSelling ? Translations.GUI_CHECKOUT_ITEMS_SELL_LORE : Translations.GUI_CHECKOUT_ITEMS_PURCHASE_LORE,
"left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK),
"right_click", TranslationManager.string(this.player, Translations.MOUSE_RIGHT_CLICK)
)).make(), click -> {
if (click.clickType == ClickType.LEFT) {
- final TransactionResult transactionResult = this.checkoutItem.executePurchase(player);
+ final TransactionResult transactionResult = this.isSelling ? this.checkoutItem.executeSell(player) : this.checkoutItem.executePurchase(player);
click.manager.showGUI(click.player, new ShopContentsGUI(new ShopsMainGUI(null, click.player), click.player, this.shop));
}
@@ -92,26 +116,39 @@ protected void draw() {
}
});
-
- drawPriceBreakdown();
- applyBackExit();
}
- private void drawSelectedItem() {
- setItem(1, 4, this.checkoutItem.getItem().generateDisplayItem(ShopContentDisplayType.CHECKOUT, this.checkoutItem.getQuantity()));
+ private void drawSellToggleButton() {
+ setButton(getRows() - 1, 8, QuickItem
+ .of(this.isSelling ? CompMaterial.REDSTONE_TORCH : CompMaterial.TORCH)
+ .name(TranslationManager.string(Translations.GUI_CHECKOUT_ITEMS_TOGGLE_SELL_NAME))
+ .lore(TranslationManager.list(Translations.GUI_CHECKOUT_ITEMS_TOGGLE_SELL_LORE, "is_true", TranslationManager.string(!this.isSelling ? Translations.ENABLED : Translations.DISABLED)))
+ .make(), click -> {
+
+ if (!this.checkoutItem.getItem().isAllowSell()) {
+ Common.tell(click.player, TranslationManager.string(Translations.SELL_NOT_ALLOWED));
+ return;
+ }
+
+ this.isSelling = !this.isSelling;
+ drawSellToggleButton();
+ drawPriceBreakdown();
+ drawBuySellButton();
+ });
}
private void drawPriceBreakdown() {
- final double subtotal = this.checkoutItem.getBuySubtotal(this.checkoutItem.getQuantity());
- final double total = Taxer.getTaxedTotal(subtotal);
+ final double subtotal = this.isSelling ? this.checkoutItem.getSellSubtotal(this.checkoutItem.getQuantity()) : this.checkoutItem.getBuySubtotal(this.checkoutItem.getQuantity());
+ final double total = this.isSelling ? subtotal : Taxer.getTaxedTotal(subtotal);
final String numberFormatSub = this.checkoutItem.getItem().isCurrencyOfItem() ? (int) subtotal + " " + this.checkoutItem.getItem().getCurrencyDisplayName() : NumberHelper.format(subtotal);
final String numberFormatTotal = this.checkoutItem.getItem().isCurrencyOfItem() ? (int) total + " " + this.checkoutItem.getItem().getCurrencyDisplayName() : NumberHelper.format(total);
- List base = TranslationManager.list(this.player, Translations.GUI_CHECKOUT_ITEMS_BREAKDOWN_LORE,
+ List base = TranslationManager.list(this.player, this.isSelling ? Translations.GUI_CHECKOUT_ITEMS_BREAKDOWN_SELL_LORE : Translations.GUI_CHECKOUT_ITEMS_BREAKDOWN_LORE,
"checkout_item_qty", this.checkoutItem.getQuantity(),
"checkout_item_buy_subtotal", numberFormatSub,
- "checkout_item_buy_total", numberFormatTotal
+ "checkout_item_buy_total", numberFormatTotal,
+ "checkout_item_sell_total", numberFormatTotal
);
VariableHelper.replaceVariable(base, "%checkout_tax_info%", Settings.TAX_ENABLED.getBoolean() ?
diff --git a/src/main/java/ca/tweetzy/shops/gui/user/ShopContentsGUI.java b/src/main/java/ca/tweetzy/shops/gui/user/ShopContentsGUI.java
index 30ea384..e50b225 100644
--- a/src/main/java/ca/tweetzy/shops/gui/user/ShopContentsGUI.java
+++ b/src/main/java/ca/tweetzy/shops/gui/user/ShopContentsGUI.java
@@ -1,5 +1,6 @@
package ca.tweetzy.shops.gui.user;
+import ca.tweetzy.flight.comp.enums.CompMaterial;
import ca.tweetzy.flight.gui.Gui;
import ca.tweetzy.flight.gui.events.GuiClickEvent;
import ca.tweetzy.flight.settings.TranslationManager;
@@ -34,18 +35,30 @@ public final class ShopContentsGUI extends ShopsPagedGUI {
private FilterOrder filterOrder;
private FilterType filterType;
- public ShopContentsGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, final String search) {
+ private boolean fromSpawners;
+
+ public ShopContentsGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, final String search, final boolean fromSpawners) {
super(parent, player, shop.getDisplayName(), Math.max(2, shop.getShopOptions().getShopDisplay().getRows()), shop.getContent());
this.shop = shop;
this.cart = Shops.getCartManager().getOrAdd(player);
this.filterType = FilterType.NAME;
this.filterOrder = FilterOrder.ASCENDING;
this.search = search;
+ this.fromSpawners = fromSpawners;
+ // apply default item
+ final ItemStack bg = this.shop.getShopOptions().getShopDisplay().getBackgroundItem();
+
+ setDefaultItem(bg.getType() == CompMaterial.AIR.parseMaterial() ? null : QuickItem.bg(bg));
+
draw();
}
public ShopContentsGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop) {
- this(parent, player, shop, null);
+ this(parent, player, shop, null, false);
+ }
+
+ public ShopContentsGUI(Gui parent, @NonNull Player player, @NonNull final Shop shop, final boolean fromSpawners) {
+ this(parent, player, shop, null, fromSpawners);
}
@Override
@@ -68,6 +81,9 @@ protected void drawFixed() {
// decorations
this.shop.getShopOptions().getShopDisplay().getDecoration().forEach((slot, item) -> setItem(slot, QuickItem.bg(item)));
+ // cart
+ drawCart();
+
// search
setButton(this.shop.getShopOptions().getShopDisplay().getSearchButtonSlot(), QuickItem
.of(Settings.GUI_SHOP_CONTENT_ITEMS_SEARCH.getItemStack())
@@ -85,20 +101,24 @@ public void onExit(Player player) {
@Override
public boolean onResult(String string) {
- click.manager.showGUI(click.player, new ShopContentsGUI(ShopContentsGUI.this.parent, click.player, ShopContentsGUI.this.shop, string));
+ click.manager.showGUI(click.player, new ShopContentsGUI(ShopContentsGUI.this.parent, click.player, ShopContentsGUI.this.shop, string, false));
return true;
}
};
if (click.clickType == ClickType.RIGHT)
- click.manager.showGUI(click.player, new ShopContentsGUI(ShopContentsGUI.this.parent, click.player, ShopContentsGUI.this.shop, null));
+ click.manager.showGUI(click.player, new ShopContentsGUI(ShopContentsGUI.this.parent, click.player, ShopContentsGUI.this.shop, null, false));
});
- // cart
- drawCart();
+ if (!this.fromSpawners) {
+ // sell drop box
+ drawSell();
+ }
+
// filter
drawFilter();
+
}
private void drawFilter() {
@@ -126,6 +146,18 @@ private void drawCart() {
}
+ private void drawSell() {
+ setButton(this.shop.getShopOptions().getShopDisplay().getSellButtonSlot(), QuickItem
+ .of(Settings.GUI_SHOP_CONTENT_ITEMS_SELL.getItemStack())
+ .name(TranslationManager.string(this.player, Translations.GUI_SHOP_CONTENTS_ITEMS_SELL_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_SHOP_CONTENTS_ITEMS_SELL_LORE))
+ .make(), click -> {
+
+ click.manager.showGUI(click.player, new ShopQuickSellGUI(click.player, this.shop));
+ });
+ }
+
+
@Override
protected ItemStack makeDisplayItem(ShopContent content) {
return content.generateDisplayItem(ShopContentDisplayType.LIVE_SHOP);
@@ -134,7 +166,7 @@ protected ItemStack makeDisplayItem(ShopContent content) {
@Override
protected void onClick(ShopContent content, GuiClickEvent click) {
if (click.clickType == ClickType.LEFT)
- click.manager.showGUI(click.player, new ShopCheckoutGUI(this, player, this.shop, new CartItem(content, content.getMinimumPurchaseQty())));
+ click.manager.showGUI(click.player, new ShopCheckoutGUI(this, player, this.shop, new CartItem(content, content.getMinimumPurchaseQty()), this.fromSpawners));
if (click.clickType == ClickType.RIGHT) {
this.cart.addItem(content);
diff --git a/src/main/java/ca/tweetzy/shops/gui/user/ShopQuickSellGUI.java b/src/main/java/ca/tweetzy/shops/gui/user/ShopQuickSellGUI.java
new file mode 100644
index 0000000..12f03f6
--- /dev/null
+++ b/src/main/java/ca/tweetzy/shops/gui/user/ShopQuickSellGUI.java
@@ -0,0 +1,146 @@
+package ca.tweetzy.shops.gui.user;
+
+import ca.tweetzy.flight.comp.enums.CompMaterial;
+import ca.tweetzy.flight.gui.helper.InventoryBorder;
+import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
+import ca.tweetzy.flight.utils.PlayerUtil;
+import ca.tweetzy.flight.utils.QuickItem;
+import ca.tweetzy.shops.Shops;
+import ca.tweetzy.shops.api.Transaction;
+import ca.tweetzy.shops.api.events.ShopTransactionEvent;
+import ca.tweetzy.shops.api.shop.Shop;
+import ca.tweetzy.shops.gui.ShopsBaseGUI;
+import ca.tweetzy.shops.impl.ShopTransaction;
+import ca.tweetzy.shops.impl.shop.ItemShopContent;
+import ca.tweetzy.shops.model.ItemParser;
+import ca.tweetzy.shops.model.NumberHelper;
+import ca.tweetzy.shops.model.Taxer;
+import ca.tweetzy.shops.settings.Settings;
+import ca.tweetzy.shops.settings.Translations;
+import lombok.NonNull;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.IntStream;
+
+public final class ShopQuickSellGUI extends ShopsBaseGUI {
+
+ private final Shop shop;
+
+ public ShopQuickSellGUI(@NonNull Player player, @NonNull final Shop shop) {
+ super(null, player, TranslationManager.string(Translations.GUI_SHOP_QUICK_SELL_TITLE, "shop_name", shop.getDisplayName()));
+ this.shop = shop;
+
+ setAcceptsItems(true);
+ InventoryBorder.getInsideBorders(6).forEach(this::setUnlocked);
+
+ setOnClose(close -> attemptSell(close.player));
+
+ draw();
+ }
+
+ @Override
+ protected void draw() {
+
+ Settings.GUI_SHOPS_QUICK_SELL_DECORATIONS.getStringList().forEach(itemLine -> {
+ final Map> keyed = ItemParser.parseString(itemLine);
+
+ String item = keyed.get("item").get(0);
+ if (keyed.containsKey("model"))
+ item += ":" + keyed.get("model").get(0);
+
+ List possibleSlots = new ArrayList<>();
+ final String rawSlots = keyed.get("slot").get(0);
+ if (rawSlots.contains("-")) {
+ final String[] slotSplit = rawSlots.split("-");
+ possibleSlots.addAll(IntStream.rangeClosed(Integer.parseInt(slotSplit[0]), Integer.parseInt(slotSplit[1])).boxed().toList());
+ } else {
+ possibleSlots.add(Integer.parseInt(rawSlots));
+ }
+
+ for (Integer possibleSlot : possibleSlots) {
+ setItem(possibleSlot, QuickItem.bg(QuickItem.of(item).tag("ShopsBorderDeco", "Y").make()));
+ }
+
+ });
+
+ setButton(5, 4, QuickItem
+ .of(CompMaterial.LIME_DYE)
+ .name(TranslationManager.string(Translations.GUI_SHOP_QUICK_SELL_ITEMS_SELL_NAME))
+ .lore(TranslationManager.list(Translations.GUI_SHOP_QUICK_SELL_ITEMS_SELL_LORE))
+ .make(), click -> attemptSell(click.player));
+
+ setButton(getBackExitButtonSlot(), getBackButton(), click -> {
+ gatherItems().forEach(item -> PlayerUtil.giveItem(click.player, item));
+
+ click.manager.showGUI(click.player, new ShopContentsGUI(new ShopsMainGUI(null, player), player, shop));
+ });
+ }
+
+ private List gatherItems() {
+ List items = new ArrayList<>();
+ InventoryBorder.getInsideBorders(6).forEach(slot -> {
+ final ItemStack slotItem = getItem(slot);
+ if (slotItem == null || slotItem.getType() == CompMaterial.AIR.parseMaterial()) return;
+ items.add(slotItem);
+ });
+ return items;
+ }
+
+ private void attemptSell(@NonNull final Player player) {
+ List itemShopContents = this.shop.getContent().stream().filter(content -> content instanceof ItemShopContent).map(content -> (ItemShopContent) content).toList();
+ List items = gatherItems();
+
+ InventoryBorder.getInsideBorders(6).forEach(slot -> setItem(slot, CompMaterial.AIR.parseItem()));
+
+ items.forEach(item -> {
+ final ItemShopContent shopContent = itemShopContents.stream().filter(content -> content.getItem().isSimilar(item)).findFirst().orElse(null);
+ if (shopContent == null || !shopContent.isAllowSell()) {
+ PlayerUtil.giveItem(player, item);
+ return;
+ }
+
+ final int amountToSell = item.getAmount();
+ final double subTotal = shopContent.getSellPrice() * amountToSell;
+ final double total = Settings.TAX_SELL.getBoolean() ? subTotal - Taxer.calculateTaxAmount(subTotal) : subTotal;
+
+ String moneyAddMsg = "";
+
+ if (shopContent.isCurrencyOfItem()) {
+ Shops.getCurrencyManager().deposit(player, shopContent.getCurrencyItem(), (int) total);
+ moneyAddMsg += ((int) total) + " " + shopContent.getCurrencyDisplayName();
+ } else {
+ final String[] currencySplit = shopContent.getCurrency().split("/");
+ Shops.getCurrencyManager().deposit(player, currencySplit[0], currencySplit[1], total);
+ moneyAddMsg += NumberHelper.format(total);
+ }
+
+ // show them msg
+ Common.tell(player, TranslationManager.string(player, Translations.MONEY_ADD, "currency", moneyAddMsg));
+
+ final Transaction transaction = new ShopTransaction(
+ UUID.randomUUID(),
+ shopContent.getId(),
+ shopContent.getShopId(),
+ shopContent.getOwningShop().getDisplayName(),
+ Transaction.TransactionType.SELL,
+ shopContent.getType(),
+ player.getUniqueId(),
+ player.getName(),
+ shopContent.getRawItem(),
+ shopContent.getCurrencyDisplayName(),
+ shopContent.isCurrencyOfItem() ? (int) total : total,
+ amountToSell,
+ System.currentTimeMillis()
+ );
+
+ final ShopTransactionEvent transactionEvent = new ShopTransactionEvent(transaction);
+ Shops.getInstance().getServer().getPluginManager().callEvent(transactionEvent);
+ });
+ }
+}
diff --git a/src/main/java/ca/tweetzy/shops/impl/currency/EcoBitsCurrency.java b/src/main/java/ca/tweetzy/shops/impl/currency/EcoBitsCurrency.java
new file mode 100644
index 0000000..894f923
--- /dev/null
+++ b/src/main/java/ca/tweetzy/shops/impl/currency/EcoBitsCurrency.java
@@ -0,0 +1,51 @@
+package ca.tweetzy.shops.impl.currency;
+
+import ca.tweetzy.flight.comp.enums.CompMaterial;
+import ca.tweetzy.shops.api.currency.IconableCurrency;
+import com.willfp.ecobits.currencies.Currencies;
+import com.willfp.ecobits.currencies.Currency;
+import com.willfp.ecobits.currencies.CurrencyUtils;
+import org.bukkit.OfflinePlayer;
+
+import java.math.BigDecimal;
+
+public final class EcoBitsCurrency extends IconableCurrency {
+
+ private final Currency currency;
+
+ public EcoBitsCurrency(String currencyName) {
+ super("EcoBits", currencyName, "", CompMaterial.PAPER.parseItem());
+ this.currency = Currencies.getByID(currencyName.toLowerCase());
+
+ if (this.currency != null) {
+ setDisplayName(this.currency.getName());
+ }
+ }
+
+ @Override
+ public boolean has(OfflinePlayer player, double amount) {
+ if (this.currency == null)
+ return false;
+
+ return CurrencyUtils.getBalance(player, currency).doubleValue() >= amount;
+ }
+
+ @Override
+ public boolean withdraw(OfflinePlayer player, double amount) {
+ if (this.currency == null)
+ return false;
+
+ CurrencyUtils.setBalance(player, currency, BigDecimal.valueOf(CurrencyUtils.getBalance(player, currency).doubleValue() - amount));
+ return true;
+ }
+
+ @Override
+ public boolean deposit(OfflinePlayer player, double amount) {
+ if (this.currency == null)
+ return false;
+
+ CurrencyUtils.setBalance(player, currency, BigDecimal.valueOf(CurrencyUtils.getBalance(player, currency).doubleValue() + amount));
+ return true;
+ }
+}
+
diff --git a/src/main/java/ca/tweetzy/shops/impl/manager/CurrencyManager.java b/src/main/java/ca/tweetzy/shops/impl/manager/CurrencyManager.java
index fb9bb9c..e773818 100644
--- a/src/main/java/ca/tweetzy/shops/impl/manager/CurrencyManager.java
+++ b/src/main/java/ca/tweetzy/shops/impl/manager/CurrencyManager.java
@@ -5,6 +5,7 @@
import ca.tweetzy.shops.api.manager.ListManager;
import ca.tweetzy.shops.impl.currency.ItemCurrency;
import ca.tweetzy.shops.impl.currency.VaultCurrency;
+import ca.tweetzy.shops.model.currency.EcoBitsEconomyLoader;
import ca.tweetzy.shops.model.currency.FundsEconomyLoader;
import ca.tweetzy.shops.model.currency.UltraEconomyLoader;
import ca.tweetzy.shops.settings.Settings;
@@ -80,5 +81,8 @@ public void load() {
if (Bukkit.getServer().getPluginManager().isPluginEnabled("Funds"))
new FundsEconomyLoader().getCurrencies().forEach(this::add);
+
+ if (Bukkit.getServer().getPluginManager().isPluginEnabled("EcoBits"))
+ new EcoBitsEconomyLoader().getCurrencies().forEach(this::add);
}
}
diff --git a/src/main/java/ca/tweetzy/shops/impl/shop/ShopLayout.java b/src/main/java/ca/tweetzy/shops/impl/shop/ShopLayout.java
index 753e176..636a9cb 100644
--- a/src/main/java/ca/tweetzy/shops/impl/shop/ShopLayout.java
+++ b/src/main/java/ca/tweetzy/shops/impl/shop/ShopLayout.java
@@ -27,13 +27,14 @@ public final class ShopLayout implements ShopDisplay {
private int searchButtonSlot;
private int filterButtonSlot;
private int cartButtonSlot;
+ private int sellButtonSlot;
private List fillSlots;
private Map decorations;
private ItemStack background;
public ShopLayout() {
- this(6, 45, 48, 50, 49, 52, 53, InventoryBorder.getInsideBorders(6), new HashMap<>(), QuickItem.bg(CompMaterial.BLACK_STAINED_GLASS_PANE.parseItem()));
+ this(6, 45, 48, 50, 49, 52, 53,47, InventoryBorder.getInsideBorders(6), new HashMap<>(), QuickItem.bg(CompMaterial.BLACK_STAINED_GLASS_PANE.parseItem()));
}
@Override
@@ -106,6 +107,16 @@ public void setCartButtonSlot(int slot) {
this.cartButtonSlot = slot;
}
+ @Override
+ public int getSellButtonSlot() {
+ return this.sellButtonSlot;
+ }
+
+ @Override
+ public void setSellButtonSlot(int slot) {
+ this.sellButtonSlot = slot;
+ }
+
@Override
public List getFillSlots() {
return this.fillSlots;
@@ -146,6 +157,7 @@ public String getJSONString() {
object.addProperty("filterButtonSlot", this.filterButtonSlot);
object.addProperty("searchButtonSlot", this.searchButtonSlot);
object.addProperty("cartButtonSlot", this.cartButtonSlot);
+ object.addProperty("sellButtonSlot", this.sellButtonSlot);
object.addProperty("rows", this.rows);
final JsonArray fillSlotsArray = new JsonArray();
@@ -192,6 +204,7 @@ public static ShopLayout decodeJSON(@NonNull final String json) {
parentObject.get("searchButtonSlot").getAsInt(),
parentObject.get("filterButtonSlot").getAsInt(),
parentObject.has("cartButtonSlot") ? parentObject.get("cartButtonSlot").getAsInt() : 53,
+ parentObject.has("sellButtonSlot") ? parentObject.get("sellButtonSlot").getAsInt() : 47,
fillSlots,
decoration,
SerializeUtil.decodeItem(parentObject.get("backgroundItem").getAsString())
diff --git a/src/main/java/ca/tweetzy/shops/model/currency/EcoBitsEconomyLoader.java b/src/main/java/ca/tweetzy/shops/model/currency/EcoBitsEconomyLoader.java
new file mode 100644
index 0000000..d79a3bc
--- /dev/null
+++ b/src/main/java/ca/tweetzy/shops/model/currency/EcoBitsEconomyLoader.java
@@ -0,0 +1,43 @@
+package ca.tweetzy.shops.model.currency;
+
+import ca.tweetzy.shops.api.currency.AbstractCurrency;
+import ca.tweetzy.shops.impl.currency.EcoBitsCurrency;
+import ca.tweetzy.shops.settings.Settings;
+import com.willfp.ecobits.currencies.Currencies;
+import com.willfp.ecobits.currencies.Currency;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class EcoBitsEconomyLoader extends CurrencyLoader {
+
+ public EcoBitsEconomyLoader() {
+ super("EcoBits");
+ }
+
+
+ @Override
+ public List getCurrencies() {
+ final List currencies = new ArrayList<>();
+
+ for (Currency currency : Currencies.values()) {
+ boolean blackListed = false;
+
+ for (String blacklisted : Settings.CURRENCY_BLACKLISTED.getStringList()) {
+ final String[] blacklistSplit = blacklisted.split(":");
+
+ if (blacklistSplit.length != 2) continue;
+ if (!blacklistSplit[0].equalsIgnoreCase(this.owningPlugin)) continue;
+
+ if (blacklistSplit[1].equalsIgnoreCase(currency.getName()))
+ blackListed = true;
+
+ }
+
+ if (!blackListed)
+ currencies.add(new EcoBitsCurrency(currency.getId()));
+ }
+
+ return currencies;
+ }
+}
diff --git a/src/main/java/ca/tweetzy/shops/settings/Settings.java b/src/main/java/ca/tweetzy/shops/settings/Settings.java
index 74b11dd..5485329 100644
--- a/src/main/java/ca/tweetzy/shops/settings/Settings.java
+++ b/src/main/java/ca/tweetzy/shops/settings/Settings.java
@@ -21,6 +21,8 @@ public final class Settings extends FlightSettings {
public static ConfigEntry TAX_ENABLED = create("settings.tax.enabled", false).withComment("If true, will apply sales tax to the total when a user is buying an item");
public static ConfigEntry TAX_AMOUNT = create("settings.tax.percentage", 13.0).withComment("The tax percentage. By default it's 13%");
public static ConfigEntry TAX_SELL = create("settings.tax.tax on sell", false).withComment("If true, selling items to a shop will remove tax percentage");
+ public static ConfigEntry GLOBAL_GUI_CLICK_DELAY = create("settings.click delays.global", 1000).withComment("In milliseconds, how long should the delay between clicks be (set to -1 to disable)");
+ public static ConfigEntry SEND_CLICK_DELAY_MSG = create("settings.send click delay message", false).withComment("Should shops tell the player to slow down? Or just send nothing.");
/*
========================= GUI STUFF =========================
@@ -49,6 +51,19 @@ public final class Settings extends FlightSettings {
"slot:44 item:BLACK_STAINED_GLASS_PANE"
), "TBD");
+ public static ConfigEntry GUI_SHOPS_QUICK_SELL_DECORATIONS = create("gui.shops quick sell.decorations", List.of(
+ "slot:0-8 item:BLACK_STAINED_GLASS_PANE",
+ "slot:45-53 item:BLACK_STAINED_GLASS_PANE",
+ "slot:9 item:BLACK_STAINED_GLASS_PANE",
+ "slot:18 item:BLACK_STAINED_GLASS_PANE",
+ "slot:27 item:BLACK_STAINED_GLASS_PANE",
+ "slot:36 item:BLACK_STAINED_GLASS_PANE",
+ "slot:17 item:BLACK_STAINED_GLASS_PANE",
+ "slot:26 item:BLACK_STAINED_GLASS_PANE",
+ "slot:35 item:BLACK_STAINED_GLASS_PANE",
+ "slot:44 item:BLACK_STAINED_GLASS_PANE"
+ ), "TBD");
+
public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_EXIT = create("gui.layout control picker.items.exit.item", CompMaterial.BARRIER.name());
public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_PREV_PAGE = create("gui.layout control picker.items.prev page.item", CompMaterial.ARROW.name());
@@ -56,10 +71,13 @@ public final class Settings extends FlightSettings {
public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_SEARCH = create("gui.layout control picker.items.search.item", CompMaterial.DARK_OAK_SIGN.name());
public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_FILTER = create("gui.layout control picker.items.filter.item", CompMaterial.REPEATER.name());
public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_CART = create("gui.layout control picker.items.cart.item", CompMaterial.MINECART.name());
+ public static ConfigEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL = create("gui.layout control picker.items.sell.item", CompMaterial.ENDER_CHEST.name());
+
public static ConfigEntry GUI_SHOP_CONTENT_ITEMS_SEARCH = create("gui.shop contents.items.review.item", CompMaterial.DARK_OAK_SIGN.name());
public static ConfigEntry GUI_SHOP_CONTENT_ITEMS_FILTER = create("gui.shop contents.items.filter.item", CompMaterial.REPEATER.name());
public static ConfigEntry GUI_SHOP_CONTENT_ITEMS_CART = create("gui.shop contents.items.cart.item", CompMaterial.MINECART.name());
+ public static ConfigEntry GUI_SHOP_CONTENT_ITEMS_SELL = create("gui.shop contents.items.sell.item", CompMaterial.ENDER_CHEST.name());
public static ConfigEntry GUI_CHECKOUT_ITEMS_CHECKOUT = create("gui.checkout.items.checkout.item", CompMaterial.LIME_DYE.name());
diff --git a/src/main/java/ca/tweetzy/shops/settings/Translations.java b/src/main/java/ca/tweetzy/shops/settings/Translations.java
index 27ba395..ee6f422 100644
--- a/src/main/java/ca/tweetzy/shops/settings/Translations.java
+++ b/src/main/java/ca/tweetzy/shops/settings/Translations.java
@@ -26,6 +26,7 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry ITEM_CANNOT_BE_AIR = create("error.item cannot be air", "&cYou cannot add air to the shop.");
public static TranslationEntry CHECKOUT_NOT_MIN_QTY = create("error.checkout is not min qty", "&cYou must buy at least &fx&e%shop_item_purchase_qty% &cof this item!");
public static TranslationEntry NOT_ALLOWED_TO_USE_SHOP = create("error.no shop permission", "&cYou are not allowed to use that shop");
+ public static TranslationEntry CLICKING_TOO_FAST = create("error.clicking too fast", "&cHey, you are clicking too fast, slow it down :)");
/*
=================== INFORMATIONAL ===================
@@ -33,8 +34,10 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry ADDED_ITEM_TO_SHOP = create("info.shop.add.item", "&aSuccessfully added &e%item_name% &ato &b%shop_id%");
public static TranslationEntry SHOP_IS_CLOSED = create("info.shop.closed", "&cThat shop is currently closed!");
public static TranslationEntry SHOP_DELETED = create("info.shop.deleted", "&aSuccessfully deleted that shop!");
+ public static TranslationEntry UPDATED_SHOP_BG = create("info.shop.updated background", "&aSuccessfully updated the shop background!");
public static TranslationEntry MONEY_ADD = create("info.money.add", "&f&l+ &a&l%currency%");
public static TranslationEntry MONEY_REMOVE = create("info.money.remove", "&f&l- &c&l%currency%");
+ public static TranslationEntry SELL_NOT_ALLOWED = create("info.checkout.sell not allowed", "&CThe sale of that item is not allowed!");
@@ -175,6 +178,22 @@ public Translations(@NonNull JavaPlugin plugin) {
"&b&l%right_click% &7to add to cart"
);
+ public static final TranslationEntry GUI_CHECKOUT_ITEMS_SELL_NAME = create("gui.checkout.items.sell.name", "&LConfirm Sell");
+ public static final TranslationEntry GUI_CHECKOUT_ITEMS_SELL_LORE = create("gui.checkout.items.sell.lore",
+ "&e&l%left_click% &7to sell now",
+ "&b&l%right_click% &7to add to cart"
+ );
+
+ public static final TranslationEntry GUI_CHECKOUT_ITEMS_TOGGLE_SELL_NAME = create("gui.checkout.items.toggle sell.name", "<oggle Sell/Buy");
+ public static final TranslationEntry GUI_CHECKOUT_ITEMS_TOGGLE_SELL_LORE = create("gui.checkout.items.toggle sell.lore",
+ "&7Used to toggle sell/buy mode",
+ "",
+ "&7Buy Mode&f: %is_true%",
+ "",
+ "&e&lClick &7to toggle buy/sell mode"
+ );
+
+
public static final TranslationEntry GUI_CHECKOUT_ITEMS_INCR_NAME = create("gui.checkout.items.increment.name", "&a&l+%increment_value%");
public static final TranslationEntry GUI_CHECKOUT_ITEMS_INCR_LORE = create("gui.checkout.items.increment.lore", "&e&lClick &7to increment qty");
@@ -198,6 +217,16 @@ public Translations(@NonNull JavaPlugin plugin) {
"&8&m------------------------------"
);
+ public static final TranslationEntry GUI_CHECKOUT_ITEMS_BREAKDOWN_SELL_LORE = create("gui.checkout.items.sell breakdown.lore",
+ "&8&m------------------------------",
+ "&7Selected Quantity&F: &e%checkout_item_qty%",
+ "",
+ "&A&lSell (Total)",
+ "&7Total&F: &a%checkout_item_sell_total%",
+ "",
+ "&8&m------------------------------"
+ );
+
public static final TranslationEntry GUI_CHECKOUT_ITEMS_BREAKDOWN_LORE_HAS_TAX = create("gui.checkout.items.breakdown.has tax lore", "&eServer Tax Rate &F(&7%tax_rate%&a%&f)");
public static final TranslationEntry GUI_CHECKOUT_ITEMS_BREAKDOWN_LORE_NO_TAX = create("gui.checkout.items.breakdown.no tax lore", "&cNo tax is currently applied.");
@@ -238,6 +267,13 @@ public Translations(@NonNull JavaPlugin plugin) {
"&e%shop_item_description%"
);
+ public static final TranslationEntry GUI_SHOP_QUICK_SELL_TITLE = create("gui.shop quick sell.title", "%shop_name% &8> &7Quick Sell");
+ public static final TranslationEntry GUI_SHOP_QUICK_SELL_ITEMS_SELL_NAME = create("gui.shop quick sell.items.sell.name", "&LSell Items");
+ public static final TranslationEntry GUI_SHOP_QUICK_SELL_ITEMS_SELL_LORE = create("gui.shop quick sell.items.sell.lore",
+ "&e&lClick &7to confirm sell"
+ );
+
+
public static final TranslationEntry GUI_SHOP_EDIT_TITLE = create("gui.shop edit.title", "&lShops &8> &7Edit &8> &e%shop_id%");
public static final TranslationEntry GUI_SHOP_EDIT_ITEMS_ITEM_CONTENT_LORE = create("gui.shop edit.items.item content.lore",
@@ -304,6 +340,14 @@ public Translations(@NonNull JavaPlugin plugin) {
"&e&lClick &7to view your cart."
);
+ public static TranslationEntry GUI_SHOP_CONTENTS_ITEMS_SELL_NAME = create("gui.shop contents.items.sell.name", "&lSell Items");
+ public static TranslationEntry GUI_SHOP_CONTENTS_ITEMS_SELL_LORE = create("gui.shop contents.items.sell.lore",
+ "&7Opens a quick sell menu to drop",
+ "&7any items this shop accepts to sell.",
+ "",
+ "&e&lClick &7to sell items."
+ );
+
public static final TranslationEntry GUI_SHOP_CONTENTS_ITEMS_ITEM_CONTENT_BASE_LORE = create("gui.shop contents.items.content.lore.base lore",
"&8&m------------------------------",
"%shop_content_desc_info%",
@@ -366,7 +410,10 @@ public Translations(@NonNull JavaPlugin plugin) {
"&7How the shop content will be positioned,",
"&7and any extra decoration items in the gui",
"",
- "&e&lClick &7to edit the layout/decoration"
+ "&e&l%left_click% &7to edit the layout/decoration",
+ "&b&l%right_click% &7with item to set background",
+ "&7If you right click with nothing it will set",
+ "&7the background item to nothing (AIR)"
);
public static final TranslationEntry GUI_SHOP_SETTINGS_ITEMS_OPEN_NAME = create("gui.shop settings.items.open.name", "&lOpen/Close Shop");
@@ -623,6 +670,11 @@ public Translations(@NonNull JavaPlugin plugin) {
"&7items from other shops."
);
+ public static TranslationEntry GUI_LAYOUT_EDITOR_ITEMS_SELL_NAME = create("gui.layout editor.items.sell.name", "&lSell");
+ public static TranslationEntry GUI_LAYOUT_EDITOR_ITEMS_SELL_LORE = create("gui.layout editor.items.sell.lore",
+ "&7Used to quickly sell anything",
+ "&7that can be sold at this shop."
+ );
public static TranslationEntry GUI_LAYOUT_CONTROL_PICKER_TITLE = create("gui.layout control picker.title", "&EShops &f- &7Select Layout Control");
public static TranslationEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_EXIT_NAME = create("gui.layout control picker.items.exit.name", "&lExit Button");
@@ -661,8 +713,14 @@ public Translations(@NonNull JavaPlugin plugin) {
"&e&l%left_click% &7to select this control"
);
+ public static TranslationEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL_NAME = create("gui.layout control picker.items.sell.name", "&lSell Button");
+ public static TranslationEntry GUI_LAYOUT_CONTROL_PICKER_ITEMS_SELL_LORE = create("gui.layout control picker.items.sell.lore",
+ "&7Used to quickly sell items at this shop.",
+ "&e&l%left_click% &7to select this control"
+ );
+
public static void init() {
- new Translations(Shops.getInstance()).setup();
+ new Translations(Shops.getInstance()).setup(Shops.getInstance());
}
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 7c2d4be..d0bc093 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -7,4 +7,7 @@ api-version: 1.16
softdepend:
- PlaceholderAPI
- - Vault
\ No newline at end of file
+ - Vault
+ - EcoBits
+ - Funds
+ - UltraEconomy
\ No newline at end of file