Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add item group for sell sign #5321

Open
wants to merge 4 commits into
base: 2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
EconomyLayers.init();
}

private ItemGroups itemGroups;

public Essentials() {
}

Expand Down Expand Up @@ -358,6 +360,10 @@ public void onEnable() {
confList.add(jails);
execTimer.mark("Init(Jails)");

itemGroups = new ItemGroups(this);
confList.add(itemGroups);
execTimer.mark("Init(ItemGroups)");

EconomyLayers.onEnable(this);

//Spawner item provider only uses one but it's here for legacy...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.earth2me.essentials;

import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;

public class ItemGroupQuery {

private final String itemGroup;
private final int amount;

public ItemGroupQuery(String group, int quantity) {
this.itemGroup = group;
this.amount = quantity;
}

public boolean contains(IEssentials ess, Material item){
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_ITEMS, NamespacedKey.minecraft(itemGroup), Material.class);
if (tag != null && tag.isTagged(item)) {
return true;
}
final ItemGroups groupsConfig = new ItemGroups(ess);
return groupsConfig.getItemGroup(itemGroup).contains(item);
}

public String getItemGroup() {
return itemGroup;
}

public int getAmount() {
return amount;
}

@Override
public String toString() {
return "ItemGroupQuery{" +
"itemGroup='" + itemGroup + '\'' +
", quantity=" + amount +
'}';
}
}
48 changes: 48 additions & 0 deletions Essentials/src/main/java/com/earth2me/essentials/ItemGroups.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.earth2me.essentials;

import com.earth2me.essentials.config.EssentialsConfiguration;
import net.ess3.api.IEssentials;
import net.ess3.api.IItemGroups;
import org.bukkit.Material;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class ItemGroups implements IItemGroups {

private final EssentialsConfiguration config;
private final Map<String, List<Material>> itemGroups = new HashMap<>();

public ItemGroups(final IEssentials ess) {
this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "groups.yml"));
reloadConfig();
}

@Override
public void reloadConfig() {
synchronized (itemGroups) {
config.load();
itemGroups.clear();

for (String id : config.getKeys()) {
final List<String> list = config.getList(id, String.class);
itemGroups.put(id, list.stream().map(Material::matchMaterial).collect(Collectors.toList()));
}
}
}

@Override
public List<Material> getItemGroup(String group) {
return itemGroups.getOrDefault(group, Collections.emptyList());
}

