From 8b9d8281d04bf32e0285ca8d27d4686840e3fe1c Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Wed, 11 Aug 2021 17:45:45 +0200 Subject: [PATCH] Fix bugs, add new event for other mods to use, allow customisation of xp storage --- README.md | 7 ++- build.gradle | 9 ++- gradle.properties | 2 +- src/main/java/eu/pb4/graves/GravesMod.java | 49 +++++++-------- .../eu/pb4/graves/compat/TrinketsCompat.java | 59 +++++++++--------- .../java/eu/pb4/graves/config/Config.java | 3 + .../eu/pb4/graves/config/ConfigManager.java | 7 ++- .../eu/pb4/graves/config/data/ConfigData.java | 8 ++- .../event/PlayerGraveItemAddedEvent.java | 25 ++++++++ .../java/eu/pb4/graves/grave/GraveBlock.java | 6 +- .../java/eu/pb4/graves/grave/GraveGui.java | 3 +- .../pb4/graves/grave/GravesXPCalculation.java | 62 +++++++++++++++++++ .../pb4/graves/mixin/LivingEntityMixin.java | 35 +++++++---- .../eu/pb4/graves/other/GraveListGui.java | 4 +- .../java/eu/pb4/graves/other/GraveUtils.java | 15 +++++ 15 files changed, 211 insertions(+), 83 deletions(-) create mode 100644 src/main/java/eu/pb4/graves/event/PlayerGraveItemAddedEvent.java create mode 100644 src/main/java/eu/pb4/graves/grave/GravesXPCalculation.java diff --git a/README.md b/README.md index 8ace1eb..4a35dd4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ If you have any questions, you can ask them on my [Discord](https://discord.com/ ![Example image](https://i.imgur.com/hfyd10Q.png) -Fun fact, I died 147 times while making this mod + 17 on 2nd account (so far) +Fun fact, I died 237 times while making this mod + 35 on 2nd account (so far) ## Commands (and permissions): - `/graves` - Main command, shows list of users graves (`universal_graves.list`, available by default) @@ -18,7 +18,7 @@ Additionally, by having `universal_graves.teleport` permission, you can teleport ## Configuration: You can find config file in `./config/unicversal-graves.json`. -[Formatting uses PlaceholderAPI's Text Parser for which docs you can find here](https://github.com/Patbox/FabricPlaceholderAPI/blob/1.17/TEXT_FORMATTING.md). +[Formatting uses Simplified Text for which docs you can find here](). Additionally, every message type has few own local variables. ```json5 @@ -32,6 +32,9 @@ Additionally, every message type has few own local variables. "protectionTime": 300, // Time for which graves should be protected (is seconds) "shouldBreak": true, // Changes if grave should break after some time "breakAfter": 900, // Time after which grave will break + "storeExperience": true, // If true, experience points will be stored in grave + "xpStorageType": "vanilla", // Allows to change how much of xp is stored, `none` for nothing, `vanilla` for vanilla amount `percent_levels` for percent of levels and `percent_points` for percent of points + "xpPercentTypeValue": 100.0, // Changes how much percent of xp will be stored, works only with xpStorageType of `percent_...` "createGravesFromPvP": true, // If false, after dying from another players attack grave won't be created "dropItemsAfterExpiring": true, // If items should drop breaking from expiration "hologram": true, // Enables hologram diff --git a/build.gradle b/build.gradle index ac4dd94..10e3fd9 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,6 @@ repositories { maven { url 'https://maven.nucleoid.xyz' } maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } maven { url 'https://api.modrinth.com/maven' } - //mavenLocal() /*maven { name = "TerraformersMC" @@ -48,10 +47,10 @@ dependencies { modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modImplementation include("eu.pb4:sgui:1.0.0-rc3-1.17.1") - modImplementation include("eu.pb4:hologram-api:0.1.2+1.17.1") - modImplementation include("eu.pb4:placeholder-api:1.0.1+1.17") - modImplementation include("eu.pb4:polymer:0.1.0-pre9+1.17.1") + modImplementation include("eu.pb4:sgui:1.0.0-rc4+1.17.1") + modImplementation include("eu.pb4:hologram-api:0.2.1+1.17.1") + modImplementation include("eu.pb4:placeholder-api:1.1.0+1.17.1") + modImplementation include("eu.pb4:polymer:0.1.0-rc.4+1.17.1") modImplementation include("fr.catcore:server-translations-api:1.4.5+1.17") modImplementation include("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") diff --git a/gradle.properties b/gradle.properties index 233bf4e..8eab5d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.11.3 # Mod Properties - mod_version = 1.0.7+1.17.1 + mod_version = 1.0.8+1.17.1 maven_group = eu.pb4 archives_base_name = graves diff --git a/src/main/java/eu/pb4/graves/GravesMod.java b/src/main/java/eu/pb4/graves/GravesMod.java index bfbcf2b..be93f80 100644 --- a/src/main/java/eu/pb4/graves/GravesMod.java +++ b/src/main/java/eu/pb4/graves/GravesMod.java @@ -2,9 +2,9 @@ import eu.pb4.graves.compat.GomlCompat; import eu.pb4.graves.compat.TrinketsCompat; +import eu.pb4.graves.config.ConfigManager; import eu.pb4.graves.grave.GraveBlock; import eu.pb4.graves.grave.GraveBlockEntity; -import eu.pb4.graves.config.ConfigManager; import eu.pb4.graves.grave.GraveManager; import eu.pb4.graves.other.Commands; import eu.pb4.polymer.PolymerMod; @@ -12,38 +12,35 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class GravesMod implements ModInitializer { - public static final Logger LOGGER = LogManager.getLogger("Universal Graves"); - public static String VERSION = FabricLoader.getInstance().getModContainer("universal-graves").get().getMetadata().getVersion().getFriendlyString(); - - @Override - public void onInitialize() { - Registry.register(Registry.BLOCK, new Identifier("universal_graves", "grave"), GraveBlock.INSTANCE); - GraveBlockEntity.BLOCK_ENTITY_TYPE = Registry.register(Registry.BLOCK_ENTITY_TYPE, "universal_graves:grave", FabricBlockEntityTypeBuilder.create(GraveBlockEntity::new, GraveBlock.INSTANCE).build(null)); - Commands.register(); - PolymerMod.registerVirtualBlockEntity(new Identifier("universal_graves", "grave")); - FabricLoader loader = FabricLoader.getInstance(); - - if (loader.isModLoaded("trinkets")) { - TrinketsCompat.register(); - } - if (loader.isModLoaded("goml")) { - GomlCompat.register(); - } + public static final Logger LOGGER = LogManager.getLogger("Universal Graves"); + public static String VERSION = FabricLoader.getInstance().getModContainer("universal-graves").get().getMetadata().getVersion().getFriendlyString(); - ServerLifecycleEvents.SERVER_STARTING.register((server) -> ConfigManager.loadConfig()); - ServerLifecycleEvents.SERVER_STARTED.register((server -> - GraveManager.INSTANCE = (GraveManager) server.getOverworld().getPersistentStateManager().getOrCreate((nbtCompound) -> GraveManager.fromNbt(nbtCompound), - () -> new GraveManager(), - "universal-graves")) - ); - } + @Override + public void onInitialize() { + Registry.register(Registry.BLOCK, new Identifier("universal_graves", "grave"), GraveBlock.INSTANCE); + GraveBlockEntity.BLOCK_ENTITY_TYPE = Registry.register(Registry.BLOCK_ENTITY_TYPE, "universal_graves:grave", FabricBlockEntityTypeBuilder.create(GraveBlockEntity::new, GraveBlock.INSTANCE).build(null)); + Commands.register(); + PolymerMod.registerVirtualBlockEntity(new Identifier("universal_graves", "grave")); + FabricLoader loader = FabricLoader.getInstance(); + if (loader.isModLoaded("trinkets")) { + TrinketsCompat.register(); + } + if (loader.isModLoaded("goml")) { + GomlCompat.register(); + } + ServerLifecycleEvents.SERVER_STARTING.register((server) -> ConfigManager.loadConfig()); + ServerLifecycleEvents.SERVER_STARTED.register((server -> + GraveManager.INSTANCE = (GraveManager) server.getOverworld().getPersistentStateManager().getOrCreate(GraveManager::fromNbt, + GraveManager::new, + "universal-graves")) + ); + } } diff --git a/src/main/java/eu/pb4/graves/compat/TrinketsCompat.java b/src/main/java/eu/pb4/graves/compat/TrinketsCompat.java index f30e230..05ec29a 100644 --- a/src/main/java/eu/pb4/graves/compat/TrinketsCompat.java +++ b/src/main/java/eu/pb4/graves/compat/TrinketsCompat.java @@ -4,47 +4,46 @@ import dev.emi.trinkets.api.TrinketInventory; import dev.emi.trinkets.api.TrinketsApi; import dev.emi.trinkets.api.event.TrinketDropCallback; +import eu.pb4.graves.event.PlayerGraveItemAddedEvent; import eu.pb4.graves.event.PlayerGraveItemsEvent; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; public class TrinketsCompat { public static void register() { - PlayerGraveItemsEvent.EVENT.register((player, items) -> { - TrinketsApi.getTrinketComponent(player).ifPresent(trinkets -> trinkets.forEach((ref, stack) -> { - if (stack.isEmpty()) { - return; - } + PlayerGraveItemsEvent.EVENT.register((player, items) -> TrinketsApi.getTrinketComponent(player).ifPresent(trinkets -> trinkets.forEach((ref, stack) -> { + if (stack.isEmpty() || PlayerGraveItemAddedEvent.EVENT.invoker().canAddItem(player, stack) == ActionResult.FAIL) { + return; + } - TrinketEnums.DropRule dropRule = TrinketsApi.getTrinket(stack.getItem()).getDropRule(stack, ref, player); + TrinketEnums.DropRule dropRule = TrinketsApi.getTrinket(stack.getItem()).getDropRule(stack, ref, player); - dropRule = TrinketDropCallback.EVENT.invoker().drop(dropRule, stack, ref, player); + dropRule = TrinketDropCallback.EVENT.invoker().drop(dropRule, stack, ref, player); - TrinketInventory inventory = ref.inventory(); + TrinketInventory inventory = ref.inventory(); - if (dropRule == TrinketEnums.DropRule.DEFAULT) { - dropRule = inventory.getSlotType().getDropRule(); - } + if (dropRule == TrinketEnums.DropRule.DEFAULT) { + dropRule = inventory.getSlotType().getDropRule(); + } - if (dropRule == TrinketEnums.DropRule.DEFAULT) { - if (EnchantmentHelper.hasVanishingCurse(stack)) { - dropRule = TrinketEnums.DropRule.DESTROY; - } else { - dropRule = TrinketEnums.DropRule.DROP; - } + if (dropRule == TrinketEnums.DropRule.DEFAULT) { + if (EnchantmentHelper.hasVanishingCurse(stack)) { + dropRule = TrinketEnums.DropRule.DESTROY; + } else { + dropRule = TrinketEnums.DropRule.DROP; } - - switch (dropRule) { - case DROP: - items.add(stack.copy()); - case DESTROY: - inventory.setStack(ref.index(), ItemStack.EMPTY); - break; - default: - break; - } - })); - - }); + } + + switch (dropRule) { + case DROP: + items.add(stack.copy()); + case DESTROY: + inventory.setStack(ref.index(), ItemStack.EMPTY); + break; + default: + break; + } + }))); } } diff --git a/src/main/java/eu/pb4/graves/config/Config.java b/src/main/java/eu/pb4/graves/config/Config.java index cbac1ba..c9a353c 100644 --- a/src/main/java/eu/pb4/graves/config/Config.java +++ b/src/main/java/eu/pb4/graves/config/Config.java @@ -3,6 +3,7 @@ import eu.pb4.graves.grave.GravesLookType; import eu.pb4.graves.config.data.ConfigData; +import eu.pb4.graves.grave.GravesXPCalculation; import eu.pb4.placeholders.TextParser; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; @@ -37,11 +38,13 @@ public final class Config { public final Text creationFailedPvPGraveMessage; @Nullable public final Text creationFailedClaimGraveMessage; + public final GravesXPCalculation xpCalc; public Config(ConfigData data) { this.configData = data; this.style = GravesLookType.byName(configData.graveType); + this.xpCalc = GravesXPCalculation.byName(configData.xpStorageType); this.hologramProtectedText = parse(data.hologramProtectedText); this.hologramText = parse(data.hologramText); diff --git a/src/main/java/eu/pb4/graves/config/ConfigManager.java b/src/main/java/eu/pb4/graves/config/ConfigManager.java index de279f2..54efd95 100644 --- a/src/main/java/eu/pb4/graves/config/ConfigManager.java +++ b/src/main/java/eu/pb4/graves/config/ConfigManager.java @@ -2,12 +2,15 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import eu.pb4.graves.GravesMod; import eu.pb4.graves.config.data.ConfigData; import net.fabricmc.loader.api.FabricLoader; import org.apache.commons.io.IOUtils; import java.io.*; +import java.nio.charset.StandardCharsets; public class ConfigManager { public static final int VERSION = 1; @@ -34,14 +37,14 @@ public static boolean loadConfig() { if (configFile.exists()) { - String json = IOUtils.toString(new InputStreamReader(new FileInputStream(configFile), "UTF-8")); + String json = IOUtils.toString(new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8)); config = GSON.fromJson(json, ConfigData.class); } else { config = new ConfigData(); } - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(configFile), "UTF-8")); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8)); writer.write(GSON.toJson(config)); writer.close(); diff --git a/src/main/java/eu/pb4/graves/config/data/ConfigData.java b/src/main/java/eu/pb4/graves/config/data/ConfigData.java index e9d1762..92cf6ee 100644 --- a/src/main/java/eu/pb4/graves/config/data/ConfigData.java +++ b/src/main/java/eu/pb4/graves/config/data/ConfigData.java @@ -1,6 +1,8 @@ package eu.pb4.graves.config.data; import eu.pb4.graves.config.ConfigManager; +import eu.pb4.graves.grave.GravesLookType; +import eu.pb4.graves.grave.GravesXPCalculation; import java.util.ArrayList; import java.util.List; @@ -8,7 +10,7 @@ public class ConfigData { public int CONFIG_VERSION_DONT_TOUCH_THIS = ConfigManager.VERSION; public String _comment = "Before changing anything, see https://github.com/Patbox/UniversalGraves#configuration"; - public String graveType = "player_head"; + public String graveType = GravesLookType.PLAYER_HEAD.name; public String lockedTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjdjYWI1NmM4MmNiODFiZGI5OTc5YTQ2NGJjOWQzYmEzZTY3MjJiYTEyMmNmNmM1Mjg3MzAxMGEyYjU5YWVmZSJ9fX0="; public String unlockedTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjdjYWI1NmM4MmNiODFiZGI5OTc5YTQ2NGJjOWQzYmEzZTY3MjJiYTEyMmNmNmM1Mjg3MzAxMGEyYjU5YWVmZSJ9fX0="; @@ -18,6 +20,10 @@ public class ConfigData { public boolean shouldBreak = true; public int breakAfter = 900; + public boolean storeExperience = true; + public String xpStorageType = GravesXPCalculation.VANILLA.name; + public double xpPercentTypeValue = 100; + public boolean createGravesFromPvP = true; public boolean createGravesInClaims = true; public boolean dropItemsAfterExpiring = true; diff --git a/src/main/java/eu/pb4/graves/event/PlayerGraveItemAddedEvent.java b/src/main/java/eu/pb4/graves/event/PlayerGraveItemAddedEvent.java new file mode 100644 index 0000000..6c34080 --- /dev/null +++ b/src/main/java/eu/pb4/graves/event/PlayerGraveItemAddedEvent.java @@ -0,0 +1,25 @@ +package eu.pb4.graves.event; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.item.ItemStack; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; + +import java.util.List; + +public interface PlayerGraveItemAddedEvent { + Event EVENT = EventFactory.createArrayBacked(PlayerGraveItemAddedEvent.class, + (listeners) -> (player, item) -> { + for (PlayerGraveItemAddedEvent listener : listeners) { + ActionResult result = listener.canAddItem(player, item); + + if (result != ActionResult.PASS) { + return result; + } + } + return ActionResult.PASS; + }); + + ActionResult canAddItem(ServerPlayerEntity player, ItemStack item); +} diff --git a/src/main/java/eu/pb4/graves/grave/GraveBlock.java b/src/main/java/eu/pb4/graves/grave/GraveBlock.java index f72b31f..9220c07 100644 --- a/src/main/java/eu/pb4/graves/grave/GraveBlock.java +++ b/src/main/java/eu/pb4/graves/grave/GraveBlock.java @@ -65,7 +65,11 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt BlockEntity blockEntity = world.getBlockEntity(pos); if (blockEntity instanceof GraveBlockEntity grave && grave.info.canTakeFrom(player)) { - new GraveGui((ServerPlayerEntity) player, grave).open(); + if (grave.info.itemCount > 0) { + new GraveGui((ServerPlayerEntity) player, grave).open(); + } else { + world.setBlockState(pos, grave.replacedBlockState, Block.NOTIFY_ALL); + } return ActionResult.SUCCESS; } return super.onUse(state, world, pos, player, hand, hit); diff --git a/src/main/java/eu/pb4/graves/grave/GraveGui.java b/src/main/java/eu/pb4/graves/grave/GraveGui.java index bd6dd0d..6fc1c03 100644 --- a/src/main/java/eu/pb4/graves/grave/GraveGui.java +++ b/src/main/java/eu/pb4/graves/grave/GraveGui.java @@ -71,7 +71,8 @@ public void onTick() { @Override public void onClose() { if (this.grave.isEmpty() && !this.grave.isRemoved()) { - this.grave.getWorld().setBlockState(this.grave.getPos(), Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL); + assert this.grave.getWorld() != null; + this.grave.getWorld().setBlockState(this.grave.getPos(), this.grave.replacedBlockState, Block.NOTIFY_ALL); } else { this.grave.updateItemCount(); } diff --git a/src/main/java/eu/pb4/graves/grave/GravesXPCalculation.java b/src/main/java/eu/pb4/graves/grave/GravesXPCalculation.java new file mode 100644 index 0000000..3aa3575 --- /dev/null +++ b/src/main/java/eu/pb4/graves/grave/GravesXPCalculation.java @@ -0,0 +1,62 @@ +package eu.pb4.graves.grave; + +import eu.pb4.graves.config.ConfigManager; +import net.minecraft.server.network.ServerPlayerEntity; + +public enum GravesXPCalculation { + NONE("none", (p) -> 0), + VANILLA("vanilla", (p) -> Math.min(p.experienceLevel * 7, 100)), + PERCENT_POINTS("percent_points", (p) -> { + int points = 0; + + for (int i = 0; i < p.experienceLevel; i++) { + if (i >= 30) { + points += 112 + (i - 30) * 9; + } else { + points += i >= 15 ? 37 + (i - 15) * 5 : 7 + i * 2; + } + } + + points += p.experienceProgress * p.getNextLevelExperience(); + return (int) (points * ConfigManager.getConfig().configData.xpPercentTypeValue / 100); + }), + + PERCENT_LEVELS("percent_levels", (p) -> { + int points = 0; + double percent = ConfigManager.getConfig().configData.xpPercentTypeValue / 100; + + for (int i = 0; i < p.experienceLevel * percent; i++) { + if (i >= 30) { + points += 112 + (i - 30) * 9; + } else { + points += i >= 15 ? 37 + (i - 15) * 5 : 7 + i * 2; + } + } + + points += p.experienceProgress * p.getNextLevelExperience() * percent; + return points; + }); + + public final String name; + public final Player2XP converter; + + GravesXPCalculation(String name, Player2XP converter) { + this.name = name; + this.converter = converter; + } + + public static GravesXPCalculation byName(String name) { + for (GravesXPCalculation type : values()) { + if (type.name.equals(name)) { + return type; + } + } + return GravesXPCalculation.NONE; + } + + @FunctionalInterface + public interface Player2XP { + int calc(ServerPlayerEntity player); + } + +} diff --git a/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java b/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java index 2a0eacb..8db1dfc 100644 --- a/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java +++ b/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java @@ -1,6 +1,7 @@ package eu.pb4.graves.mixin; import eu.pb4.graves.event.PlayerGraveCreationEvent; +import eu.pb4.graves.event.PlayerGraveItemAddedEvent; import eu.pb4.graves.event.PlayerGraveItemsEvent; import eu.pb4.graves.config.Config; import eu.pb4.graves.config.ConfigManager; @@ -21,10 +22,14 @@ import net.minecraft.state.property.Properties; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.ItemScatterer; import net.minecraft.util.Util; +import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.GameRules; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -36,6 +41,7 @@ @Mixin(LivingEntity.class) public abstract class LivingEntityMixin { + @Shadow protected int playerHitTimer; @Inject(method = "drop", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;dropInventory()V", shift = At.Shift.BEFORE), cancellable = true) private void replaceWithGrave(DamageSource source, CallbackInfo ci) { @@ -46,7 +52,7 @@ private void replaceWithGrave(DamageSource source, CallbackInfo ci) { try { Config config = ConfigManager.getConfig(); - Text text = null; + Text text; Map placeholders = Map.of( "position", new LiteralText("" + player.getBlockPos().toShortString()), "world", new LiteralText(GraveUtils.toWorldName(player.getServerWorld().getRegistryKey().getValue())) @@ -67,33 +73,38 @@ private void replaceWithGrave(DamageSource source, CallbackInfo ci) { for (int i = 0; i < player.getInventory().size(); ++i) { ItemStack itemStack = player.getInventory().getStack(i); - if (!itemStack.isEmpty()) { - if (EnchantmentHelper.hasVanishingCurse(itemStack)) { - player.getInventory().removeStack(i); - } else { - items.add(player.getInventory().removeStack(i)); - } + if (!itemStack.isEmpty() + && PlayerGraveItemAddedEvent.EVENT.invoker().canAddItem(player, itemStack) != ActionResult.FAIL + && !GraveUtils.hasSoulboundEnchantment(itemStack)) { + items.add(player.getInventory().removeStack(i)); } } PlayerGraveItemsEvent.EVENT.invoker().modifyItems(player, items); + int i = 0; + if (config.configData.storeExperience) { + i = config.xpCalc.converter.calc(player); + } - if (items.size() == 0) { + if (items.size() == 0 && i == 0) { return; } - BlockState blockState = player.getServerWorld().getBlockState(gravePos); + BlockState oldBlockState = player.getServerWorld().getBlockState(gravePos); player.getServerWorld().setBlockState(gravePos, GraveBlock.INSTANCE.getDefaultState().with(Properties.ROTATION, player.getRandom().nextInt(15))); BlockEntity entity = player.getServerWorld().getBlockEntity(gravePos); if (entity instanceof GraveBlockEntity grave) { - int i = player.experienceLevel * 7; - grave.setGrave(player.getGameProfile(), items, i > 100 ? 100 : i, source.getDeathMessage(player), blockState); - player.experienceLevel = 0; + if (config.configData.storeExperience) { + player.experienceLevel = 0; + } + + grave.setGrave(player.getGameProfile(), items, i, source.getDeathMessage(player), oldBlockState); text = config.createdGraveMessage; placeholders = grave.info.getPlaceholders(); } else { text = config.creationFailedGraveMessage; + ItemScatterer.spawn(player.getServerWorld(), gravePos, DefaultedList.copyOf(ItemStack.EMPTY, items.toArray(new ItemStack[0]))); } } else { text = switch (result.result()) { diff --git a/src/main/java/eu/pb4/graves/other/GraveListGui.java b/src/main/java/eu/pb4/graves/other/GraveListGui.java index d738830..a7a6117 100644 --- a/src/main/java/eu/pb4/graves/other/GraveListGui.java +++ b/src/main/java/eu/pb4/graves/other/GraveListGui.java @@ -30,9 +30,9 @@ public class GraveListGui extends SimpleGui { public GraveListGui(ServerPlayerEntity player, GameProfile profile) { super(ScreenHandlerType.GENERIC_9X3, player, false); - targetUUID = player.getUuid(); + this.targetUUID = profile.getId(); - if (player.getUuid().equals(profile.getId())) { + if (player.getUuid().equals(this.targetUUID)) { this.setTitle(ConfigManager.getConfig().guiTitle); } else { this.setTitle(PlaceholderAPI.parsePredefinedText( diff --git a/src/main/java/eu/pb4/graves/other/GraveUtils.java b/src/main/java/eu/pb4/graves/other/GraveUtils.java index 349e056..c7068ca 100644 --- a/src/main/java/eu/pb4/graves/other/GraveUtils.java +++ b/src/main/java/eu/pb4/graves/other/GraveUtils.java @@ -4,12 +4,15 @@ import eu.pb4.graves.event.GraveValidPosCheckEvent; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.tag.Tag; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -19,6 +22,8 @@ public class GraveUtils { public static final Identifier REPLACEABLE_TAG = new Identifier("universal_graves","replaceable"); + + public static BlockCheckResult findGravePosition(ServerPlayerEntity player, ServerWorld world, BlockPos blockPos, Tag replaceable) { int maxDistance = 8; int line = 1; @@ -101,4 +106,14 @@ public static String toWorldName(Identifier identifier) { } return String.join("", parts); } + + public static boolean hasSoulboundEnchantment(ItemStack stack) { + for (var enchant : EnchantmentHelper.get(stack).keySet()) { + var key = Registry.ENCHANTMENT.getId(enchant); + if (key.getPath().contains("soulbound") || key.getPath().contains("soul_bound")) { + return true; + } + } + return false; + } }