Working in Experience issues.

Discussion in 'Plugin Development' started by xKYLERxx, Dec 27, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    xKYLERxx

    I am making something that involves increasing and decreasing XP in increments of 64. Increasing is fine. I use giveExp(64); but when I try to do giveExp(-64);, it does decrease the Exp internally, but the player isn't notified. Is there any method or anything I could do to tell the client about it'snew Exp balance?
     
  2. Offline

    tkausl

    Try to set yourself:

    Code:
    Player p; //Any Player
    p.setExperience(p.getExperience() - 64);
     
  3. Offline

    xKYLERxx

    I figured it out. But it only works for what I need. I used setLevel(); and getLevel();.
     
  4. Offline

    desht

    What did you do, out of interest? I'm also trying to add/remove experience, and I find that if I use player.giveExp() to take away enough experience for the player's level to go down, player.getExp() starts to return a negative value, and that's when the client's XP bar stops updating properly, even though player.getTotalExperience() still returns the right values. And even though player.getExp() is returning a negative value, player.getLevel() hasn't changed.

    This is pretty bizarre behaviour, seems buggy to me. There doesn't seem to be a proper connection between the player's experience and their level.

    Okay, so this method seems to work, updating the client's XP bar as I'd like to see, and used the tables & formulae in http://www.minecraftwiki.net/wiki/Experience :

    Code:java
    1.  
    2. private static void awardExperience(Player player, int xp) {
    3. player.giveExp(xp);
    4.  
    5. int newXp = player.getTotalExperience();
    6. int newLevel = (int) (Math.sqrt(newXp / 3.5 + 0.25) - 0.5);
    7. player.setLevel(newLevel);
    8. int xpForThisLevel = xpNeeded(newLevel);
    9. float neededForThisLevel = xpNeeded(newLevel + 1) - xpForThisLevel;
    10. float distanceThru = player.getTotalExperience() - xpForThisLevel;
    11. player.setExp(distanceThru / neededForThisLevel);
    12. }
    13.  
    14. private static int xpNeeded(int level) {
    15. if (level <= 0) {
    16. return 0;
    17. } else {
    18. return (int) (3.5 * level * (level + 1));
    19. }
    20. }
    21.  
    22.  

    (sorry if the indentation is funny here... XenForo's cut & paste functionality is to be despised)

    I had hoped to only do the code from the player.setLevel() call onwards if the player's level actually changed, but that caused some odd effects - seeming the client's (I'm testing with Spoutcraft) idea of levels doesn't quite match what the Wiki describes.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 22, 2016
  5. Offline

    xKYLERxx

    I was making an ExperienceBank. It let's players store experience. No permissions system though.
     
  6. Offline

    Don Redhorse

  7. Offline

    desht

    OK, so my calculations are based on bad (outdated) data from the Wiki. Back to the drawing board on that one, then.

    I'm pretty much lost on what I would need to do to give or take XP correctly. player.giveExp() seems to work for positive quantities (although there are issues with giving large amounts, presumably related to how @Dinnerbone described it working in the bug report - it's the most counter-intuitive XP system I've ever seen, no exceptions).

    But for negative quantities, giveExp() goes weird as soon as you take away enough XP to level the player down. The client XP bar stops updating, player.getLevel() doesn't change, and player.getExp() (representing how far through the level the player is) goes negative. I don't know if that's bugged or intended behaviour.

    At the end of the day, my needs are pretty simple. I'd like to give or take an arbitrary quantity of XP to/from a player, and have the client's XP bar update correctly. Is that actually possible?

    I noticed you state in the bug report that you use player.setExp() to set the player's XP. But that takes a float argument, and according to the Javadocs, all setExp() does is set the distance through the current level that the player is (so needs to be between 0.0 and 1.0). I don't understand how that's working for you when you're passing it an integer representing the player's total XP...?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 22, 2016
  8. Offline

    Don Redhorse

    would need to look up the old code again.. this is the code which works..
    Code:
    Player player = event.getPlayer();
            int storedDroppedExperience = tStoneBlockDTP.getDroppedExperience();
            int playerTotalExperience = player.getTotalExperience();
            log.debug("Player TotalExperience", playerTotalExperience);
            log.debug("Stored droppedExperience", storedDroppedExperience);
            for (int i = 1; i < storedDroppedExperience; ++i) {
                player.giveExp(1);
                log.debug("Player New TotalExperience", player.getTotalExperience());
            }
    I tried both:


    //player.setTotalExperience(storedDroppedExperience + playerTotalExperience);
    player.setExp(storedDroppedExperience + playerTotalExperience);

    but they will give weird results.. and yeah I figured the issue with the float out later..
     
  9. Offline

    ibhh

    Look up xpshop it solved the problem and do all on his own.
     
Thread Status:
Not open for further replies.

Share This Page