you can now give yourself custom items with necessary contexts

This commit is contained in:
XTerPL 2025-01-22 01:39:00 +01:00
parent 78961b0cac
commit 31c881aa41
7 changed files with 127 additions and 17 deletions

View file

@ -16,7 +16,6 @@
package de.blazemcworld.blazinggames.commands;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.items.ContextlessItem;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.items.CustomItems;
import net.kyori.adventure.text.Component;
@ -30,6 +29,7 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
@ -49,15 +49,10 @@ public class CustomGiveCommand implements CommandExecutor, TabCompleter {
return true;
}
if(strings.length > 2) {
CommandHelper.sendUsage(commandSender, command);
return true;
}
CustomItem<?> itemType = CustomItems.getByKey(BlazingGames.get().key(strings[0]));
int count = 1;
if(!(itemType instanceof ContextlessItem contextlessItemType))
if(itemType == null)
{
commandSender.sendMessage(Component.text("Unknown custom item: " + strings[0] + "!").color(NamedTextColor.RED));
return true;
@ -67,10 +62,34 @@ public class CustomGiveCommand implements CommandExecutor, TabCompleter {
count = Integer.parseInt(strings[1]);
}
ItemStack item = contextlessItemType.create();
item.setAmount(count);
String unparsedContext = "";
p.getInventory().addItem(item);
if(strings.length > 2)
{
List<String> contextStrings = new ArrayList<>(List.of(strings));
contextStrings.removeFirst();
contextStrings.removeFirst();
unparsedContext = String.join(" ", contextStrings);
}
try {
ItemStack item = itemType.createWithUnparsed(p, unparsedContext);
item.setAmount(count);
p.getInventory().addItem(item);
}
catch(ParseException parsingException) {
commandSender.sendMessage(Component.text("Parsing Exception: "
+ parsingException.getMessage()
+ " at " + parsingException.getErrorOffset())
.color(NamedTextColor.RED));
}
catch(NumberFormatException numberException) {
commandSender.sendMessage(Component.text("Number Format Exception: "
+ numberException.getMessage())
.color(NamedTextColor.RED));
}
return true;
}
@ -81,12 +100,7 @@ public class CustomGiveCommand implements CommandExecutor, TabCompleter {
List<String> tabs = new ArrayList<>();
if(strings.length == 1) {
CustomItems.getAllItems().forEach(itemType -> {
if(itemType instanceof ContextlessItem)
{
tabs.add(itemType.getKey().getKey());
}
});
CustomItems.getAllItems().forEach(itemType -> tabs.add(itemType.getKey().getKey()));
}
return tabs;

View file

@ -20,16 +20,20 @@ import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.items.CustomItems;
import de.blazemcworld.blazinggames.items.contexts.ItemContext;
import de.blazemcworld.blazinggames.utils.TextLocation;
import io.azam.ulidj.ULID;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.text.ParseException;
import java.util.List;
public class DeathCrateKey extends CustomItem<DeathCrateKey.DeathCrateKeyContext> {
@ -79,6 +83,11 @@ public class DeathCrateKey extends CustomItem<DeathCrateKey.DeathCrateKeyContext
);
}
@Override
protected DeathCrateKeyContext parseContext(Player player, String string) throws ParseException {
return DeathCrateKeyContext.parse(player, string);
}
public static String getKeyULID(ItemStack item) {
if(CustomItems.DEATH_CRATE_KEY.matchItem(item))
{
@ -89,5 +98,28 @@ public class DeathCrateKey extends CustomItem<DeathCrateKey.DeathCrateKeyContext
}
public record DeathCrateKeyContext(String crateId) implements ItemContext {
public static DeathCrateKeyContext parse(Player player, String string) throws ParseException {
if (!string.contains(":")) {
string = "ulid:" + string;
}
String[] split = string.split(":", 2);
switch (split[0]) {
case "ulid" -> {
if (!ULID.isValid(split[1])) {
throw new ParseException("Invalid ULID!", string.length());
}
return new DeathCrateKeyContext(split[1]);
}
case "loc" -> {
Location loc = TextLocation.deserializeUserInput(player.getWorld(), split[1]);
return new DeathCrateKeyContext(CrateManager.getKeyULID(loc));
}
}
throw new ParseException("Invalid type '" + split[0] + "'", split[0].length() - 1);
}
}
}