@Override
public Set<String> getItemGroups() {
return itemGroups.keySet();
}
}
37 changes: 29 additions & 8 deletions Essentials/src/main/java/com/earth2me/essentials/Trade.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,39 +31,45 @@ public class Trade {
private final transient Trade fallbackTrade;
private final transient BigDecimal money;
private final transient ItemStack itemStack;
private final transient ItemGroupQuery itemGroupQuery;
private final transient Integer exp;
private final transient IEssentials ess;

public Trade(final String command, final IEssentials ess) {
this(command, null, null, null, null, ess);
this(command, null, null, null, null, null, ess);
}

public Trade(final String command, final Trade fallback, final IEssentials ess) {
this(command, fallback, null, null, null, ess);
this(command, fallback, null, null, null, null, ess);
}

@Deprecated
public Trade(final double money, final com.earth2me.essentials.IEssentials ess) {
this(null, null, BigDecimal.valueOf(money), null, null, (IEssentials) ess);
this(null, null, BigDecimal.valueOf(money), null, null, null, (IEssentials) ess);
}

public Trade(final BigDecimal money, final IEssentials ess) {
this(null, null, money, null, null, ess);
this(null, null, money, null, null, null, ess);
}

public Trade(final ItemStack items, final IEssentials ess) {
this(null, null, null, items, null, ess);
this(null, null, null, items, null, null, ess);
}

public Trade(final int exp, final IEssentials ess) {
this(null, null, null, null, exp, ess);
this(null, null, null, null, null, exp, ess);
}

private Trade(final String command, final Trade fallback, final BigDecimal money, final ItemStack item, final Integer exp, final IEssentials ess) {
public Trade(final ItemGroupQuery query, final IEssentials ess){
this(null, null, null, null, query, null, ess);
}

private Trade(final String command, final Trade fallback, final BigDecimal money, final ItemStack item, final ItemGroupQuery groupQuery, final Integer exp, final IEssentials ess) {
this.command = command;
this.fallbackTrade = fallback;
this.money = money;
this.itemStack = item;
this.itemGroupQuery = groupQuery;
this.exp = exp;
this.ess = ess;
}
Expand Down Expand Up @@ -146,7 +152,7 @@ public static void log(final String type, final String subtype, final String eve
sb.append(loc.getBlockY()).append(",");
sb.append(loc.getBlockZ()).append(",");
}

if (endBalance == null) {
sb.append(",");
} else {
Expand Down Expand Up @@ -303,6 +309,17 @@ public void charge(final IUser user, final CompletableFuture<Boolean> future) {
Inventories.removeItemAmount(user.getBase(), getItemStack(), getItemStack().getAmount());
user.getBase().updateInventory();
}
if(getItemGroupQuery() != null){
if(ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemgroup " +getItemGroupQuery().toString());
}
if (!Inventories.containsAtLeast(user.getBase(), ess, getItemGroupQuery())) {
future.completeExceptionally(new ChargeException(tl("missingItems", getItemGroupQuery().getAmount(), "~"+getItemGroupQuery().getItemGroup().toLowerCase(Locale.ENGLISH).replace("_", " "))));
return;
}
Inventories.removeItemAmount(user.getBase(), ess, getItemGroupQuery());
user.getBase().updateInventory();
}
if (command != null) {
final BigDecimal cost = getCommandCost(user);
if (!user.canAfford(cost) && cost.signum() > 0) {
Expand Down Expand Up @@ -335,6 +352,10 @@ public ItemStack getItemStack() {
return itemStack;
}

public ItemGroupQuery getItemGroupQuery() {
return itemGroupQuery;
}

public Integer getExperience() {
return exp;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.earth2me.essentials.craftbukkit;

import com.earth2me.essentials.ItemGroupQuery;
import com.earth2me.essentials.ItemGroups;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.IEssentials;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
Expand Down Expand Up @@ -85,6 +88,22 @@ public static boolean containsAtLeast(final Player player, final ItemStack item,
return false;
}

public static boolean containsAtLeast(final Player player, IEssentials ess, final ItemGroupQuery query) {
int amount = query.getAmount();
for (final ItemStack invItem : player.getInventory().getContents()) {
if (isEmpty(invItem)) {
continue;
}
if (query.contains(ess, invItem.getType())) {
amount -= invItem.getAmount();
if (amount <= 0) {
return true;
}
}
}
return false;
}

public static boolean hasSpace(final Player player, final int maxStack, final boolean includeArmor, ItemStack... items) {
items = normalizeItems(cloneItems(items));
final InventoryData inventoryData = parseInventoryData(player.getInventory(), items, maxStack, includeArmor);
Expand Down Expand Up @@ -276,6 +295,41 @@ public static boolean removeItemAmount(final Player player, final ItemStack toRe
return false;
}

public static boolean removeItemAmount(final Player player, final IEssentials ess, final ItemGroupQuery query) {
final List<Integer> clearSlots = new ArrayList<>();
final ItemStack[] items = player.getInventory().getContents();

int amount = query.getAmount();
for (int i = 0; i < items.length; i++) {
final ItemStack item = items[i];
if (isEmpty(item)) {
continue;
}

if (query.contains(ess, item.getType())) {
if (item.getAmount() >= amount) {
item.setAmount(item.getAmount() - amount);
player.getInventory().setItem(i, item);
for (final int slot : clearSlots) {
clearSlot(player, slot);
}
return true;
} else {
amount -= item.getAmount();
clearSlots.add(i);
}

if (amount == 0) {
for (final int slot : clearSlots) {
clearSlot(player, slot);
}
return true;
}
}
}
return false;
}

public static void clearSlot(final Player player, final int slot) {
final ItemStack item = player.getInventory().getItem(slot);
if (!isEmpty(item)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.ItemGroupQuery;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
Expand Down Expand Up @@ -338,6 +339,12 @@ protected final void validateTrade(final ISign sign, final int amountIndex, fina
sign.setLine(itemIndex, "exp");
return;
}
if(itemType.startsWith("~")){
final int amount = getIntegerPositive(getSignText(sign, amountIndex));
sign.setLine(amountIndex, Integer.toString(amount));
sign.setLine(itemIndex, "§6~§r"+itemType.substring(1));
return;
}
final Trade trade = getTrade(sign, amountIndex, itemIndex, player, ess);
final ItemStack item = trade.getItemStack();
sign.setLine(amountIndex, Integer.toString(item.getAmount()));
Expand All @@ -354,6 +361,11 @@ protected final Trade getTrade(final ISign sign, final int amountIndex, final in
final int amount = getIntegerPositive(getSignText(sign, amountIndex));
return new Trade(amount, ess);
}
if(itemType.startsWith("§6~§r")){
final int amount = Math.min(getIntegerPositive(getSignText(sign, amountIndex)), 64 * player.getBase().getInventory().getSize());
final ItemGroupQuery query = new ItemGroupQuery(itemType.substring(5), amount);
return new Trade(query, ess);
}
final ItemStack item = getItemStack(itemType, 1, allowId, ess);
final int amount = Math.min(getIntegerPositive(getSignText(sign, amountIndex)), item.getType().getMaxStackSize() * player.getBase().getInventory().getSize());
if (item.getType() == Material.AIR || amount < 1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.earth2me.essentials.signs;

import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.ItemGroupQuery;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.Trade.OverflowType;
import com.earth2me.essentials.User;
Expand Down Expand Up @@ -30,13 +31,24 @@ protected boolean onSignInteract(final ISign sign, final User player, final Stri
// Check if the player is trying to sell in bulk.
if (ess.getSettings().isAllowBulkBuySell() && player.getBase().isSneaking()) {
final ItemStack heldItem = player.getItemInHand();
if (charge.getItemStack().isSimilar(heldItem)) {
if (charge.getItemStack() != null && charge.getItemStack().isSimilar(heldItem)) {
final int initialItemAmount = charge.getItemStack().getAmount();
final int newItemAmount = heldItem.getAmount();
final ItemStack item = charge.getItemStack();
item.setAmount(newItemAmount);
charge = new Trade(item, ess);

final BigDecimal chargeAmount = money.getMoney();
//noinspection BigDecimalMethodWithoutRoundingCalled
BigDecimal pricePerSingleItem = chargeAmount.divide(new BigDecimal(initialItemAmount));
pricePerSingleItem = pricePerSingleItem.multiply(new BigDecimal(newItemAmount));
money = new Trade(pricePerSingleItem, ess);
}else if(charge.getItemGroupQuery() != null && charge.getItemGroupQuery().contains(ess, heldItem.getType())){
final ItemGroupQuery groupQuery = charge.getItemGroupQuery();
final int initialItemAmount = groupQuery.getAmount();
final int newItemAmount = heldItem.getAmount();
charge = new Trade(new ItemGroupQuery(groupQuery.getItemGroup(), newItemAmount), ess);

final BigDecimal chargeAmount = money.getMoney();
//noinspection BigDecimalMethodWithoutRoundingCalled
BigDecimal pricePerSingleItem = chargeAmount.divide(new BigDecimal(initialItemAmount));
Expand Down
26 changes: 26 additions & 0 deletions Essentials/src/main/java/net/ess3/api/IItemGroups.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.ess3.api;

import com.earth2me.essentials.IConf;
import org.bukkit.Material;

import java.util.List;
import java.util.Set;

/**
* Provides access to the storage of item groups. Maintainers should add methods to <i>this interface</i>.
*/
public interface IItemGroups extends IConf {

/**
* Gets the set of saved item groups from config file
* @return the set of item groups
*/
Set<String> getItemGroups();

/**
* Gets the list of item materials inside an item group
* @param group the item group
* @return a list of items in the item group
*/
List<Material> getItemGroup(String group);
}
13 changes: 13 additions & 0 deletions Essentials/src/main/resources/groups.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#EssentialsX item group configuration
#Item groups are currently used only by sell sign
#By creating a group here and using ~[group_id] on the sign
#Any player will be able to sell items with one of the types written here

#You can use minecraft tags as groups, for reference https://minecraft.fandom.com/wiki/Tag#Item_tags
#Example
#dirt:
# - DIRT
# - GRASS
# - PODZOL
# - COARSE_DIRT
# - ROOTED_DIRT