Add InventoryThing collection.
Adds three new Thing types that can be used to reference items in chests
(or any block-based InventoryHolder):
- InventoryIndexThing looks up an item by index/slot in an inventory.
- InventoryGroupThing groups all non-null/non-air items in an inventory
into a ThingGroup.
- InventoryRangeThing groups all non-null/non-air items in a given range
of an inventory into a ThingGroup.
The new Thing types aim to bridge a gap between the class chests and the
rest of the Thing-based parts of the config-file. The goal is two-fold:
allow for more in-game configuration so access to the config-file isn't
_quite_ as crucial, and propagate the item-wise feature completeness of
class chests to other parts of the plugin.
While class chests are low configuration and a bit "all or nothing", the
inventory Thing types require manually punching in the coords for chests
and possibly indices/ranges for items. This means that the initial setup
could be a bit unwieldy, and highly volatile wave setups are definitely
not a good fit. If the wave setup is mostly pre-defined, it is fairly
easy to tweak upgrade waves and rewards in the same way class chests are
tweaked.
As for item-wise feature completeness, the inventory Thing types share
the same "if Bukkit can copy it, it will work" rule of thumb as class
chests do, which means items with metadata such as custom names, lore,
or even NBTs, should just work. This could remove the need to employ
other plugins.
By no means can this solution be considered "optimal", but it it _does_
enable some long-requested features.
Closes #456
2021-08-07 22:43:08 +02:00
|
|
|
package com.garbagemule.MobArena.things;
|
|
|
|
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Server;
|
|
|
|
import org.bukkit.World;
|
|
|
|
|
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
2024-01-01 18:34:20 +01:00
|
|
|
class InventoryThingParser implements ThingParser {
|
Add InventoryThing collection.
Adds three new Thing types that can be used to reference items in chests
(or any block-based InventoryHolder):
- InventoryIndexThing looks up an item by index/slot in an inventory.
- InventoryGroupThing groups all non-null/non-air items in an inventory
into a ThingGroup.
- InventoryRangeThing groups all non-null/non-air items in a given range
of an inventory into a ThingGroup.
The new Thing types aim to bridge a gap between the class chests and the
rest of the Thing-based parts of the config-file. The goal is two-fold:
allow for more in-game configuration so access to the config-file isn't
_quite_ as crucial, and propagate the item-wise feature completeness of
class chests to other parts of the plugin.
While class chests are low configuration and a bit "all or nothing", the
inventory Thing types require manually punching in the coords for chests
and possibly indices/ranges for items. This means that the initial setup
could be a bit unwieldy, and highly volatile wave setups are definitely
not a good fit. If the wave setup is mostly pre-defined, it is fairly
easy to tweak upgrade waves and rewards in the same way class chests are
tweaked.
As for item-wise feature completeness, the inventory Thing types share
the same "if Bukkit can copy it, it will work" rule of thumb as class
chests do, which means items with metadata such as custom names, lore,
or even NBTs, should just work. This could remove the need to employ
other plugins.
By no means can this solution be considered "optimal", but it it _does_
enable some long-requested features.
Closes #456
2021-08-07 22:43:08 +02:00
|
|
|
|
|
|
|
private static final String PREFIX = "inv(";
|
|
|
|
private static final String SUFFIX = ")";
|
|
|
|
|
|
|
|
private final Server server;
|
|
|
|
|
|
|
|
InventoryThingParser(Server server) {
|
|
|
|
this.server = server;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public InventoryThing parse(String s) {
|
|
|
|
if (!s.startsWith(PREFIX) || !s.endsWith(SUFFIX)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trim prefix and suffix
|
|
|
|
int start = PREFIX.length();
|
|
|
|
int end = s.length() - SUFFIX.length();
|
|
|
|
String inner = s.substring(start, end);
|
|
|
|
|
|
|
|
// Split by whitespace to get all the parts
|
|
|
|
String[] parts = inner.split("\\s+");
|
|
|
|
if (parts.length != 5) {
|
|
|
|
throw new IllegalArgumentException("Expected format " + PREFIX + "world x y z slot" + SUFFIX + ", got: " + s);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extract location
|
|
|
|
String name = parts[0];
|
|
|
|
int x = Integer.parseInt(parts[1]);
|
|
|
|
int y = Integer.parseInt(parts[2]);
|
|
|
|
int z = Integer.parseInt(parts[3]);
|
|
|
|
Supplier<Location> location = () -> {
|
|
|
|
World world = server.getWorld(name);
|
|
|
|
return new Location(world, x, y ,z);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Determine type by slot value
|
|
|
|
String slot = parts[4];
|
|
|
|
if (slot.equals("all")) {
|
|
|
|
return group(location);
|
|
|
|
}
|
|
|
|
if (slot.contains("-")) {
|
|
|
|
return range(location, slot);
|
|
|
|
}
|
|
|
|
return index(location, slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
private InventoryThing group(Supplier<Location> location) {
|
|
|
|
return new InventoryGroupThing(location);
|
|
|
|
}
|
|
|
|
|
|
|
|
private InventoryThing range(Supplier<Location> location, String slot) {
|
|
|
|
String[] indices = slot.split("-");
|
|
|
|
if (indices.length != 2) {
|
|
|
|
throw new IllegalArgumentException("Expected range format (e.g. 0-8), got: " + slot);
|
|
|
|
}
|
|
|
|
int first = Integer.parseInt(indices[0]);
|
|
|
|
int last = Integer.parseInt(indices[1]);
|
|
|
|
if (last < first) {
|
|
|
|
throw new IllegalArgumentException("Range end is less than range start: " + slot);
|
|
|
|
}
|
|
|
|
return new InventoryRangeThing(location, first, last);
|
|
|
|
}
|
|
|
|
|
|
|
|
private InventoryThing index(Supplier<Location> location, String slot) {
|
|
|
|
int index = Integer.parseInt(slot);
|
|
|
|
return new InventoryIndexThing(location, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|