View file

@ -1,9 +1,12 @@
package de.blazemcworld.blazinggames.items;
import de.blazemcworld.blazinggames.items.contexts.EmptyItemContext;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.text.ParseException;
public abstract class ContextlessItem extends CustomItem<EmptyItemContext> {
public final @NotNull ItemStack create() {
return create(EmptyItemContext.instance);
@ -13,6 +16,11 @@ public abstract class ContextlessItem extends CustomItem<EmptyItemContext> {
return modifyMaterial(stack);
}
@Override
protected EmptyItemContext parseContext(Player player, String string) throws ParseException {
return EmptyItemContext.parse(player, string);
}
protected @NotNull ItemStack modifyMaterial(ItemStack stack) {
return stack;
}

View file

@ -25,6 +25,7 @@ import net.kyori.adventure.text.Component;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemRarity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@ -32,6 +33,7 @@ import org.bukkit.inventory.meta.components.UseCooldownComponent;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.text.ParseException;
import java.util.List;
public abstract class CustomItem<T extends ItemContext> implements RecipeProvider, Keyed, ItemPredicate {
@ -94,6 +96,10 @@ public abstract class CustomItem<T extends ItemContext> implements RecipeProvide
return ItemChangeProviders.update(result);
}
public final @NotNull ItemStack createWithUnparsed(Player player, String string) throws ParseException {
return create(parseContext(player, string));
}
public ItemStack update(ItemStack stack) {
return stack.clone();
}
@ -129,4 +135,6 @@ public abstract class CustomItem<T extends ItemContext> implements RecipeProvide
public List<Component> lore(ItemStack stack) {
return List.of();
}
protected abstract T parseContext(Player player, String string) throws ParseException;
}

View file

@ -16,6 +16,19 @@
package de.blazemcworld.blazinggames.items.contexts;
import org.bukkit.entity.Player;
import java.text.ParseException;
public class EmptyItemContext implements ItemContext {
public static EmptyItemContext instance = new EmptyItemContext();
public static EmptyItemContext parse(Player player, String string) throws ParseException {
if(string.isBlank())
{
return instance;
}
throw new ParseException("Do mention that this item's context is empty.", string.length());
}
}

View file

@ -17,5 +17,4 @@
package de.blazemcworld.blazinggames.items.contexts;
public interface ItemContext {
}

View file

@ -24,6 +24,7 @@ import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.bukkit.World;
/**
* Location represented as a string
@ -74,6 +75,41 @@ public class TextLocation {
}
}
public static Location deserializeUserInput(World world, String serialized) {
if (serialized != null && !serialized.isEmpty()) {
String[] split = serialized.split(" ");
switch (split.length) {
case 6: { // world, x, y, z, yaw, pitch
String worldName = split[0];
double x = Double.parseDouble(split[1]);
double y = Double.parseDouble(split[2]);
double z = Double.parseDouble(split[3]);
float yaw = Float.parseFloat(split[4]);
float pitch = Float.parseFloat(split[5]);
return new Location(Bukkit.getWorld(worldName), x, y, z, yaw, pitch);
}
case 4: { // world, x, y, z
String worldName = split[0];
double x = Double.parseDouble(split[1]);
double y = Double.parseDouble(split[2]);
double z = Double.parseDouble(split[3]);
return new Location(Bukkit.getWorld(worldName), x, y, z);
}
case 3: { // x, y, z
double x = Double.parseDouble(split[0]);
double y = Double.parseDouble(split[1]);
double z = Double.parseDouble(split[2]);
return new Location(world, x, y, z);
}
default: {
return null;
}
}
} else {
return null;
}
}
public static class LocationTypeAdapter extends TypeAdapter<Location> {
@Override
public void write(JsonWriter out, Location value) throws IOException {