diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..f9e9887
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/blazemcworld/blazinggames/crates/CrateManager.java b/src/main/java/de/blazemcworld/blazinggames/crates/CrateManager.java
index 7db362e..df311df 100644
--- a/src/main/java/de/blazemcworld/blazinggames/crates/CrateManager.java
+++ b/src/main/java/de/blazemcworld/blazinggames/crates/CrateManager.java
@@ -15,31 +15,21 @@
*/
package de.blazemcworld.blazinggames.crates;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
+import java.util.*;
import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.persistence.PersistentDataType;
-import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.data.DataStorage;
import de.blazemcworld.blazinggames.data.compression.GZipCompressionProvider;
import de.blazemcworld.blazinggames.data.name.ULIDNameProvider;
import de.blazemcworld.blazinggames.data.storage.GsonStorageProvider;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import net.kyori.adventure.text.format.TextDecoration;
public class CrateManager {
private CrateManager() {}
- private static final NamespacedKey KEY = BlazingGames.get().key("death_crate_key");
private static final DataStorage crateStorage = DataStorage.forClass(
CrateManager.class, null,
new GsonStorageProvider<>(CrateData.class), new ULIDNameProvider(), new GZipCompressionProvider()
@@ -59,13 +49,11 @@ public class CrateManager {
}
public static String getKeyULID(Location loc) {
- List ids = crateStorage.query(data -> {
- return !data.opened &&
- data.location.getWorld().getName().equals(loc.getWorld().getName()) &&
- data.location.blockX() == loc.getBlockX() &&
- data.location.blockY() == loc.getBlockY() &&
- data.location.blockZ() == loc.getBlockZ();
- });
+ List ids = crateStorage.query(data -> !data.opened &&
+ data.location.getWorld().getName().equals(loc.getWorld().getName()) &&
+ data.location.blockX() == loc.getBlockX() &&
+ data.location.blockY() == loc.getBlockY() &&
+ data.location.blockZ() == loc.getBlockZ());
if (ids.isEmpty()) {
return null;
@@ -73,22 +61,17 @@ public class CrateManager {
if (ids.size() > 1) {
// sort the ULIDs to find the newest
- ids.sort((a, b) -> {
- return b.compareTo(a);
- });
+ ids.sort(Comparator.reverseOrder());
}
- return ids.get(0);
+ return ids.getFirst();
}
public static String createDeathCrate(UUID owner, PlayerInventory inventory, int exp, Location crateLocation) {
- ArrayList items = new ArrayList<>();
- for (ItemStack item : inventory.getStorageContents()) {
- items.add(item);
- }
+ ArrayList items = new ArrayList<>(Arrays.asList(inventory.getStorageContents()));
- List hotbarItems = items.subList(0, 9).stream().filter(i -> i == null ? true : CrateManager.shouldStayOnDeath(i)).toList();
- List inventoryItems = items.subList(9, 36).stream().filter(i -> i == null ? true : CrateManager.shouldStayOnDeath(i)).toList();
+ List hotbarItems = items.subList(0, 9).stream().filter(i -> i == null || CrateManager.shouldStayOnDeath(i)).toList();
+ List inventoryItems = items.subList(9, 36).stream().filter(i -> i == null || CrateManager.shouldStayOnDeath(i)).toList();
return crateStorage.storeNext(id -> new CrateData(
id, owner, false,
@@ -109,26 +92,4 @@ public class CrateManager {
public static void deleteCrate(String ulid) {
crateStorage.deleteData(ulid);
}
-
- public static ItemStack makeKey(String ulid, Location location) {
- ItemStack item = new ItemStack(Material.TRIPWIRE_HOOK, 1);
- ItemMeta meta = item.getItemMeta();
- meta.displayName(Component.text("Death Crate Key").color(NamedTextColor.DARK_RED).decoration(TextDecoration.ITALIC, false));
- meta.lore(List.of(
- Component.text("Location: %s, %s, %s in %s".formatted(location.getBlockX(), location.getBlockY(), location.getBlockZ(),
- location.getWorld().getName())).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true),
- Component.text("ULID: %s".formatted(ulid)).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true),
- Component.empty(),
- Component.text("Unlocks the crate at the location above. Can be used by anyone.").color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true)
- ));
- meta.getPersistentDataContainer().set(KEY, PersistentDataType.STRING, ulid);
- item.setItemMeta(meta);
- return item;
- }
-
- public static String getKeyULID(ItemStack item) {
- if (item == null) { return null; }
- if (!item.hasItemMeta()) { return null; }
- return item.getItemMeta().getPersistentDataContainer().get(KEY, PersistentDataType.STRING);
- }
}
diff --git a/src/main/java/de/blazemcworld/blazinggames/crates/DeathCrateKey.java b/src/main/java/de/blazemcworld/blazinggames/crates/DeathCrateKey.java
new file mode 100644
index 0000000..62e8c6c
--- /dev/null
+++ b/src/main/java/de/blazemcworld/blazinggames/crates/DeathCrateKey.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2025 The Blazing Games Maintainers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.blazemcworld.blazinggames.crates;
+
+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 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.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class DeathCrateKey extends CustomItem {
+ private static final NamespacedKey crateKey = BlazingGames.get().key("death_crate_key");
+
+ @Override
+ public @NotNull NamespacedKey getKey() {
+ return crateKey;
+ }
+
+ @Override
+ protected @NotNull Component itemName() {
+ return Component.text("Death Crate Key").color(NamedTextColor.DARK_RED);
+ }
+
+ @Override
+ protected @NotNull ItemStack modifyMaterial(ItemStack stack, DeathCrateKeyContext context) {
+ String crateId = context.crateId();
+ Location location = CrateManager.readCrate(crateId).location;
+
+ ItemMeta meta = stack.getItemMeta();
+
+ meta.getPersistentDataContainer().set(crateKey, PersistentDataType.STRING, crateId);
+ meta.lore(List.of(
+ Component.text("Location: %s, %s, %s in %s".formatted(location.getBlockX(), location.getBlockY(), location.getBlockZ(),
+ location.getWorld().getName())).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true),
+ Component.text("ULID: %s".formatted(crateId)).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true),
+ Component.empty(),
+ Component.text("Unlocks the crate at the location above. Can be used by anyone.").color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true)
+ ));
+
+ stack.setItemMeta(meta);
+
+ return stack;
+ }
+
+ public static String getKeyULID(ItemStack item) {
+ if(CustomItems.DEATH_CRATE_KEY.matchItem(item))
+ {
+ return item.getItemMeta().getPersistentDataContainer().get(crateKey, PersistentDataType.STRING);
+ }
+
+ return null;
+ }
+
+ public record DeathCrateKeyContext(String crateId) implements ItemContext {
+ }
+}
diff --git a/src/main/java/de/blazemcworld/blazinggames/events/BlockPlaceEventListener.java b/src/main/java/de/blazemcworld/blazinggames/events/BlockPlaceEventListener.java
index fd46245..2ea348a 100644
--- a/src/main/java/de/blazemcworld/blazinggames/events/BlockPlaceEventListener.java
+++ b/src/main/java/de/blazemcworld/blazinggames/events/BlockPlaceEventListener.java
@@ -19,7 +19,6 @@ import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.computing.BootedComputer;
import de.blazemcworld.blazinggames.computing.ComputerRegistry;
import de.blazemcworld.blazinggames.computing.types.ComputerTypes;
-import de.blazemcworld.blazinggames.crates.CrateManager;
import de.blazemcworld.blazinggames.items.CustomItem;
import de.blazemcworld.blazinggames.items.CustomItems;
import de.blazemcworld.blazinggames.items.CustomSlabs;
@@ -59,11 +58,6 @@ public class BlockPlaceEventListener implements Listener {
event.setCancelled(true);
}
- if (CrateManager.getKeyULID(event.getItemInHand()) != null) {
- event.setCancelled(true);
- return;
- }
-
if (event.getItemInHand().getType() == Material.SPAWNER) {
CreatureSpawner spawner = (CreatureSpawner) event.getBlock().getState();
CreatureSpawner item = (CreatureSpawner) ((BlockStateMeta) event.getItemInHand().getItemMeta()).getBlockState();
diff --git a/src/main/java/de/blazemcworld/blazinggames/events/DeathEventListener.java b/src/main/java/de/blazemcworld/blazinggames/events/DeathEventListener.java
index 58322dd..cd0b28b 100644
--- a/src/main/java/de/blazemcworld/blazinggames/events/DeathEventListener.java
+++ b/src/main/java/de/blazemcworld/blazinggames/events/DeathEventListener.java
@@ -16,8 +16,10 @@
package de.blazemcworld.blazinggames.events;
import de.blazemcworld.blazinggames.crates.CrateManager;
+import de.blazemcworld.blazinggames.crates.DeathCrateKey;
import de.blazemcworld.blazinggames.discord.DiscordApp;
import de.blazemcworld.blazinggames.discord.DiscordNotification;
+import de.blazemcworld.blazinggames.items.CustomItems;
import de.blazemcworld.blazinggames.utils.TextUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -88,6 +90,6 @@ public class DeathEventListener implements Listener {
event.setDroppedExp(0);
event.getDrops().clear();
String ulid = CrateManager.createDeathCrate(player.getUniqueId(), event.getPlayer().getInventory(), event.getPlayer().calculateTotalExperiencePoints(), crateLocation);
- event.getItemsToKeep().add(CrateManager.makeKey(ulid, crateLocation));
+ event.getItemsToKeep().add(CustomItems.DEATH_CRATE_KEY.create(new DeathCrateKey.DeathCrateKeyContext(ulid)));
}
}
diff --git a/src/main/java/de/blazemcworld/blazinggames/events/InteractEventListener.java b/src/main/java/de/blazemcworld/blazinggames/events/InteractEventListener.java
index 4cc219d..4092aa7 100644
--- a/src/main/java/de/blazemcworld/blazinggames/events/InteractEventListener.java
+++ b/src/main/java/de/blazemcworld/blazinggames/events/InteractEventListener.java
@@ -18,6 +18,7 @@ package de.blazemcworld.blazinggames.events;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.crates.CrateData;
import de.blazemcworld.blazinggames.crates.CrateManager;
+import de.blazemcworld.blazinggames.crates.DeathCrateKey;
import de.blazemcworld.blazinggames.enchantments.sys.CustomEnchantments;
import de.blazemcworld.blazinggames.enchantments.sys.EnchantmentHelper;
import de.blazemcworld.blazinggames.enchantments.sys.altar.AltarInterface;
@@ -86,20 +87,35 @@ public class InteractEventListener implements Listener {
if (block != null && block.getType() == Material.VAULT) vaultShit(block);
- if (eventItem != null && (CrateManager.getKeyULID(eventItem) != null)) {
- event.setCancelled(true);
- }
-
if (block != null && block.getType() == Material.END_PORTAL_FRAME && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
- ItemStack handItem = player.getInventory().getItem(hand);
- String ulid = (CustomItems.SKELETON_KEY.matchItem(handItem) || CustomItems.TO_GO_BOX.matchItem(handItem))
- ? CrateManager.getKeyULID(block.getLocation()) : CrateManager.getKeyULID(handItem);
- if (CustomItems.SKELETON_KEY.matchItem(handItem) || CustomItems.TO_GO_BOX.matchItem(handItem)) player.setCooldown(handItem, 200);
- if (ulid != null) {
- CrateData data = CrateManager.readCrate(ulid);
+ String crateId = CrateManager.getKeyULID(block.getLocation());
+
+ boolean allowOpening = false;
+
+ if(crateId != null) {
+ if(CustomItems.DEATH_CRATE_KEY.matchItem(eventItem)) {
+ String keyId = DeathCrateKey.getKeyULID(eventItem);
+
+ if(Objects.equals(crateId, keyId)) {
+ allowOpening = true;
+ }
+ }
+
+ if(CustomItems.SKELETON_KEY.matchItem(eventItem) || CustomItems.TO_GO_BOX.matchItem(eventItem)) {
+ assert eventItem != null;
+
+ if(!player.hasCooldown(eventItem)) {
+ allowOpening = true;
+ player.setCooldown(eventItem, 200);
+ }
+ }
+ }
+
+ if (allowOpening) {
+ CrateData data = CrateManager.readCrate(crateId);
Location crateLocation = data.location;
- if (CustomItems.TO_GO_BOX.matchItem(handItem)) {
+ if (CustomItems.TO_GO_BOX.matchItem(eventItem)) {
crateLocation.getBlock().breakNaturally();
ItemStack filledToGoBox = new ItemStack(Material.BUNDLE);
BundleMeta bundleMeta = (BundleMeta) filledToGoBox.getItemMeta();
@@ -117,80 +133,70 @@ public class InteractEventListener implements Listener {
}
filledToGoBox.setItemMeta(bundleMeta);
- player.getInventory().getItem(hand).setAmount(player.getInventory().getItem(hand).getAmount() - 1);
+ player.getInventory().getItem(hand).subtract(1);
if (player.getInventory().firstEmpty() != -1) {
player.getInventory().addItem(filledToGoBox);
} else {
player.getWorld().dropItemNaturally(player.getLocation(), filledToGoBox);
}
player.giveExp(data.exp);
- CrateManager.deleteCrate(ulid);
+ CrateManager.deleteCrate(crateId);
return;
}
- if (crateLocation != null && (
- crateLocation.blockX() == block.getX() && crateLocation.blockY() == block.getY() && crateLocation.blockZ() == block.getZ()
- )) {
- PlayerInventory inventory = player.getInventory();
+ PlayerInventory inventory = player.getInventory();
- if (
- (data.offhand != null && inventory.getItemInOffHand() != null && !inventory.getItemInOffHand().isEmpty()) ||
- (data.helmet != null && inventory.getHelmet() != null && !inventory.getHelmet().isEmpty()) ||
- (data.chestplate != null && inventory.getChestplate() != null && !inventory.getChestplate().isEmpty()) ||
- (data.leggings != null && inventory.getLeggings() != null && !inventory.getLeggings().isEmpty()) ||
- (data.boots != null && inventory.getBoots() != null && !inventory.getBoots().isEmpty())
- ) {
- player.sendActionBar(Component.text("Move your offhand/armor into your inventory to open").color(NamedTextColor.RED));
- return;
- }
-
- if (handItem.getAmount() > 1) {
- ItemStack newStack = handItem;
- newStack.setAmount(handItem.getAmount() - 1);
- inventory.setItem(hand, newStack);
- } else {
- inventory.setItem(hand, new ItemStack(Material.AIR));
- }
- crateLocation.getBlock().breakNaturally(true);
-
- if (data.offhand != null) inventory.setItemInOffHand(data.offhand);
- if (data.helmet != null) inventory.setHelmet(data.helmet);
- if (data.chestplate != null) inventory.setChestplate(data.chestplate);
- if (data.leggings != null) inventory.setLeggings(data.leggings);
- if (data.boots != null) inventory.setBoots(data.boots);
-
- int hotbarIndex = -1;
- for (ItemStack hotbarItem : data.hotbarItems) {
- hotbarIndex++;
- if (hotbarItem == null) continue;
- if (inventory.getItem(hotbarIndex) == null) {
- inventory.setItem(hotbarIndex, hotbarItem);
- } else {
- if (inventory.firstEmpty() == -1) {
- crateLocation.getWorld().dropItemNaturally(crateLocation, hotbarItem);
- }
- inventory.addItem(hotbarItem);
- }
- }
-
- int inventoryIndex = 8;
- for (ItemStack inventoryItem : data.inventoryItems) {
- inventoryIndex++;
- if (inventoryItem == null) continue;
- if (inventory.getItem(inventoryIndex) == null) {
- inventory.setItem(inventoryIndex, inventoryItem);
- } else {
- if (inventory.firstEmpty() == -1) {
- crateLocation.getWorld().dropItemNaturally(crateLocation, inventoryItem);
- }
- inventory.addItem(inventoryItem);
- }
- }
-
- player.giveExp(data.exp);
-
- CrateManager.deleteCrate(ulid);
+ if (
+ (data.offhand != null && inventory.getItemInOffHand() != null && !inventory.getItemInOffHand().isEmpty()) ||
+ (data.helmet != null && inventory.getHelmet() != null && !inventory.getHelmet().isEmpty()) ||
+ (data.chestplate != null && inventory.getChestplate() != null && !inventory.getChestplate().isEmpty()) ||
+ (data.leggings != null && inventory.getLeggings() != null && !inventory.getLeggings().isEmpty()) ||
+ (data.boots != null && inventory.getBoots() != null && !inventory.getBoots().isEmpty())
+ ) {
+ player.sendActionBar(Component.text("Move your offhand/armor into your inventory to open").color(NamedTextColor.RED));
+ return;
}
+
+ player.getInventory().getItem(hand).subtract(1);
+ crateLocation.getBlock().breakNaturally(true);
+
+ if (data.offhand != null) inventory.setItemInOffHand(data.offhand);
+ if (data.helmet != null) inventory.setHelmet(data.helmet);
+ if (data.chestplate != null) inventory.setChestplate(data.chestplate);
+ if (data.leggings != null) inventory.setLeggings(data.leggings);
+ if (data.boots != null) inventory.setBoots(data.boots);
+
+ int hotbarIndex = -1;
+ for (ItemStack hotbarItem : data.hotbarItems) {
+ hotbarIndex++;
+ if (hotbarItem == null) continue;
+ if (inventory.getItem(hotbarIndex) == null) {
+ inventory.setItem(hotbarIndex, hotbarItem);
+ } else {
+ if (inventory.firstEmpty() == -1) {
+ crateLocation.getWorld().dropItemNaturally(crateLocation, hotbarItem);
+ }
+ inventory.addItem(hotbarItem);
+ }
+ }
+
+ int inventoryIndex = 8;
+ for (ItemStack inventoryItem : data.inventoryItems) {
+ inventoryIndex++;
+ if (inventoryItem == null) continue;
+ if (inventory.getItem(inventoryIndex) == null) {
+ inventory.setItem(inventoryIndex, inventoryItem);
+ } else {
+ if (inventory.firstEmpty() == -1) {
+ crateLocation.getWorld().dropItemNaturally(crateLocation, inventoryItem);
+ }
+ inventory.addItem(inventoryItem);
+ }
+ }
+
+ player.giveExp(data.exp);
+
+ CrateManager.deleteCrate(crateId);
}
return;
}
diff --git a/src/main/java/de/blazemcworld/blazinggames/items/CustomItems.java b/src/main/java/de/blazemcworld/blazinggames/items/CustomItems.java
index 146f575..1aeb344 100644
--- a/src/main/java/de/blazemcworld/blazinggames/items/CustomItems.java
+++ b/src/main/java/de/blazemcworld/blazinggames/items/CustomItems.java
@@ -17,6 +17,7 @@ package de.blazemcworld.blazinggames.items;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.builderwand.BuilderWand;
+import de.blazemcworld.blazinggames.crates.DeathCrateKey;
import de.blazemcworld.blazinggames.crates.SkeletonKey;
import de.blazemcworld.blazinggames.crates.ToGoBoxItem;
import de.blazemcworld.blazinggames.enchantments.sys.CustomEnchantments;
@@ -36,6 +37,7 @@ public class CustomItems {
public static final Blueprint BLUEPRINT = new Blueprint();
public static final TomeAltar TOME_ALTAR = new TomeAltar();
public static final List CUSTOM_SLABS = new CustomSlabs().slabs;
+ public static final DeathCrateKey DEATH_CRATE_KEY = new DeathCrateKey();
public static final SkeletonKey SKELETON_KEY = new SkeletonKey();
public static final ToGoBoxItem TO_GO_BOX = new ToGoBoxItem();
public static final NetherStarChunk NETHER_STAR_CHUNK = new NetherStarChunk();
@@ -51,13 +53,14 @@ public class CustomItems {
public static final EnchantmentTome GREED_TOME = new EnchantmentTome(BlazingGames.get().key("greed_tome"), "Greed Tome", CustomEnchantments.SCAVENGER);
public static final EnchantmentTome DIM_TOME = new EnchantmentTome(BlazingGames.get().key("dim_tome"), "Dim Tome", CustomEnchantments.UNSHINY);
- public static Set list() {
- Set set = new java.util.HashSet<>(Set.of(
+ public static Set> list() {
+ Set> set = new java.util.HashSet<>(Set.of(
BUILDER_WAND,
PORTABLE_CRAFTING_TABLE,
TELEPORT_ANCHOR,
BLUEPRINT,
TOME_ALTAR,
+ DEATH_CRATE_KEY,
SKELETON_KEY,
TO_GO_BOX,
NETHER_STAR_CHUNK,
@@ -77,8 +80,8 @@ public class CustomItems {
return set;
}
- public static @Nullable CustomItem getByKey(NamespacedKey key) {
- for(CustomItem curr : list()) {
+ public static @Nullable CustomItem> getByKey(NamespacedKey key) {
+ for(CustomItem> curr : list()) {
if(curr.getKey().equals(key)) {
return curr;
}