Use the Things API for entry fees and class prices.
While it doesn't really make sense to have class prices be a Thing (or maybe it does?), this does get rid of the dirty "ItemStacks wit ID -29" hack for economy money, which will eventually break, when the upstream int-based ID API breaks.
This commit is contained in:
@@ -4,6 +4,7 @@ import static org.bukkit.Material.*;
|
|||||||
|
|
||||||
import com.garbagemule.MobArena.framework.Arena;
|
import com.garbagemule.MobArena.framework.Arena;
|
||||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||||
|
import com.garbagemule.MobArena.things.Thing;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -28,14 +29,14 @@ public class ArenaClass
|
|||||||
private Map<String,Boolean> perms;
|
private Map<String,Boolean> perms;
|
||||||
private Map<String,Boolean> lobbyperms;
|
private Map<String,Boolean> lobbyperms;
|
||||||
private boolean unbreakableWeapons, unbreakableArmor;
|
private boolean unbreakableWeapons, unbreakableArmor;
|
||||||
private double price;
|
private Thing price;
|
||||||
private Location classchest;
|
private Location classchest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new, empty arena class with the given name.
|
* Create a new, empty arena class with the given name.
|
||||||
* @param name the class name as it appears in the config-file
|
* @param name the class name as it appears in the config-file
|
||||||
*/
|
*/
|
||||||
public ArenaClass(String name, double price, boolean unbreakableWeapons, boolean unbreakableArmor) {
|
public ArenaClass(String name, Thing price, boolean unbreakableWeapons, boolean unbreakableArmor) {
|
||||||
this.configName = name;
|
this.configName = name;
|
||||||
this.lowercaseName = name.toLowerCase().replace(" ", "");
|
this.lowercaseName = name.toLowerCase().replace(" ", "");
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ public class ArenaClass
|
|||||||
return unbreakableArmor;
|
return unbreakableArmor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getPrice() {
|
public Thing getPrice() {
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +378,7 @@ public class ArenaClass
|
|||||||
public static class MyItems extends ArenaClass {
|
public static class MyItems extends ArenaClass {
|
||||||
private ArenaMaster am;
|
private ArenaMaster am;
|
||||||
|
|
||||||
public MyItems(double price, boolean unbreakableWeapons, boolean unbreakableArmor, ArenaMaster am) {
|
public MyItems(Thing price, boolean unbreakableWeapons, boolean unbreakableArmor, ArenaMaster am) {
|
||||||
super("My Items", price, unbreakableWeapons, unbreakableArmor);
|
super("My Items", price, unbreakableWeapons, unbreakableArmor);
|
||||||
this.am = am;
|
this.am = am;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.bukkit.inventory.PlayerInventory;
|
|||||||
import org.bukkit.permissions.PermissionAttachment;
|
import org.bukkit.permissions.PermissionAttachment;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -119,7 +120,7 @@ public class ArenaImpl implements Arena
|
|||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
private ArenaListener eventListener;
|
private ArenaListener eventListener;
|
||||||
private List<ItemStack> entryFee;
|
private List<Thing> entryFee;
|
||||||
private TimeStrategy timeStrategy;
|
private TimeStrategy timeStrategy;
|
||||||
private AutoStartTimer autoStartTimer;
|
private AutoStartTimer autoStartTimer;
|
||||||
private StartDelayTimer startDelayTimer;
|
private StartDelayTimer startDelayTimer;
|
||||||
@@ -190,10 +191,26 @@ public class ArenaImpl implements Arena
|
|||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
this.eventListener = new ArenaListener(this, plugin);
|
this.eventListener = new ArenaListener(this, plugin);
|
||||||
this.entryFee = ItemParser.parseItems(settings.getString("entry-fee", ""));
|
|
||||||
this.allowMonsters = world.getAllowMonsters();
|
this.allowMonsters = world.getAllowMonsters();
|
||||||
this.allowAnimals = world.getAllowAnimals();
|
this.allowAnimals = world.getAllowAnimals();
|
||||||
|
|
||||||
|
this.entryFee = new ArrayList<>();
|
||||||
|
String feeString = settings.getString("entry-fee", "");
|
||||||
|
if (feeString != null && !feeString.isEmpty()) {
|
||||||
|
for (String fee : feeString.split(",")) {
|
||||||
|
try {
|
||||||
|
Thing thing = plugin.getThingManager().parse(fee.trim());
|
||||||
|
if (thing == null) {
|
||||||
|
plugin.getLogger().warning("Failed to parse entry fee: " + fee.trim());
|
||||||
|
} else {
|
||||||
|
this.entryFee.add(thing);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().severe("Exception parsing entry fee '" + fee.trim() + "': " + e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.autoStartTimer = new AutoStartTimer(this);
|
this.autoStartTimer = new AutoStartTimer(this);
|
||||||
this.startDelayTimer = new StartDelayTimer(this, autoStartTimer);
|
this.startDelayTimer = new StartDelayTimer(this, autoStartTimer);
|
||||||
|
|
||||||
@@ -289,7 +306,7 @@ public class ArenaImpl implements Arena
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getEntryFee() {
|
public List<Thing> getEntryFee() {
|
||||||
return entryFee;
|
return entryFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,9 +529,9 @@ public class ArenaImpl implements Arena
|
|||||||
assignClassPermissions(p);
|
assignClassPermissions(p);
|
||||||
arenaPlayerMap.get(p).resetStats();
|
arenaPlayerMap.get(p).resetStats();
|
||||||
|
|
||||||
double price = arenaPlayerMap.get(p).getArenaClass().getPrice();
|
Thing price = arenaPlayerMap.get(p).getArenaClass().getPrice();
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
plugin.takeMoney(p, price);
|
price.takeFrom(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
scoreboard.addPlayer(p);
|
scoreboard.addPlayer(p);
|
||||||
@@ -1523,23 +1540,11 @@ public class ArenaImpl implements Arena
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(Player p) {
|
public boolean canAfford(Player p) {
|
||||||
if (entryFee.isEmpty()) return true;
|
for (Thing fee : entryFee) {
|
||||||
|
if (!fee.heldBy(p)) {
|
||||||
PlayerInventory inv = p.getInventory();
|
|
||||||
for (ItemStack stack : entryFee) {
|
|
||||||
// Economy money
|
|
||||||
if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) {
|
|
||||||
if (!plugin.hasEnough(p, stack)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Normal stack
|
|
||||||
else {
|
|
||||||
if (!inv.contains(stack.getType(), stack.getAmount())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1547,31 +1552,8 @@ public class ArenaImpl implements Arena
|
|||||||
public boolean takeFee(Player p) {
|
public boolean takeFee(Player p) {
|
||||||
if (entryFee.isEmpty()) return true;
|
if (entryFee.isEmpty()) return true;
|
||||||
|
|
||||||
PlayerInventory inv = p.getInventory();
|
for (Thing fee : entryFee) {
|
||||||
|
fee.takeFrom(p);
|
||||||
// Take some economy money
|
|
||||||
for (ItemStack stack : InventoryUtils.extractAll(MobArena.ECONOMY_MONEY_ID, entryFee)) {
|
|
||||||
plugin.takeMoney(p, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take any other items
|
|
||||||
for (ItemStack fee : entryFee) {
|
|
||||||
if (fee.getTypeId() < 0) continue;
|
|
||||||
|
|
||||||
int remaining = fee.getAmount();
|
|
||||||
while (remaining > 0) {
|
|
||||||
int slot = inv.first(fee.getType());
|
|
||||||
if (slot < 0) break;
|
|
||||||
|
|
||||||
ItemStack item = inv.getItem(slot);
|
|
||||||
remaining -= item.getAmount();
|
|
||||||
if (remaining >= 0) {
|
|
||||||
inv.setItem(slot, null);
|
|
||||||
} else {
|
|
||||||
item.setAmount(-remaining);
|
|
||||||
inv.setItem(slot, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messenger.tell(p, Msg.JOIN_FEE_PAID.format(MAUtils.listToString(entryFee, plugin)));
|
messenger.tell(p, Msg.JOIN_FEE_PAID.format(MAUtils.listToString(entryFee, plugin)));
|
||||||
@@ -1583,16 +1565,8 @@ public class ArenaImpl implements Arena
|
|||||||
if (entryFee.isEmpty()) return true;
|
if (entryFee.isEmpty()) return true;
|
||||||
if (!inLobby(p)) return false;
|
if (!inLobby(p)) return false;
|
||||||
|
|
||||||
// Refund economy money
|
for (Thing fee : entryFee) {
|
||||||
for (ItemStack stack : InventoryUtils.extractAll(MobArena.ECONOMY_MONEY_ID, entryFee)) {
|
fee.giveTo(p);
|
||||||
plugin.giveMoney(p, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refund other items.
|
|
||||||
for (ItemStack stack : entryFee) {
|
|
||||||
if (stack.getTypeId() > 0) {
|
|
||||||
p.getInventory().addItem(stack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1067,10 +1067,10 @@ public class ArenaListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check price, balance, and inform
|
// Check price, balance, and inform
|
||||||
double price = newAC.getPrice();
|
Thing price = newAC.getPrice();
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
if (!plugin.hasEnough(p, price)) {
|
if (!price.heldBy(p)) {
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_TOO_EXPENSIVE, plugin.economyFormat(price));
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_TOO_EXPENSIVE, price.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1095,7 +1095,7 @@ public class ArenaListener
|
|||||||
return true;
|
return true;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
private void delayAssignClass(final Player p, final String className, final double price, final Sign sign) {
|
private void delayAssignClass(final Player p, final String className, final Thing price, final Sign sign) {
|
||||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() {
|
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!className.equalsIgnoreCase("random")) {
|
if (!className.equalsIgnoreCase("random")) {
|
||||||
@@ -1111,8 +1111,8 @@ public class ArenaListener
|
|||||||
}
|
}
|
||||||
arena.assignClass(p, className);
|
arena.assignClass(p, className);
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(className).getConfigName());
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(className).getConfigName());
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, plugin.economyFormat(price));
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, price.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import static com.garbagemule.MobArena.util.config.ConfigUtils.parseLocation;
|
|||||||
import com.garbagemule.MobArena.ArenaClass.ArmorType;
|
import com.garbagemule.MobArena.ArenaClass.ArmorType;
|
||||||
import com.garbagemule.MobArena.framework.Arena;
|
import com.garbagemule.MobArena.framework.Arena;
|
||||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||||
|
import com.garbagemule.MobArena.things.Thing;
|
||||||
import com.garbagemule.MobArena.util.ItemParser;
|
import com.garbagemule.MobArena.util.ItemParser;
|
||||||
import com.garbagemule.MobArena.util.TextUtils;
|
import com.garbagemule.MobArena.util.TextUtils;
|
||||||
import com.garbagemule.MobArena.util.config.ConfigUtils;
|
import com.garbagemule.MobArena.util.config.ConfigUtils;
|
||||||
@@ -294,7 +295,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
if (section == null) {
|
if (section == null) {
|
||||||
// We may not have a class entry for My Items, but that's fine
|
// We may not have a class entry for My Items, but that's fine
|
||||||
if (classname.equals("My Items")) {
|
if (classname.equals("My Items")) {
|
||||||
ArenaClass myItems = new ArenaClass.MyItems(0, false, false, this);
|
ArenaClass myItems = new ArenaClass.MyItems(null, false, false, this);
|
||||||
classes.put(lowercase, myItems);
|
classes.put(lowercase, myItems);
|
||||||
return myItems;
|
return myItems;
|
||||||
}
|
}
|
||||||
@@ -307,15 +308,14 @@ public class ArenaMasterImpl implements ArenaMaster
|
|||||||
boolean arms = section.getBoolean("unbreakable-armor", true);
|
boolean arms = section.getBoolean("unbreakable-armor", true);
|
||||||
|
|
||||||
// Grab the class price, if any
|
// Grab the class price, if any
|
||||||
double price = -1D;
|
Thing price = null;
|
||||||
String priceString = section.getString("price", null);
|
String priceString = section.getString("price", null);
|
||||||
if (priceString != null) {
|
if (priceString != null) {
|
||||||
ItemStack priceItem = ItemParser.parseItem(priceString);
|
try {
|
||||||
if (priceItem != null && priceItem.getTypeId() == MobArena.ECONOMY_MONEY_ID) {
|
price = plugin.getThingManager().parse(priceString);
|
||||||
price = (priceItem.getAmount() + (priceItem.getDurability() / 100D));
|
} catch (Exception e) {
|
||||||
} else {
|
plugin.getLogger().warning("Exception parsing class price: " + e.getLocalizedMessage());
|
||||||
plugin.getLogger().warning("The price for class '" + classname + "' could not be parsed!");
|
price = null;
|
||||||
plugin.getLogger().warning("- expected e.g. '$10', found '" + priceString + "'");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -223,19 +223,6 @@ public class MAUtils
|
|||||||
ItemStack stack;
|
ItemStack stack;
|
||||||
for (E e : list) {
|
for (E e : list) {
|
||||||
stack = (ItemStack) e;
|
stack = (ItemStack) e;
|
||||||
if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) {
|
|
||||||
String formatted = plugin.economyFormat(stack);
|
|
||||||
if (formatted != null) {
|
|
||||||
buffy.append(formatted);
|
|
||||||
buffy.append(", ");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
plugin.getLogger().warning("Tried to do some money stuff, but no economy plugin was detected!");
|
|
||||||
return buffy.toString();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffy.append(stack.getType().toString().toLowerCase());
|
buffy.append(stack.getType().toString().toLowerCase());
|
||||||
buffy.append(":");
|
buffy.append(":");
|
||||||
buffy.append(stack.getAmount());
|
buffy.append(stack.getAmount());
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class MobArena extends JavaPlugin
|
|||||||
private FileConfiguration config;
|
private FileConfiguration config;
|
||||||
|
|
||||||
public static final double MIN_PLAYER_DISTANCE_SQUARED = 225D;
|
public static final double MIN_PLAYER_DISTANCE_SQUARED = 225D;
|
||||||
public static final int ECONOMY_MONEY_ID = -29;
|
|
||||||
public static Random random = new Random();
|
public static Random random = new Random();
|
||||||
|
|
||||||
private Messenger messenger;
|
private Messenger messenger;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.garbagemule.MobArena.commands.CommandInfo;
|
|||||||
import com.garbagemule.MobArena.commands.Commands;
|
import com.garbagemule.MobArena.commands.Commands;
|
||||||
import com.garbagemule.MobArena.framework.Arena;
|
import com.garbagemule.MobArena.framework.Arena;
|
||||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||||
|
import com.garbagemule.MobArena.things.Thing;
|
||||||
import com.garbagemule.MobArena.util.ClassChests;
|
import com.garbagemule.MobArena.util.ClassChests;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -70,10 +71,10 @@ public class PickClassCommand implements Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check price, balance, and inform
|
// Check price, balance, and inform
|
||||||
double price = ac.getPrice();
|
Thing price = ac.getPrice();
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
if (!am.getPlugin().hasEnough(p, price)) {
|
if (!price.heldBy(p)) {
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_TOO_EXPENSIVE, am.getPlugin().economyFormat(price));
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_TOO_EXPENSIVE, price.toString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,8 +92,8 @@ public class PickClassCommand implements Command
|
|||||||
}
|
}
|
||||||
arena.assignClass(p, lowercase);
|
arena.assignClass(p, lowercase);
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(lowercase).getConfigName());
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(lowercase).getConfigName());
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, am.getPlugin().economyFormat(price));
|
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, price.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
arena.addRandomPlayer(p);
|
arena.addRandomPlayer(p);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public interface Arena
|
|||||||
|
|
||||||
int getMaxPlayers();
|
int getMaxPlayers();
|
||||||
|
|
||||||
List<ItemStack> getEntryFee();
|
List<Thing> getEntryFee();
|
||||||
|
|
||||||
Set<Map.Entry<Integer,List<Thing>>> getEveryWaveEntrySet();
|
Set<Map.Entry<Integer,List<Thing>>> getEveryWaveEntrySet();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.garbagemule.MobArena.util;
|
|||||||
import com.garbagemule.MobArena.ArenaClass;
|
import com.garbagemule.MobArena.ArenaClass;
|
||||||
import com.garbagemule.MobArena.Msg;
|
import com.garbagemule.MobArena.Msg;
|
||||||
import com.garbagemule.MobArena.framework.Arena;
|
import com.garbagemule.MobArena.framework.Arena;
|
||||||
|
import com.garbagemule.MobArena.things.Thing;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -98,9 +99,9 @@ public class ClassChests {
|
|||||||
arena.assignClassGiveInv(player, classname, contents);
|
arena.assignClassGiveInv(player, classname, contents);
|
||||||
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(classname).getConfigName());
|
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(classname).getConfigName());
|
||||||
|
|
||||||
double price = ac.getPrice();
|
Thing price = ac.getPrice();
|
||||||
if (price > 0D) {
|
if (price != null) {
|
||||||
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PRICE, arena.getPlugin().economyFormat(price));
|
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PRICE, price.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,13 +182,6 @@ public class ItemParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ItemStack singleItem(String item) {
|
private static ItemStack singleItem(String item) {
|
||||||
if (item.matches("\\$(([1-9]\\d*)|(\\d*.\\d\\d?))")) {
|
|
||||||
double amount = Double.parseDouble(item.substring(1));
|
|
||||||
|
|
||||||
int major = (int) amount;
|
|
||||||
int minor = ((int) (amount * 100D)) % 100;
|
|
||||||
return new ItemStack(MobArena.ECONOMY_MONEY_ID, major, (short) minor);
|
|
||||||
}
|
|
||||||
int id = getTypeId(item);
|
int id = getTypeId(item);
|
||||||
return new ItemStack(id);
|
return new ItemStack(id);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user