Bottle Your XP doesn't decrease levels if level curve is changed
Partonetrain opened this issue ยท 3 comments
Information
Minecraft version: 1.20.1
Modloader: Fabric
Fabric loader version: 0.15.11
Environment: Both Singleplayer / Multiplayer
Mod name: Bottle Your XP
Mod version: 3.3
Collective version 1.20.1-7.6.1 (I think this is where the issue lies ... seems like experience curve is hardcoded here instead of referencing Player#getXpNeededForNextLevel)
Description
When experience level curve is changed, Bottling does not decrease level amount, only points, making experience dupable. To reproduce, set own level with commands, then shift-click glass bottle
No crash.
I am unsure how to fix this. I see you're the author of the mod, could you help me out?
I'm already checking for player.getXpNeededForNextLevel()
:
But I guess this is hardcoded?
Unfortunately I don't think there's a better way to re-implement getExperienceForLevel than just making it build a list of level->exp conversions (using player.getXpNeededForNextLevel())
I was having the same issue with Fixed Levels, where I have all the levels set to cost the same amount of xp.
I don't know java but I guess the collective library is using the vanilla curve? what functions should I edit so it recognizes that my levels take 30 points of xp?
edit: I gave it a shot to edit ExperienceFunctions but I don't know how to build the project.
Here's my code:
package com.natamus.collective.functions;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
public class ExperienceFunctions {
public static boolean canConsumeXp(final Player ep, final int xp) {
if (ep.isCreative()) {
return true;
}
return xp <= 0 || getPlayerXP(ep) >= xp;
}
public static void consumeXp(final Player ep, final int xp) {
if (xp <= 0) {
return;
}
final int playerXP = getPlayerXP(ep);
if (playerXP >= xp) {
addPlayerXP(ep, -xp);
}
if (ep instanceof ServerPlayer) {
((ServerPlayer) ep).connection.send(new ClientboundEntityEventPacket(ep, (byte) 9));
}
}
public static int getPlayerXP(final Player player) {
return (int) (getExperienceForLevel(player.experienceLevel) + player.experienceProgress);
}
public static void addPlayerXP(final Player player, final int amount) {
final int experience = getPlayerXP(player) + amount;
player.totalExperience = experience;
player.experienceLevel = getLevelForExperience(experience);
final int expForLevel = getExperienceForLevel(player.experienceLevel);
player.experienceProgress = (float) (experience - expForLevel);
}
public static int getLevelForExperience(int targetXp) {
int target = targetXp / 30;
return target;
}
public static int getExperienceForLevel(final int level) {
if (level == 0) {
return 0;
} else {
return level * 30;
}
}
}