MobArena/src/main/java/com/garbagemule/MobArena/things/InventoryThingParser.java

81 lines
2.5 KiB
Java
Raw Normal View History

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;
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);
}
}