package com.laytonsmith.core.functions; import com.laytonsmith.PureUtilities.Common.StringUtils; import com.laytonsmith.abstraction.MCCommandSender; import com.laytonsmith.abstraction.MCEntity; import com.laytonsmith.abstraction.MCInventory; import com.laytonsmith.abstraction.MCItemMeta; import com.laytonsmith.abstraction.MCItemStack; import com.laytonsmith.abstraction.MCLocation; import com.laytonsmith.abstraction.MCPlayer; import com.laytonsmith.abstraction.MCPlayerInventory; import com.laytonsmith.abstraction.MCWorld; import com.laytonsmith.abstraction.StaticLayer; import com.laytonsmith.abstraction.enums.MCInventoryType; import com.laytonsmith.abstraction.enums.MCVersion; import com.laytonsmith.annotations.api; import com.laytonsmith.core.CHVersion; import com.laytonsmith.core.ObjectGenerator; import com.laytonsmith.core.Static; import com.laytonsmith.core.constructs.CArray; import com.laytonsmith.core.constructs.CInt; import com.laytonsmith.core.constructs.CNull; import com.laytonsmith.core.constructs.CString; import com.laytonsmith.core.constructs.CVoid; import com.laytonsmith.core.constructs.Construct; import com.laytonsmith.core.constructs.Target; import com.laytonsmith.core.environments.CommandHelperEnvironment; import com.laytonsmith.core.environments.Environment; import com.laytonsmith.core.exceptions.CRE.CREBadEntityException; import com.laytonsmith.core.exceptions.CRE.CRECastException; import com.laytonsmith.core.exceptions.CRE.CREFormatException; import com.laytonsmith.core.exceptions.CRE.CREIllegalArgumentException; import com.laytonsmith.core.exceptions.CRE.CREInsufficientArgumentsException; import com.laytonsmith.core.exceptions.CRE.CREInvalidWorldException; import com.laytonsmith.core.exceptions.CRE.CRELengthException; import com.laytonsmith.core.exceptions.CRE.CRENotFoundException; import com.laytonsmith.core.exceptions.CRE.CREPlayerOfflineException; import com.laytonsmith.core.exceptions.CRE.CRERangeException; import com.laytonsmith.core.exceptions.CRE.CREThrowable; import com.laytonsmith.core.exceptions.ConfigRuntimeException; import java.util.Map; /** * */ public class InventoryManagement { public static String docs(){ return "Provides methods for managing inventory related tasks."; } @api(environments={CommandHelperEnvironment.class}) public static class pinv extends AbstractFunction { @Override public String getName() { return "pinv"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1, 2}; } @Override public String docs() { return "mixed {[player, [index]]} Gets the inventory information for the specified player, or the current " + " player if none specified. If the index is specified, only the slot given will be returned." + " The index of the array in the array is 0 - 35, 100 - 103, -106, which corresponds to the slot" + " in the player's inventory. To access armor slots, you may also specify the index. (100 - 103)." + " The quick bar is 0 - 8. If index is null, the item in the player's hand is returned, regardless" + " of what slot is selected. If index is -106, the player's off-hand item is returned. If there is" + " no item at the slot specified, null is returned." + " ---- If all slots are requested, an associative array of item objects is returned, and if" + " only one item is requested, just that single item object is returned. An item object" + " consists of the following associative array(name: the string id of the item," + " type: The numeric id of the item, data: The data value of the item," + " or the damage if a damagable item, qty: The number of items in their inventory, meta: An array" + " of item meta or null if none exists. See {{function|get_itemmeta}} for details about item meta."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CRECastException.class, CRERangeException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_1_3; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCCommandSender p = env.getEnv(CommandHelperEnvironment.class).GetCommandSender(); Integer index = -1; boolean all = false; MCPlayer m = null; if (args.length == 0) { all = true; if (p instanceof MCPlayer) { m = (MCPlayer) p; } } else if (args.length == 1) { all = true; m = Static.GetPlayer(args[0], t); } else if (args.length == 2) { if (args[1] instanceof CNull) { index = null; } else { index = Static.getInt32(args[1], t); } all = false; m = Static.GetPlayer(args[0], t); } Static.AssertPlayerNonNull(m, t); if(all){ CArray ret = CArray.GetAssociativeArray(t); for(int i = 0; i < 36; i++){ ret.set(i, getInvSlot(m, i, t), t); } for(int i = 100; i < 104; i++){ ret.set(i, getInvSlot(m, i, t), t); } if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_9)){ ret.set(-106, getInvSlot(m, -106, t), t); } return ret; } else { return getInvSlot(m, index, t); } } private Construct getInvSlot(MCPlayer m, Integer slot, Target t) { if(slot == null){ return ObjectGenerator.GetGenerator().item(m.getItemInHand(), t); } MCPlayerInventory inv = m.getInventory(); if (inv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } if(slot.equals(36)){ slot = 100; } if(slot.equals(37)){ slot = 101; } if(slot.equals(38)){ slot = 102; } if(slot.equals(39)){ slot = 103; } MCItemStack is; if(slot >= 0 && slot <= 35){ is = inv.getItem(slot); } else if(slot.equals(100)){ is = inv.getBoots(); } else if(slot.equals(101)){ is = inv.getLeggings(); } else if(slot.equals(102)){ is = inv.getChestplate(); } else if(slot.equals(103)){ is = inv.getHelmet(); } else if(slot.equals(-106)){ is = inv.getItemInOffHand(); } else { throw new CRERangeException("Slot index must be 0-35, or 100-103, or -106", t); } return ObjectGenerator.GetGenerator().item(is, t); } } @api(environments = {CommandHelperEnvironment.class}) public static class close_pinv extends AbstractFunction { @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p; if (args.length == 1) { p = Static.GetPlayer(args[0], t); } else { p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); } Static.AssertPlayerNonNull(p, t); p.closeInventory(); return CVoid.VOID; } @Override public String getName() { return "close_pinv"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1}; } @Override public String docs() { return "void {[player]} Closes the inventory of the current player, " + "or of the specified player."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class pworkbench extends AbstractFunction { @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CREInsufficientArgumentsException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p; if (args.length == 1) { p = Static.GetPlayer(args[0], t); } else { p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); if (p == null) { throw new CREInsufficientArgumentsException( "You have to specify a player when running " + this.getName() + " from console.", t); } } p.openWorkbench(p.getLocation(), true); return CVoid.VOID; } @Override public String getName() { return "pworkbench"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1}; } @Override public String docs() { return "void {[player]} Shows a workbench to the current player, " + "or a specified player."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class show_enderchest extends AbstractFunction { @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer player; MCPlayer other; if (args.length == 1) { player = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); other = Static.GetPlayer(args[0], t); } else if (args.length == 2) { other = Static.GetPlayer(args[0], t); player = Static.GetPlayer(args[1], t); } else { player = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); other = player; } Static.AssertPlayerNonNull(player, t); Static.AssertPlayerNonNull(other, t); player.openInventory(other.getEnderChest()); return CVoid.VOID; } @Override public String getName() { return "show_enderchest"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1, 2}; } @Override public String docs() { return "void {[player [, player]]} Shows the enderchest of either the current player " + " or the specified player if given. If a second player is specified, shows the" + " second player the contents of the first player's enderchest."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class penchanting extends AbstractFunction { @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p; if (args.length == 1) { p = Static.GetPlayer(args[0], t); } else { p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); } Static.AssertPlayerNonNull(p, t); p.openEnchanting(p.getLocation(), true); return CVoid.VOID; } @Override public String getName() { return "penchanting"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1}; } @Override public String docs() { return "void {[player]} Shows an enchanting to the current player, " + " or a specified player. Note that power is defined by how many" + " bookcases are near."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments={CommandHelperEnvironment.class}) public static class set_pinv extends AbstractFunction { @Override public String getName() { return "set_pinv"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2, 3, 4, 5, 7}; } @Override public String docs() { return "void {[player], pinvArray} Sets a player's inventory to the specified inventory object." + " An inventory object is one that matches what is returned by pinv(), so set_pinv(pinv())," + " while pointless, would be a correct call. ---- The array must be associative, " + " however, it may skip items, in which case, only the specified values will be changed. If" + " a key is out of range, or otherwise improper, a warning is emitted, and it is skipped," + " but the function will not fail as a whole. A simple way to set one item in a player's" + " inventory would be: set_pinv(array(2: array(type: 1, qty: 64))) This sets the player's second slot" + " to be a stack of stone. set_pinv(array(103: array(type: 298))) gives them a hat. To set the" + " item in hand, use something like set_pinv(array(null: array(type: 298))), where" + " the key is null. If you set a null key in addition to an entire inventory set, only" + " one item will be used (which one is undefined). Use an index of -106 to set the item in the" + " player's off-hand. Note that this uses the unsafe enchantment mechanism to add enchantments, so" + " any enchantment value will work. If type uses the old format (for instance, \"35:11\"), then" + " the second number is taken to be the data, making this backwards compatible (and sometimes more" + " convenient)."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CRECastException.class, CREFormatException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_2_0; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCCommandSender p = env.getEnv(CommandHelperEnvironment.class).GetCommandSender(); MCPlayer m = null; if (p instanceof MCPlayer) { m = (MCPlayer) p; } Construct arg; if(args.length == 2){ m = Static.GetPlayer(args[0], t); arg = args[1]; } else if(args.length == 1){ arg = args[0]; } else { throw new CREFormatException("The old format for set_pinv has been deprecated. Please update your script.", t); } if(!(arg instanceof CArray)){ throw new CRECastException("Expecting an array as argument " + (args.length==1?"1":"2"), t); } CArray array = (CArray)arg; Static.AssertPlayerNonNull(m, t); for(String key : array.stringKeySet()){ try{ int index = -2; try{ index = Integer.parseInt(key); } catch(NumberFormatException e){ if(key.isEmpty() || key.equals("null")){ //It was a null key index = -1; } else { throw e; } } if(index == -1){ MCItemStack is = ObjectGenerator.GetGenerator().item(array.get("", t), t); m.setItemInHand(is); } else { MCItemStack is = ObjectGenerator.GetGenerator().item(array.get(index, t), t); if(index >= 0 && index <= 35){ m.getInventory().setItem(index, is); } else if(index == 100){ m.getInventory().setBoots(is); } else if(index == 101){ m.getInventory().setLeggings(is); } else if(index == 102){ m.getInventory().setChestplate(is); } else if(index == 103){ m.getInventory().setHelmet(is); } else if(index == -106){ m.getInventory().setItemInOffHand(is); } else { ConfigRuntimeException.DoWarning("Out of range value (" + index + ") found in array passed to set_pinv(), so ignoring."); } } } catch(NumberFormatException e){ ConfigRuntimeException.DoWarning("Expecting integer value for key in array passed to set_pinv(), but \"" + key + "\" was found. Ignoring."); } } return CVoid.VOID; } } @api(environments={CommandHelperEnvironment.class}) public static class phas_item extends AbstractFunction{ @Override public String getName() { return "phas_item"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "int {[player], itemId} Returns the quantity of the specified item" + " that the player is carrying (including armor slots)." + " This counts across all slots in" + " inventory. Recall that 0 is false, and anything else is true," + " so this can be used to get the total, or just see if they have" + " the item. itemId can be either a plain number, or a 0:0 number," + " indicating a data value."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CREFormatException.class, CRECastException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); String item; if(args.length == 1){ item = args[0].val(); } else { p = Static.GetPlayer(args[0], t); item = args[1].val(); } Static.AssertPlayerNonNull(p, t); MCItemStack is = Static.ParseItemNotation(this.getName(), item, 0, t); MCPlayerInventory inv = p.getInventory(); if (inv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } int total = 0; for(int i = 0; i < 36; i++){ MCItemStack iis = inv.getItem(i); total += total(is, iis); } total += total(is, inv.getBoots()); total += total(is, inv.getLeggings()); total += total(is, inv.getChestplate()); total += total(is, inv.getHelmet()); if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_9)){ total += total(is, inv.getItemInOffHand()); } return new CInt(total, t); } private int total(MCItemStack is, MCItemStack iis){ if(iis.getTypeId() == is.getTypeId() && iis.getData().getData() == is.getData().getData()){ int i = iis.getAmount(); if(i < 0){ //Infinite stack i = iis.maxStackSize(); } return i; } return 0; } @Override public CHVersion since() { return CHVersion.V3_3_0; } } @api(environments={CommandHelperEnvironment.class}) public static class pitem_slot extends AbstractFunction{ @Override public String getName() { return "pitem_slot"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "array {[player], itemID} Given an item id, returns the slot numbers" + " that the matching item has at least one item in."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CREPlayerOfflineException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); String item; if(args.length == 1){ item = args[0].val(); } else { p = Static.GetPlayer(args[0], t); item = args[1].val(); } Static.AssertPlayerNonNull(p, t); MCItemStack is = Static.ParseItemNotation(this.getName(), item, 0, t); MCPlayerInventory inv = p.getInventory(); if (inv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } CArray ca = new CArray(t); for(int i = 0; i < 36; i++){ if(match(is, inv.getItem(i))){ ca.push(new CInt(i, t), t); } } if(match(is, inv.getBoots())){ ca.push(new CInt(100, t), t); } if(match(is, inv.getLeggings())){ ca.push(new CInt(101, t), t); } if(match(is, inv.getChestplate())){ ca.push(new CInt(102, t), t); } if(match(is, inv.getHelmet())){ ca.push(new CInt(103, t), t); } if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_9) && match(is, inv.getItemInOffHand())){ ca.push(new CInt(-106, t), t); } return ca; } private boolean match(MCItemStack is, MCItemStack iis){ return (is.getTypeId() == iis.getTypeId() && is.getData().getData() == iis.getData().getData()); } @Override public CHVersion since() { return CHVersion.V3_3_0; } } @api(environments={CommandHelperEnvironment.class}) public static class pgive_item extends AbstractFunction{ @Override public String getName() { return "pgive_item"; } @Override public Integer[] numArgs() { return new Integer[]{2, 3, 4}; } @Override public String docs() { return "int {[player], itemID, qty, [meta]} Gives a player the specified item * qty. The meta argument uses the" + " same format as set_itemmeta. Unlike set_pinv(), this does not specify a slot. The qty is distributed" + " in the player's inventory, first filling up slots that have the same item" + " type, up to the max stack size, then fills up empty slots, until either" + " the entire inventory is filled, or the entire amount has been given." + " If the player's inv is full, number of items that were not added is returned, which will be less than" + " or equal to the quantity provided. Otherwise, returns 0. This function will not touch the player's" + " armor slots however. Supports 'infinite' stacks by providing a negative number."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CREPlayerOfflineException.class, CRENotFoundException.class, CREIllegalArgumentException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); MCItemStack is; Construct m = null; if(args.length == 2){ is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); } else if(args.length == 3) { if(args[0] instanceof CString) { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); } else { is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); m = args[2]; } } else { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); m = args[3]; } Static.AssertPlayerNonNull(p, t); MCItemMeta meta; if (m != null) { meta = ObjectGenerator.GetGenerator().itemMeta(m, is.getType(), t); } else { meta = ObjectGenerator.GetGenerator().itemMeta(CNull.NULL, is.getType(), t); } is.setItemMeta(meta); Map<Integer, MCItemStack> h; try { h = p.getInventory().addItem(is); } catch(IllegalArgumentException e) { throw new CREIllegalArgumentException("Item value is invalid", t); } p.updateInventory(); if (h.isEmpty()) { return new CInt(0, t); } else { return new CInt(h.get(0).getAmount(), t); } } @Override public CHVersion since() { return CHVersion.V3_3_0; } } @api(environments={CommandHelperEnvironment.class}) public static class ptake_item extends AbstractFunction{ @Override public String getName() { return "ptake_item"; } @Override public Integer[] numArgs() { return new Integer[]{2, 3}; } @Override public String docs() { return "int {[player], itemID, qty} Works in reverse of pgive_item(), but" + " returns the number of items actually taken, which will be" + " from 0 to qty."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREPlayerOfflineException.class, CREFormatException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); MCItemStack is; if(args.length == 2){ is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); } else { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); } int total = is.getAmount(); int remaining = is.getAmount(); Static.AssertPlayerNonNull(p, t); MCPlayerInventory inv = p.getInventory(); if (inv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } for(int i = 35; i >= 0; i--){ MCItemStack iis = inv.getItem(i); if(remaining <= 0){ break; } if(match(is, iis)){ //Take the minimum of either: remaining, or iis.getAmount() int toTake = java.lang.Math.min(remaining, iis.getAmount()); remaining -= toTake; int replace = iis.getAmount() - toTake; if(replace == 0){ inv.setItem(i, StaticLayer.GetItemStack(0, 0)); } else { inv.setItem(i, StaticLayer.GetItemStack(is.getTypeId(), is.getData().getData(), replace)); } } } return new CInt(total - remaining, t); } private boolean match(MCItemStack is, MCItemStack iis){ if(is.getData() == null && iis.getData() == null) { return is.getTypeId() == iis.getTypeId(); } else if(is.getData() == null || iis.getData() == null) { return false; } else { return (is.getTypeId() == iis.getTypeId() && is.getData().getData() == iis.getData().getData()); } } @Override public CHVersion since() { return CHVersion.V3_3_0; } } @api(environments = {CommandHelperEnvironment.class}) public static class pgive_enderchest_item extends AbstractFunction { @Override public String getName() { return "pgive_enderchest_item"; } @Override public Integer[] numArgs() { return new Integer[]{2, 3, 4}; } @Override public String docs() { return "int {[player], itemID, qty, [meta]} Add to a player ender chest the specified item * qty. The meta argument uses the" + " same format as set_itemmeta. Unlike set_penderchest(), this does not specify a slot. The qty is distributed" + " in the player's inventory, first filling up slots that have the same item" + " type, up to the max stack size, then fills up empty slots, until either" + " the entire inventory is filled, or the entire amount has been given." + " If the player's inv is full, number of items that were not added is returned, which will be less than" + " or equal to the quantity provided. Otherwise, returns 0." + " Supports 'infinite' stacks by providing a negative number."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CREPlayerOfflineException.class, CRENotFoundException.class, CREIllegalArgumentException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); MCItemStack is; Construct m = null; if (args.length == 2) { is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); } else if (args.length == 3) { if (args[0] instanceof CString) { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); } else { is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); m = args[2]; } } else { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); m = args[3]; } Static.AssertPlayerNonNull(p, t); MCItemMeta meta; if (m != null) { meta = ObjectGenerator.GetGenerator().itemMeta(m, is.getType(), t); } else { meta = ObjectGenerator.GetGenerator().itemMeta(CNull.NULL, is.getType(), t); } is.setItemMeta(meta); Map<Integer, MCItemStack> h; try { h = p.getEnderChest().addItem(is); } catch(IllegalArgumentException e) { throw new CREIllegalArgumentException("Item value is invalid", t); } if (h.isEmpty()) { return new CInt(0, t); } else { return new CInt(h.get(0).getAmount(), t); } } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class ptake_enderchest_item extends AbstractFunction { @Override public String getName() { return "ptake_enderchest_item"; } @Override public Integer[] numArgs() { return new Integer[]{2, 3}; } @Override public String docs() { return "int {[player], itemID, qty} Works in reverse of pgive_enderchest_item(), but" + " returns the number of items actually taken, which will be" + " from 0 to qty."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREPlayerOfflineException.class, CREFormatException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); MCItemStack is; if (args.length == 2) { is = Static.ParseItemNotation(this.getName(), args[0].val(), Static.getInt32(args[1], t), t); } else { p = Static.GetPlayer(args[0], t); is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); } int total = is.getAmount(); int remaining = is.getAmount(); Static.AssertPlayerNonNull(p, t); MCInventory inv = p.getEnderChest(); if (inv == null) { throw new CRENotFoundException( "Could not find the enderchest inventory of the given player (are you running in cmdline mode?)", t); } for (int i = 26; i >= 0; i--) { MCItemStack iis = inv.getItem(i); if (remaining <= 0) { break; } if (match(is, iis)) { //Take the minimum of either: remaining, or iis.getAmount() int toTake = java.lang.Math.min(remaining, iis.getAmount()); remaining -= toTake; int replace = iis.getAmount() - toTake; if (replace == 0) { inv.setItem(i, StaticLayer.GetItemStack(0, 0)); } else { inv.setItem(i, StaticLayer.GetItemStack(is.getTypeId(), is.getData().getData(), replace)); } } } return new CInt(total - remaining, t); } private boolean match(MCItemStack is, MCItemStack iis) { return (is.getTypeId() == iis.getTypeId() && is.getData().getData() == iis.getData().getData()); } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class set_penderchest extends AbstractFunction { @Override public String getName() { return "set_penderchest"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "void {[player], pinvArray} Sets a player's enderchest's inventory to the specified inventory object." + " An inventory object is one that matches what is returned by penderchest(), so set_penderchest(penderchest())," + " while pointless, would be a correct call. ---- The array must be associative, " + " however, it may skip items, in which case, only the specified values will be changed. If" + " a key is out of range, or otherwise improper, a warning is emitted, and it is skipped," + " but the function will not fail as a whole. A simple way to set one item in a player's" + " enderchest would be: set_penderchest(array(2: array(type: 1, qty: 64))) This sets the chest's second slot" + " to be a stack of stone. set_penderchest(array(103: array(type: 298))) gives them a hat." + " Note that this uses the unsafe" + " enchantment mechanism to add enchantments, so any enchantment value will work. If" + " type uses the old format (for instance, \"35:11\"), then the second number is taken" + " to be the data, making this backwards compatible (and sometimes more convenient)."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CRECastException.class, CREFormatException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_3_1; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCCommandSender p = env.getEnv(CommandHelperEnvironment.class).GetCommandSender(); MCPlayer m = null; if (p instanceof MCPlayer) { m = (MCPlayer) p; } Construct arg; if (args.length == 2) { m = Static.GetPlayer(args[0], t); arg = args[1]; } else { arg = args[0]; } if (!(arg instanceof CArray)) { throw new CRECastException("Expecting an array as argument " + (args.length == 1 ? "1" : "2"), t); } CArray array = (CArray) arg; Static.AssertPlayerNonNull(m, t); for (String key : array.stringKeySet()) { try { int index = -2; try { index = Integer.parseInt(key); } catch (NumberFormatException e) { if (key.isEmpty()) { throw new CRERangeException("Slot index must be 0-26", t); } else { throw e; } } MCItemStack is = ObjectGenerator.GetGenerator().item(array.get(index, t), t); if (index >= 0 && index <= 26) { m.getEnderChest().setItem(index, is); } else { ConfigRuntimeException.DoWarning("Out of range value (" + index + ") found in array passed to set_penderchest(), so ignoring."); } } catch (NumberFormatException e) { ConfigRuntimeException.DoWarning("Expecting integer value for key in array passed to set_penderchest(), but \"" + key + "\" was found. Ignoring."); } } return CVoid.VOID; } } @api(environments = {CommandHelperEnvironment.class}) public static class penderchest extends AbstractFunction { @Override public String getName() { return "penderchest"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1, 2}; } @Override public String docs() { return "mixed {[player, [index]]} Gets the inventory information for the specified player's enderchest, or the current player if none specified. If the index is specified, only the slot " + " given will be returned." + " The index of the array in the array is 0 - 26, which corresponds to the slot in the enderchest inventory." + " If there is no item at the slot specified, null is returned." + " ---- If all slots are requested, an associative array of item objects is returned, and if" + " only one item is requested, just that single item object is returned. An item object" + " consists of the following associative array(type: The id of the item, data: The data value of the item," + " or the damage if a damagable item, qty: The number of items in their inventory, enchants: An array" + " of enchant objects, with 0 or more associative arrays which look like:" + " array(etype: The type of enchantment, elevel: The strength of the enchantment))"; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CRECastException.class, CRERangeException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_3_1; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCCommandSender p = env.getEnv(CommandHelperEnvironment.class).GetCommandSender(); Integer index = -1; boolean all = false; MCPlayer m = null; if (args.length == 0) { all = true; if (p instanceof MCPlayer) { m = (MCPlayer) p; } } else if (args.length == 1) { all = true; m = Static.GetPlayer(args[0], t); } else if (args.length == 2) { if (args[1] instanceof CNull) { throw new CRERangeException("Slot index must be 0-26", t); } else { index = Static.getInt32(args[1], t); } all = false; m = Static.GetPlayer(args[0], t); } Static.AssertPlayerNonNull(m, t); if (all) { CArray ret = CArray.GetAssociativeArray(t); for (int i = 0; i < 27; i++) { ret.set(i, getInvSlot(m, i, t), t); } return ret; } else { return getInvSlot(m, index, t); } } private Construct getInvSlot(MCPlayer m, Integer slot, Target t) { MCInventory inv = m.getEnderChest(); if (inv == null) { throw new CRENotFoundException( "Could not find the enderchest inventory of the given player (are you running in cmdline mode?)", t); } if (slot < 0 || slot > 26) { throw new CRERangeException("Slot index must be 0-26", t); } MCItemStack is = inv.getItem(slot); return ObjectGenerator.GetGenerator().item(is, t); } } @api(environments={CommandHelperEnvironment.class}) public static class get_inventory_item extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREFormatException.class, CRECastException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCWorld w = null; MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); if(p != null){ w = p.getWorld(); } MCInventory inv = GetInventory(args[0], w, t); int slot = Static.getInt32(args[1], t); try{ MCItemStack is = inv.getItem(slot); return ObjectGenerator.GetGenerator().item(is, t); } catch(ArrayIndexOutOfBoundsException e){ throw new CRERangeException("Index out of bounds for the inventory type.", t); } } @Override public String getName() { return "get_inventory_item"; } @Override public Integer[] numArgs() { return new Integer[]{2}; } @Override public String docs() { return "array {entityID, slotNumber | locationArray, slotNumber} If a number is provided, it is assumed to be an entity, and if the entity supports" + " inventories, it will be valid. Otherwise, if a location array is provided, it is assumed to be a block (chest, brewer, etc)" + " and interpreted thusly. Depending on the inventory type, the max index will vary. If the index is too large, a RangeException is thrown," + " otherwise, the item at that location is returned as an item array, or null, if no item is there. You can determine the inventory type" + " (and thus the max index count) with get_inventory_type(). An itemArray, like the one used by pinv/set_pinv is returned."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments={CommandHelperEnvironment.class}) public static class set_inventory_item extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREFormatException.class, CRECastException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCWorld w = null; MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); if(p != null){ w = p.getWorld(); } MCInventory inv = GetInventory(args[0], w, t); int slot = Static.getInt32(args[1], t); MCItemStack is = ObjectGenerator.GetGenerator().item(args[2], t); try{ inv.setItem(slot, is); return CVoid.VOID; } catch(ArrayIndexOutOfBoundsException e){ throw new CRERangeException("Index out of bounds for the inventory type.", t); } } @Override public String getName() { return "set_inventory_item"; } @Override public Integer[] numArgs() { return new Integer[]{3}; } @Override public String docs() { return "void {entityID, index, itemArray | locationArray, index, itemArray} Sets the specified item in the specified slot given either an entityID or a location array of a container" + " object. See get_inventory_type for more information. The itemArray is an array in the same format as pinv/set_pinv takes."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments={CommandHelperEnvironment.class}) public static class get_inventory_type extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCWorld w = null; MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); if(p != null){ w = p.getWorld(); } MCInventory inv = GetInventory(args[0], w, t); return new CString(inv.getType().name(), t); } @Override public String getName() { return "get_inventory_type"; } @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public String docs() { return "string {entityID | locationArray} Returns the inventory type at the location specified, or of the entity specified. If the" + " entity or location specified is not capable of having an inventory, a FormatException is thrown." + " ---- Note that not all valid inventory types are actually returnable at this time, due to lack of support in the server, but" + " the valid return types are: " + StringUtils.Join(MCInventoryType.values(), ", "); } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments={CommandHelperEnvironment.class}) public static class get_inventory_size extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREFormatException.class, CRECastException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCWorld w = null; if(environment.getEnv(CommandHelperEnvironment.class).GetPlayer() != null){ w = environment.getEnv(CommandHelperEnvironment.class).GetPlayer().getWorld(); } MCInventory inventory = InventoryManagement.GetInventory(args[0], w, t); return new CInt(inventory.getSize(), t); } @Override public String getName() { return "get_inventory_size"; } @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public String docs() { return "int {entityID | locationArray} Returns the max size of the inventory specified. If the block or entity can't have an inventory," + " a FormatException is thrown."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments={CommandHelperEnvironment.class}) public static class get_inventory_name extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREBadEntityException.class, CRECastException.class, CREFormatException.class, CREIllegalArgumentException.class, CREInvalidWorldException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCWorld w = null; MCPlayer p = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); if(p != null){ w = p.getWorld(); } MCInventory inventory = InventoryManagement.GetInventory(args[0], w, t); return new CString(inventory.getTitle(), t); } @Override public String getName() { return "get_inventory_name"; } @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public String docs() { return "string {entityID | locationArray} Returns the name of the inventory specified. If the block or entity" + " can't have an inventory, a FormatException is thrown."; } @Override public CHVersion since() { return CHVersion.V3_3_2; } } @api(environments={CommandHelperEnvironment.class}) public static class pinv_open extends AbstractFunction{ @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer p1 = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); MCPlayer p2; if(args.length == 2){ p1 = Static.GetPlayer(args[0], t); p2 = Static.GetPlayer(args[1], t); } else { p2 = Static.GetPlayer(args[0], t); } Static.AssertPlayerNonNull(p1, t); p1.openInventory(p2.getInventory()); return CVoid.VOID; } @Override public String getName() { return "pinv_open"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "void {[playerToShow,] playerInventory} Opens a player's inventory, shown to the player specified's screen."; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class get_inventory extends AbstractFunction { @Override public String getName() { return "get_inventory"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "mixed {entityID, [index] | locationArray, [index]} Gets the inventory information for the specified block or entity." + " If the block or entity can't have an inventory, a FormatException is thrown. If the index is specified," + " only the slot given will be returned. The max index of the array in the array is different for different types" + " of inventories. If there is no item at the slot specified, null is returned." + " ---- If all slots are requested, an associative array of item objects is returned, and if" + " only one item is requested, just that single item object is returned. An item object" + " consists of the following associative array(type: The id of the item, data: The data value of the item," + " or the damage if a damagable item, qty: The number of items in their inventory, enchants: An array" + " of enchant objects, with 0 or more associative arrays which look like:" + " array(etype: The type of enchantment, elevel: The strength of the enchantment))"; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CRERangeException.class, CREFormatException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_3_1; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCInventory inventory = InventoryManagement.GetInventory(args[0], null, t); Integer size = inventory.getSize(); Integer index = -1; if (args.length == 2) { index = Static.getInt32(args[1], t); if (index < 0 || index >= size) { throw new CRERangeException("Slot index must be 0-" + (size - 1), t); } } if (index == -1) { CArray ret = CArray.GetAssociativeArray(t); for (int i = 0; i < size; i++) { ret.set(i, ObjectGenerator.GetGenerator().item(inventory.getItem(i), t), t); } return ret; } else { return ObjectGenerator.GetGenerator().item(inventory.getItem(index), t); } } } @api(environments = {CommandHelperEnvironment.class}) public static class set_inventory extends AbstractFunction { @Override public String getName() { return "set_inventory"; } @Override public Integer[] numArgs() { return new Integer[]{2}; } @Override public String docs() { return "void {entityID, pinvArray | locationArray, pinvArray} Sets a block or entity inventory to the specified" + " inventory object. If the block or entity can't have an inventory, a FormatException is thrown." + " An inventory object pinvArray is one that matches what is returned by get_inventory(), so" + " set_inventory(123, get_inventory(123)) while pointless, would be a correct call." + " ---- The array must be associative, however, it may skip items, in which case, only the specified" + " values will be changed. If a key is out of range, or otherwise improper, a warning is emitted," + " and it is skipped, but the function will not fail as a whole. A simple way to set one item would be:" + " set_inventory(123, array(2: array(type: 1, qty: 64))) This sets the inventory second slot" + " to be a stack of stone for entity with ID = 123. Note that this uses the unsafe" + " enchantment mechanism to add enchantments, so any enchantment value will work. If" + " type uses the old format (for instance, \"35:11\"), then the second number is taken" + " to be the data, making this backwards compatible (and sometimes more convenient)."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_3_1; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { MCInventory inventory = InventoryManagement.GetInventory(args[0], null, t); Integer size = inventory.getSize(); if (!(args[1] instanceof CArray)) { throw new CRECastException("Expecting an array as argument 2", t); } CArray array = (CArray) args[1]; for (String key : array.stringKeySet()) { try { int index; try { index = Integer.parseInt(key); } catch (NumberFormatException e) { throw e; } if (index < 0 || index >= size) { ConfigRuntimeException.DoWarning("Out of range value (" + index + ") found in array passed to set_inventory(), so ignoring."); } else { MCItemStack is = ObjectGenerator.GetGenerator().item(array.get(index, t), t); inventory.setItem(index, is); } } catch (NumberFormatException e) { ConfigRuntimeException.DoWarning("Expecting integer value for key in array passed to set_inventory(), but \"" + key + "\" was found. Ignoring."); } } return CVoid.VOID; } } @api(environments = {CommandHelperEnvironment.class}) public static class add_to_inventory extends AbstractFunction { @Override public String getName() { return "add_to_inventory"; } @Override public Integer[] numArgs() { return new Integer[]{3, 4}; } @Override public String docs() { return "int {entityID, itemID, qty, [meta] | locationArray, itemID, qty, [meta]} Add to block or entity inventory" + " the specified item * qty. The meta argument uses the same format as set_itemmeta. Unlike set_inventory()," + " this does not specify a slot. The qty is distributed in the inventory, first filling up slots" + " that have the same item type, up to the max stack size, then fills up empty slots, until either" + " the entire inventory is filled, or the entire amount has been given." + " If the inventory is full, number of items that were not added is returned, which will be less than" + " or equal to the quantity provided. Otherwise, returns 0. Supports 'infinite' stacks by providing" + " a negative number."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CRELengthException.class, CREIllegalArgumentException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCInventory inventory = InventoryManagement.GetInventory(args[0], null, t); MCItemStack is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); Construct m = null; if (args.length == 4) { m = args[3]; } MCItemMeta meta; if (m != null) { meta = ObjectGenerator.GetGenerator().itemMeta(m, is.getType(), t); } else { meta = ObjectGenerator.GetGenerator().itemMeta(CNull.NULL, is.getType(), t); } is.setItemMeta(meta); Map<Integer, MCItemStack> h; try { h = inventory.addItem(is); } catch(IllegalArgumentException e){ throw new CREIllegalArgumentException("Item value is invalid", t); } if (h.isEmpty()) { return new CInt(0, t); } else { return new CInt(h.get(0).getAmount(), t); } } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class take_from_inventory extends AbstractFunction { @Override public String getName() { return "take_from_inventory"; } @Override public Integer[] numArgs() { return new Integer[]{3}; } @Override public String docs() { return "int {entityID, itemID, qty | locationArray, itemID, qty} Works in reverse of add_to_inventory(), but" + " returns the number of items actually taken, which will be from 0 to qty."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREFormatException.class, CRELengthException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCInventory inventory = InventoryManagement.GetInventory(args[0], null, t); Integer size = inventory.getSize(); MCItemStack is = Static.ParseItemNotation(this.getName(), args[1].val(), Static.getInt32(args[2], t), t); int total = is.getAmount(); int remaining = is.getAmount(); for (int i = size - 1; i >= 0; i--) { MCItemStack iis = inventory.getItem(i); if (remaining <= 0) { break; } if (match(is, iis)) { //Take the minimum of either: remaining, or iis.getAmount() int toTake = java.lang.Math.min(remaining, iis.getAmount()); remaining -= toTake; int replace = iis.getAmount() - toTake; if (replace == 0) { inventory.setItem(i, StaticLayer.GetItemStack(0, 0)); } else { inventory.setItem(i, StaticLayer.GetItemStack(is.getTypeId(), is.getData().getData(), replace)); } } } return new CInt(total - remaining, t); } private boolean match(MCItemStack is, MCItemStack iis) { return (is.getTypeId() == iis.getTypeId() && is.getData().getData() == iis.getData().getData()); } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class set_pheld_slot extends AbstractFunction { @Override public String getName() { return "set_pheld_slot"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "void {[player], slotNumber} Sets the selected quickbar slot of the given or executing player" + " to the given slot. The slot number is in range of [0-8]."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRERangeException.class, CREPlayerOfflineException.class, CREFormatException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer player; switch(args.length) { case 1: { MCCommandSender sender = environment.getEnv(CommandHelperEnvironment.class).GetCommandSender(); if(sender instanceof MCPlayer) { player = (MCPlayer) sender; } else { throw new CREPlayerOfflineException("The command sender is not online (are you running this from console?).", t); } break; } case 2: { player = Static.GetPlayer(args[0], t); break; } default: { throw new CREFormatException("Wrong number of arguments passed to " + this.getName(), t); } } int slot; try { slot = Integer.parseInt(args[args.length - 1].val()); } catch(NumberFormatException e) { throw new CREFormatException("Slot number must be an integer in range of [0-8].", t); } if(slot < 0 || slot > 8) { throw new CRERangeException("Slot number must be an integer in range of [0-8].", t); } MCPlayerInventory pinv = player.getInventory(); if (pinv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } pinv.setHeldItemSlot(slot); return CVoid.VOID; } @Override public CHVersion since() { return CHVersion.V3_3_1; } } @api(environments = {CommandHelperEnvironment.class}) public static class pheld_slot extends AbstractFunction { @Override public String getName() { return "pheld_slot"; } @Override public Integer[] numArgs() { return new Integer[]{0, 1}; } @Override public String docs() { return "int {[player]} Returns the selected quickbar slot of the given or executing player." + " The slot number is in range of [0-8]."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class, CREFormatException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer player; switch(args.length) { case 0: { MCCommandSender sender = environment.getEnv(CommandHelperEnvironment.class).GetCommandSender(); if(sender instanceof MCPlayer) { player = (MCPlayer) sender; } else { throw new CREPlayerOfflineException("The command sender is not online (are you running this from console?).", t); } break; } case 1: { player = Static.GetPlayer(args[0], t); break; } default: { throw new CREFormatException("Wrong number of arguments passed to " + this.getName(), t); } } MCPlayerInventory pinv = player.getInventory(); if (pinv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } int slot = pinv.getHeldItemSlot(); return new CInt(slot, t); } @Override public CHVersion since() { return CHVersion.V3_3_1; } } // @api // public static class pinv_consolidate extends AbstractFunction { // // public String getName() { // return "pinv_consolidate"; // } // // public Integer[] numArgs() { // return new Integer[]{0, 1}; // } // // public String docs() { // return "void {[player]} Consolidates a player's inventory as much as possible." // + " There is no guarantee anything will happen after this function" // + " is called, and there is no way to specify details about how" // + " consolidation occurs, however, the following heuristics are followed:" // + " The hotbar items will not be moved from the hotbar, unless there are" // + " two+ slots that have the same item. Items in the main inventory area" // + " will be moved closer to the bottom of the main inventory. No empty slots" // + " will be filled in the hotbar."; // } // // public Class<? extends CREThrowable>[] thrown() { // return new Class[]{}; // } // // public boolean isRestricted() { // return true; // } // // public boolean preResolveVariables() { // return true; // } // // public Boolean runAsync() { // return false; // } // // public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { // MCPlayer p = environment.GetPlayer(); // if(args.length == 1){ // p = Static.GetPlayer(args[0], t); // } // //First, we need to address the hotbar // for(int i = 0; i < 10; i++){ // //If the stack size is maxed out, we're done. // } // // return CVoid.VOID; // } // // public CHVersion since() { // return CHVersion.V3_3_1; // } // } private static MCInventory GetInventory(Construct specifier, MCWorld w, Target t){ MCInventory inv; if(specifier instanceof CArray){ MCLocation l = ObjectGenerator.GetGenerator().location(specifier, w, t); inv = StaticLayer.GetConvertor().GetLocationInventory(l); } else { MCEntity entity = Static.getEntity(specifier, t); inv = StaticLayer.GetConvertor().GetEntityInventory(entity); } if(inv == null){ throw new CREFormatException("The entity or location specified is not capable of having an inventory.", t); } else { return inv; } } }