Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LOL LMAO ROFL XD XD XP XP XP #145

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
- [server.playNoteBlock(world, position, pitch)](#serverplaynoteblockworld-position-pitch)
- [server.getNote(note)](#servergetnotenote)
- [server.emitParticle(particle, world, position, opt)](#serveremitparticleparticle-world-position-opt)
- [serv.getXpLevel(xp)](#servgetxplevelxp)
- [serv.getXpRequired(level, toLevel=level+1)](#servgetxprequiredlevel-tolevellevel1)
- [serv.getBaseXpFromLevel(level)](#servgetbasexpfromlevellevel)
- [serv.distanceToXpLevel(xp, toLevel=startLevel+1, startLevel=xp level)](#servdistancetoxplevelxp-tolevelstartlevel1-startlevelxp-level)
- [Low level methods](#low-level-methods)
- [server._writeAll(packetName, packetFields)](#server_writeallpacketname-packetfields)
- [server._writeArray(packetName, packetFields, playerArray)](#server_writearraypacketname-packetfields-playerarray)
Expand Down Expand Up @@ -92,6 +96,9 @@
- [Properties](#properties-2)
- [player.username](#playerusername)
- [player.view](#playerview)
- [player.xp](#playerxp)
- [player.displayXp](#playerdisplayxp)
- [player.xpLevel](#playerxplevel)
- [Events](#events-2)
- ["connected"](#connected)
- ["spawned"](#spawned)
Expand Down Expand Up @@ -132,6 +139,10 @@
- [player.spawnAPlayer(spawnedPlayer)](#playerspawnaplayerspawnedplayer)
- [player.updateAndSpawnNearbyPlayers()](#playerupdateandspawnnearbyplayers)
- [player.playSound(sound, opt)](#playerplaysoundsound-opt)
- [player.setXp(xp, opt)](#playersetxpxp-opt)
- [player.sendXp()](#playersendxp)
- [player.setXpLevel(level)](#playersetxplevellevel)
- [player.setDisplayXp(num)](#playersetdisplayxpnum)
- [Low level properties](#low-level-properties)
- [player._client](#player_client)
- [Low level methods](#low-level-methods-1)
Expand Down Expand Up @@ -353,6 +364,28 @@ Opt:
- size: vec3 of the size. (0,0,0) will be at an exact position, (10,10,10) will be very spread out (particles less dense)
- count: Number of particles. 100,000,000+ will crash the client. Try not to go over 100,000 (sincerely, minecraft clients)

#### serv.getXpLevel(xp)

Get level given XP amount

#### serv.getXpRequired(level, toLevel=level+1)

Get's the amount of xp required to get from level to toLevel (or level to level+1)

#### serv.getBaseXpFromLevel(level)

Gets the minimum amount of xp required to be at that level (or "base xp" for that level)

#### serv.distanceToXpLevel(xp, toLevel=startLevel+1, startLevel=xp level)

Gets a number between 0 and 1 (used in player.displayXp as the green bar at the bottom) that is the progress of xp between startLevel and toLevel.

By default, startLevel will be the xp's lowest possible level: serv.getXpLevel(xp)

By default, toLevel is startLevel + 1.

This means when startLevel and toLevel are at their defaults, this function returns the progress to the next level of XP (from 0.0 to 1.0)

### Low level methods

#### server._writeAll(packetName, packetFields)
Expand Down Expand Up @@ -605,6 +638,18 @@ The username of the player

The view size of the player, for example 8 for 16x16

#### player.xp

Total experience the player has (int). Set this using player.setXp()

#### player.displayXp

Number from 0 to 1.0 representing the progress bar at the bottom of the player's screen. Set this with player.setDisplayXp()

#### player.xpLevel

Level of xp the player has. Set this with player.setXpLevel()

### Events

#### "connected"
Expand Down Expand Up @@ -876,6 +921,25 @@ Spawn and despawn the correct players depending on distance for `player`.

Easy way to only play a sound for one player. Same opt as serv.playSound except no `whitelist`.

#### player.setXp(xp, opt)

Sets the player's XP level. Options:
- setLevel: Calculate and set player.level (default: true)
- setDisplay: Calculate and set player.displayXp (default: true)
- send: Send xp packet (default: true)

#### player.sendXp()

Updates the player's xp based on player.xp, player.displayXp, and player.xpLevel

#### player.setXpLevel(level)

Sets and sends the player's new level

#### player.setDisplayXp(num)

Sets and sends the palyer's new display amount. num should be from 0 to 1.0

### Low level properties

#### player._client
Expand Down
106 changes: 106 additions & 0 deletions src/lib/plugins/experience.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
module.exports.player = function(player, serv) {
player.xp = 0;
player.displayXp = 0;
player.xpLevel = 0;

player.sendXp = () => {
player._client.write('experience', {
experienceBar: player.displayXp,
level: player.level,
totalExperience: player.xp
});
}

player.setXpLevel = (level) => {
player.xpLevel = level;
player.sendXp();
}

player.setDisplayXp = (num) => {
player.displayXp = Math.max(0, Math.min(1, player.displayXp));
player.sendXp();
}

player.setXp = (xp, { setLevel=true, setDisplay=true, send=true }={}) => {
player.xp = xp;
if (setLevel) player.level = serv.getXpLevel(xp);
if (setDisplay) player.displayXp = serv.distanceToXpLevel(xp);
if (send) player.sendXp();
}

player.commands.add({
base: 'xp',
info: 'Give yourself experience',
usage: '/xp <amount> [player] OR /xp <amount>L [player]',
op: true,
parse(str) {
return str.match(/(-?\d+)(L)? ?([a-zA-Z0-9_]+)?/) || false;
},
action(args) {
var isLevel = !!args[2];
var amt = parseInt(args[1]);
var user = args[3] ? serv.getPlayer(args[3]) : player;
if (!user) return args[3] + ' is not on this server!';

if (!isLevel) {
user.setXp(user.xp + amt);
player.chat('Gave ' + user.username + ' ' + amt + ' xp');
} else {
var currLevel = serv.getXpLevel(player.xp);
var baseCurrLevel = serv.getBaseXpFromLevel(currLevel);
var extraXp = player.xp - baseCurrLevel;
user.setXp(serv.getBaseXpFromLevel(currLevel + amt) + extraXp);
player.chat('Gave ' + user.username + ' ' + amt + ' levels');
}
}
});
}

module.exports.server = function(serv) {
serv.distanceToXpLevel = (xp, toLevel) => {
var level = serv.getXpLevel(xp);
if (!toLevel) toLevel = level+1;
var levelBaseXp = serv.getBaseXpFromLevel(level);
var requiredXp = serv.getXpRequired(level, toLevel);
return (xp - levelBaseXp) / requiredXp;
}

serv.getXpLevel = (xp) => {
// I have to use quadratic equation to reverse the equation from serv.getBaseXpFromLevel(). Ugh.
var a;
var b;
var c;
if (xp < 352) { // 352 == Experience at level 16
a = 1;
b = 6;
c = 0;
} else if (xp < 1507) { // 1507 == Experience at level 31
a = 2.5;
b = -40.5;
c = 360;
} else { // Level 32+
a = 4.5;
b = -162.5;
c = 2220;
}
c -= xp;
return Math.floor((-b + Math.sqrt(b*b - 4*a*c)) / (2 * a)); // Math class was useful I guess mmph
}

serv.getXpRequired = (level, toLevel) => {
if (!toLevel) toLevel = level + 1;
return serv.getBaseXpFromLevel(toLevel) - serv.getBaseXpFromLevel(level);
}

serv.getBaseXpFromLevel = (level) => {
// The equations in this function are stupid and directly from the MC Wiki
// http://minecraft.gamepedia.com/Experience#Leveling_up
if (level <= 16) {
return level*level + 6*level;
} else if (level <= 31) {
return 2.5*level*level - 40.5*level + 360;
} else { // 32+
return 4.5*level*level - 162.5*level + 2220;
}
}
}