diff --git a/CHANGELOG.md b/CHANGELOG.md index a8aff868..7ca9f879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ### Added: -- +- restrictOreExperienceDrops tags used to restrict what blocks drop Levelz's experience orbs +- Config option for restrictOreExperienceDrops +- Adjustable respawn options. Refunding levels, skill points and skill levels. +- Config option for levelRetainPercentage (how much of levels in %, rounded down, to keep after respawn) and levelRefundSkillPoints (if player should keep skill points in assigned skills or be fully refunded) ### Fixed: -- Fixed levelz xp bug +- ### Changed: -- \ No newline at end of file +- hardMode config usage deprecated \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 8810eee1..44c8d3da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.17.2 # Mod Properties - mod_version=2.0.6 + mod_version=2.0.7 maven_group=net.levelz archives_base_name=levelz diff --git a/src/main/java/net/levelz/config/LevelzConfig.java b/src/main/java/net/levelz/config/LevelzConfig.java index 7b688a78..dd163234 100644 --- a/src/main/java/net/levelz/config/LevelzConfig.java +++ b/src/main/java/net/levelz/config/LevelzConfig.java @@ -25,9 +25,16 @@ public class LevelzConfig implements ConfigData, ConfigSync { @ConfigEntry.Category("level_settings") public int pointsPerLevel = 3; @ConfigEntry.Category("level_settings") - @Comment("If true will reset stats on death") + @Comment("If true will reset stats on death \n!!!deprecated, not in use!!!") public boolean hardMode = false; @ConfigEntry.Category("level_settings") + @ConfigEntry.BoundedDiscrete(min = 0, max = 100) + @Comment("Retain x% of levels and skill points, round down") + public float levelRetainPercentage = 100; + @ConfigEntry.Category("level_settings") + @Comment("Fully regain all skill points after death") + public boolean levelRefundSkillPoints = false; + @ConfigEntry.Category("level_settings") public boolean disableMobFarms = true; @ConfigEntry.Category("level_settings") @Comment("Amount of allowed mob kills in a chunk") @@ -162,6 +169,9 @@ public class LevelzConfig implements ConfigData, ConfigSync { public float mobXPMultiplier = 1.0F; @ConfigEntry.Category("experience_settings") public boolean spawnerMobXP = false; + @ConfigEntry.Category("experience_settings") + @Comment("Datapack modifyable. Default entry 'minecraft:sculk'") + public boolean restrictOreExperienceDrops = true; @ConfigSync.ClientOnly @ConfigEntry.Category("gui_settings") diff --git a/src/main/java/net/levelz/init/EventInit.java b/src/main/java/net/levelz/init/EventInit.java index 04276ec2..241d2e81 100644 --- a/src/main/java/net/levelz/init/EventInit.java +++ b/src/main/java/net/levelz/init/EventInit.java @@ -21,6 +21,9 @@ import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.BlockPos; +import java.util.ArrayList; +import java.util.List; + public class EventInit { public static void init() { @@ -47,16 +50,49 @@ public static void init() { }); ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> { - if (ConfigInit.CONFIG.hardMode) { + LevelManager newLevelManager = ((LevelManagerAccess) newPlayer).getLevelManager(); + if (ConfigInit.CONFIG.levelRetainPercentage < 100) { + LevelManager oldLevelManager = ((LevelManagerAccess) oldPlayer).getLevelManager(); + float levelRetainPercentageFloat = ConfigInit.CONFIG.levelRetainPercentage / 100; + int retainedLevel = (int) (oldLevelManager.getOverallLevel() * levelRetainPercentageFloat); + + int usedSkillPoints = oldLevelManager.getOverallLevel() * ConfigInit.CONFIG.pointsPerLevel + ConfigInit.CONFIG.startPoints - oldLevelManager.getSkillPoints(); + if(!ConfigInit.CONFIG.levelRefundSkillPoints && usedSkillPoints > oldLevelManager.getSkillPoints()) { + int lossUnusedSkillPointsAmount = oldLevelManager.getSkillPoints() - ConfigInit.CONFIG.startPoints; + newLevelManager.setSkillPoints(ConfigInit.CONFIG.startPoints); + + List skillsList = new ArrayList<>(oldLevelManager.getPlayerSkills().keySet()); + int lossSkillsAmount = (oldLevelManager.getOverallLevel() - retainedLevel) * ConfigInit.CONFIG.pointsPerLevel - lossUnusedSkillPointsAmount; + while (lossSkillsAmount > 0 && !skillsList.isEmpty()) { + int skillIdPos = (int) (Math.random() * skillsList.size()); + int skillId = skillsList.get(skillIdPos); + if (oldLevelManager.getSkillLevel(skillId) == 0) { + skillsList.remove(skillIdPos); + continue; + } + oldLevelManager.setSkillLevel(skillId, oldLevelManager.getSkillLevel(skillId) - 1); + lossSkillsAmount--; + } + + List skillsList2 = new ArrayList<>(oldLevelManager.getPlayerSkills().keySet()); + for (int skillId : skillsList2) { + newLevelManager.setSkillLevel(skillId, oldLevelManager.getSkillLevel(skillId)); + } + PacketHelper.updatePlayerSkills(newPlayer, null); + } else { + newPlayer.getScoreboard().forEachScore(CriteriaInit.LEVELZ, newPlayer, ScoreAccess::resetScore); + + newLevelManager.setSkillPoints(ConfigInit.CONFIG.startPoints + retainedLevel * ConfigInit.CONFIG.pointsPerLevel); + } + newLevelManager.setOverallLevel(retainedLevel); + PacketHelper.updateLevels(newPlayer); newPlayer.getServer().getPlayerManager().sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.UPDATE_GAME_MODE, newPlayer)); - newPlayer.getScoreboard().forEachScore(CriteriaInit.LEVELZ, newPlayer, ScoreAccess::resetScore); } else { PacketHelper.updatePlayerSkills(newPlayer, oldPlayer); if (ConfigInit.CONFIG.resetCurrentXp) { - LevelManager levelManager = ((LevelManagerAccess) newPlayer).getLevelManager(); - levelManager.setLevelProgress(0); - levelManager.setTotalLevelExperience(0); + newLevelManager.setLevelProgress(0); + newLevelManager.setTotalLevelExperience(0); } PacketHelper.updateLevels(newPlayer); diff --git a/src/main/java/net/levelz/init/TagInit.java b/src/main/java/net/levelz/init/TagInit.java index 19888f56..975b2caf 100644 --- a/src/main/java/net/levelz/init/TagInit.java +++ b/src/main/java/net/levelz/init/TagInit.java @@ -1,6 +1,7 @@ package net.levelz.init; import net.levelz.LevelzMain; +import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.TagKey; @@ -8,7 +9,7 @@ public class TagInit { public static final TagKey RESTRICTED_FURNACE_EXPERIENCE_ITEMS = TagKey.of(RegistryKeys.ITEM, LevelzMain.identifierOf("restricted_furnace_experience_items")); - + public static final TagKey RESTRICTED_ORE_EXPERIENCE_BLOCKS = TagKey.of(RegistryKeys.BLOCK, LevelzMain.identifierOf("restricted_ore_experience_blocks")); public static void init() { } } diff --git a/src/main/java/net/levelz/mixin/block/BlockMixin.java b/src/main/java/net/levelz/mixin/block/BlockMixin.java index 7b64d3c8..93e4b655 100644 --- a/src/main/java/net/levelz/mixin/block/BlockMixin.java +++ b/src/main/java/net/levelz/mixin/block/BlockMixin.java @@ -1,23 +1,19 @@ package net.levelz.mixin.block; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.fabricmc.fabric.api.tag.convention.v2.ConventionalBlockTags; import net.levelz.access.LevelManagerAccess; import net.levelz.entity.LevelExperienceOrbEntity; import net.levelz.init.ConfigInit; import net.levelz.init.EntityInit; +import net.levelz.init.TagInit; import net.levelz.level.LevelManager; import net.levelz.util.BonusHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContextParameterSet; -import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; @@ -25,6 +21,7 @@ import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -35,7 +32,8 @@ import java.util.List; @Mixin(Block.class) -public class BlockMixin { +public abstract class BlockMixin { + @Shadow private BlockState defaultState; @Unique @Nullable @@ -68,7 +66,16 @@ private static void getDroppedStacksMixin(BlockState state, ServerWorld world, B @Inject(method = "dropExperience", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ExperienceOrbEntity;spawn(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;I)V")) protected void dropExperienceMixin(ServerWorld world, BlockPos pos, int size, CallbackInfo info) { - if (ConfigInit.CONFIG.oreXPMultiplier > 0.0F) { + boolean boolTagList = this.defaultState.isIn(TagInit.RESTRICTED_ORE_EXPERIENCE_BLOCKS); + if (ConfigInit.CONFIG.restrictOreExperienceDrops) { + if (ConfigInit.CONFIG.oreXPMultiplier > 0.0F && !boolTagList) { + LevelExperienceOrbEntity.spawn(world, Vec3d.ofCenter(pos), + (int) (size * ConfigInit.CONFIG.oreXPMultiplier + * (ConfigInit.CONFIG.dropXPbasedOnLvl && this.serverPlayerEntity != null + ? 1.0F + ConfigInit.CONFIG.basedOnMultiplier * ((LevelManagerAccess) this.serverPlayerEntity).getLevelManager().getOverallLevel() + : 1.0F))); + } + } else if (ConfigInit.CONFIG.oreXPMultiplier > 0.0F) { LevelExperienceOrbEntity.spawn(world, Vec3d.ofCenter(pos), (int) (size * ConfigInit.CONFIG.oreXPMultiplier * (ConfigInit.CONFIG.dropXPbasedOnLvl && this.serverPlayerEntity != null diff --git a/src/main/resources/assets/levelz/lang/en_us.json b/src/main/resources/assets/levelz/lang/en_us.json index ad7fc06a..41fa2d85 100644 --- a/src/main/resources/assets/levelz/lang/en_us.json +++ b/src/main/resources/assets/levelz/lang/en_us.json @@ -18,6 +18,8 @@ "text.autoconfig.levelz.option.devMode": "Dev Mode", "text.autoconfig.levelz.option.hardMode": "Hard Mode", + "text.autoconfig.levelz.option.levelRetainPercentage": "Retained level after death", + "text.autoconfig.levelz.option.levelRefundSkillPoints": "Refund Attribute Points", "text.autoconfig.levelz.option.disableMobFarms": "Disable Mob Farms", "text.autoconfig.levelz.option.overallMaxLevel": "Overall Max Level", "text.autoconfig.levelz.option.allowHigherSkillLevel": "Allow Higher Skill Level", @@ -74,6 +76,7 @@ "text.autoconfig.levelz.option.tradingXPMultiplier": "Trading XP Multiplier", "text.autoconfig.levelz.option.mobXPMultiplier": "Mob XP Multiplier", "text.autoconfig.levelz.option.spawnerMobXP": "Spawner Mob XP", + "text.autoconfig.levelz.option.restrictOreExperienceDrops": "Restrict ore drop XP", "text.autoconfig.levelz.option.sortCraftingRecipesBySkill": "Sort Crafting Recipes By Skill", "text.autoconfig.levelz.option.inventoryButton": "Inventory Button", @@ -223,5 +226,7 @@ "advancements.adventure.level_100.title": "Level 100", "advancements.adventure.level_100.description": "Reach the unreachable level", - "tag.levelz.restricted_furnace_experience_items": "Restricted Furnace Experience Items" + "tag.levelz.restricted_furnace_experience_items": "Restricted Furnace Experience Items", + + "effect.levelz.soul_exhaust": "Soul Exhaust" } \ No newline at end of file diff --git a/src/main/resources/data/levelz/tags/block/restricted_ore_experience_blocks.json b/src/main/resources/data/levelz/tags/block/restricted_ore_experience_blocks.json new file mode 100644 index 00000000..c5f29ce3 --- /dev/null +++ b/src/main/resources/data/levelz/tags/block/restricted_ore_experience_blocks.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:sculk" + ] +} \ No newline at end of file