Skip to content

3.5 Identifing Items

Yanbing Zhao edited this page Jun 20, 2019 · 1 revision

HandheldItem is the key of a field which should be defined in PrimaryAction, SecondaryAction, PrimaryShiftAction, or SecondaryShiftAction. HandheldItems are used for identifing items and perform different actions for different items. In other words, HandheldItems are treated as item filters in VirtualChest.

VirtualChest could recognize six types of fields in HandheldItems, which are shown as follows.

The ItemType field

As the name implies, ItemType is used for identifing item types.

Here is an example for identifing diamonds:

HandheldItem {
  ItemType = "minecraft:diamond"
}

The Count field

Count is used to identify items containing at least a given amount. The default value will be 1 if the Count field is not set.

Here is an example for identifing at least 60 diamonds:

HandheldItem {
  Count = 60
  ItemType = "minecraft:diamond"
}

An itemstack containing 61, 62, 63, or 64 diamonds will also be identified.

The UnsafeDamage field

UnsafeDamage is used for identifing the item damage. If it is not set, the corresponding HandheldItem will match any possible item damages (as a wildcard matcher).

Here is an example for identifing charcoals:

HandheldItem {
  UnsafeDamage = 1
  ItemType = "minecraft:coal"
}

Here is an example for identifing naturally generated coals:

HandheldItem {
  UnsafeDamage = 1
  ItemType = "minecraft:coal"
}

If the UnsafeDamage field is not set, both coals and charcoals will be identified:

HandheldItem {
  ItemType = "minecraft:coal"
}

The UnsafeData field

UnsafeData is used for matching nbt tags of items. The detection logic for matching nbt tags is same as what /testfor does.

Unlike the configuration in Item, here you need to handle raw NBT and § should be used in some places instead of &. Here is an example for checking if the item has the corresponding display name and lore texts:

HandheldItem {
  UnsafeDamage = 1
  ItemType = "minecraft:coal"
  UnsafeData {
    display {
      Name = "§lCoal Buyer"
      Lore = [
        "§e1xCoal => $10"
      ]
    }
  }
}

Please notice that the UnsafeData field represents the rule that matches nbt tags directly, so use § instead of & for formatted codes.

The SearchInventory field

The default of SearchInventory field is false. If it is set to true, not only the players' cursors but also their inventories will be searched to match the HandheldItem field. Since the player's inventory is large enough, the value of theCount field can even be set to an integer greater than the max stack size (usually it is 64).

If there are multiple actions withe multiple HandheldItems and the player's cursor is empty, the order in the list will determine the priority. Both wheats and hay bales will be still used as the following example:

PrimaryAction = [{
  Command = "cost-item: 9; cost: -8"
  HandheldItem {
    SearchInventory = true
    ItemType = "minecraft:wheat"
    UnsafeDamage = 0
    Count = 9
  }
  KeepInventoryOpen = true
}, {
  Command = "cost-item: 1; cost: -8"
  HandheldItem {
    SearchInventory = true
    ItemType = "minecraft:hay_block"
    UnsafeDamage = 0
    Count = 1
  }
  KeepInventoryOpen = true
}]

If the player clicks the slot with nothing in the hand, the wheats in the inventory will be searched first, and the next item to be searched will be hay bales if the amount of wheat is not enough (less than 9).

However, the item held in the mouse cursor will be always the highest priority. If a slot is clicked with a hay bale held in hand, the second item will be directly selected, although there may be plenty of wheats in the player's inventory.

The RepetitionUpperLimit Field

Is it possible to sell all the matched items in the inventory? Yes, it is possible. RepetitionUpperLimit allows you to search the inventory and the mouse cursor repeatly and perform the action as many times as possible, until the upper bound set by yourself. The default value of RepetitionUpperLimit is 0, which means that there will not be any repetition. If you set the value to a positive integer, the situation will be different. Here we still use wheat as the example:

PrimaryAction {
  Command = "cost-item: 9; cost: -8"
  HandheldItem {
    RepetitionUpperLimit = 2
    ItemType = "minecraft:wheat"
    UnsafeDamage = 0
    Count = 9
  }
  KeepInventoryOpen = true
}
  • If you have less than 9 wheats, nothing will happen.
  • If you have no less than 9 but less than 18 wheats, the action will be executed once. You used 9 wheats in exchange for 8 default currency units.
  • If you have no less than 18 but less than 27 wheats, the action will be executed twice (repeated once). You used 18 wheats in exchange for 16 default currency units.
  • If you have no less than 27 but less than 36 wheats, the action will be executed three times (repeated twice). You used 27 wheats in exchange for 24 default currency units.
  • If you have no less than 36 wheats, the action should have been executed four times (repeated three times), but the RepetitionUpperLimit limits the maximum number of repetitions, so it would only be repeated twice (executed three times), deduct 27 wheats, and give you 24 default currency units.

It seems tempting to set the value of RepetitionUpperLimit to a very large value, but a large number of repeatitions will cause the server to perform too many operations on the same tick, so I actually do not recommend this. The following example:

HandheldItem {
  RepetitionUpperLimit = 9
  ItemType = "minecraft:wheat"
  UnsafeDamage = 0
  Count = 64
}

is better than this one:

HandheldItem {
  RepetitionUpperLimit = 64
  ItemType = "minecraft:wheat"
  UnsafeDamage = 0
  Count = 9
}

All you also need to do is just the adjustion of the action to be executed (such as the money to be given and the item to be deducted).