Skip to content

Community Scripts

Funnycube edited this page Apr 22, 2023 · 28 revisions

JavaScript Expansion Scripts

The JavaScript Expansion for PlaceholderAPI allows for expansions that wouldn't really need an entire expansion otherwise. For example, a random number or letter generator, or an expansion that sends out a random motivational message. On this page, you can find some scripts made by the community.

How to Use

  1. Download the JavaScript expansion from the eCloud page if you haven't already.
  2. Copy the expansion to the /plugins/PlaceholderAPI/expansions/ folder.
  3. Reload PlaceholderAPI with /papi reload
  4. Add the downloaded script file to /plugins/PlaceholderAPI/javascripts/ folder.
  5. Copy the config file code to /plugins/PlaceholderAPI/javascript_placeholders.yml

How to Contribute

  1. Make a javascript placeholder!
  2. Open an issue, explaining what it does, how it works and also posting the code in there. (You could also just update the existing ones if you think there's a better way to do what they do)
  3. Wait.

Community Scripts


All Scripts


Random Integer Between

  • Author: NathanG
  • Description: Generates a random integer between two given integers.
  • Usage: %javascript_randomintbetween_<min>,<max>%
  • Example: %javascript_randomintbetween_10,20% - Produces a random integer between 10 and 20.

Javascript Code

random_integer_between.js
var min = 1;
var max = 25;

function randomInteger() {
   if (args.length == 2) {
       min = args[0];
       max = args[1];
   }

   var random = Math.random() * (max - min);
       random += min;

   return Math.floor(random);
}

randomInteger();

Add to javascript_placeholders.yml

randomintbetween:
  file: random_integer_between.js

Data

  • Author: clip
  • Description: placeholder that allows you to get and set custom data via the placeholder arguments specified when the placeholder is called.

Usage:

  • %javascript_data_get,<path>% - Attempts to get a string value from the path specified, empty string if no value found.
  • %javascript_data_getint,<path>% - Attempts to get an integer from the path specified, 0 if no value found.
  • %javascript_data_set,<path>,<value>% - Sets the value for the path specified.
  • %javascript_data_add,<path>,<amount>% - Attempts to add to the value at the path specified
  • %javascript_data_subtract,<path>,<amount>% - Attempts to subtract from the value at the path specified

You will need to insert the set, add, or subtract placeholder in the plugin function where you want to track the data. A quick example of functionality for this placeholder would be a "1 time use" item in a GUI plugin that supports PlaceholderAPI.

Example of usage with DeluxeMenus ```yaml menu_title: 'One time use menu' open_command: onetimeuse size: 9 items: 'denied_item': slot: 0 priority: 2 material: BARRIER display_name: '&cYou already clicked the item once :(' 'allowed_item': slot: 0 priority: 1 view_requirement: requirements: check_if_can_use: type: string equals input: '%javascript_data_get,{player_uuid}.has_used%' # the get argument will return an empty string if the value has never been set so we can just check for that output: '' material: DIAMOND # we need to make sure we set the data value that way next time it is checked, it will tell us if the give command has been ran # Since the placeholder to set data returns nothing, we can add it anywhere to set the data. We will just drop it in the command left_click_commands: - '[console] give %player_name% diamond 1 %javascript_data_set,{player_uuid}.has_used,true%' - '[close]' ```

Javascript Code

data.js
function set(path, data) {
    Data.set(path, data);
    return "";
}
function add(path, amount) {
    if (isNaN(amount)) {
        return "";
    }
    var amt = Data.exists(path) ? Data.get(path) : 0;
    if (isNaN(amt)) {
        amt = 0;
    }
    amt = parseInt(amt) + parseInt(amount);
    Data.set(path, amt.toFixed());
    return "";
}
function subtract(path, amount) {
    if (isNaN(amount)) {
        return "";
    }
    var amt = Data.exists(path) ? parseInt(Data.get(path)) : 0;
    if (isNaN(amt)) {
        amt = 0;
    }
    amt = parseInt(amt) - parseInt(amount);
    Data.set(path, amt.toFixed());
    return "";
}
function get(path)  {
    return Data.exists(path) ? Data.get(path) : "";
}
function getInt(path) {
    if (Data.exists(path)) {
        var amt = Data.get(path);
        if (isNaN(amt)) {
            return 0;
        } else {
            return parseInt(amt).toFixed();
        }
    }
    return 0;
}
function getUsage(firstArg) {
    switch(firstArg) {
    case "get":
        return "get,<path>";
    case "getint":
        return "getint,<path>";
    case "add":
        return "add,<path>,<amount>";
    case "subtract":
        return "subtract,<path>,<amount>";
    case "set":
        return "set,<path>,<value>";
    default:
        return "first argument must be get, getint, set, add, subtract";
    }
}
function runPlaceholder() {
    if (args.length == 0) {
        return getUsage("no args");
    }
    else if (args.length == 1) {
        return getUsage(args[0]);
    }
 
    if (args.length == 2) {
        if (args[0].equals("get")) {
            return get(args[1]);
        }
        else if (args[0].equals("getint")) {
            return getInt(args[1]);
        }
    }
    else if (args.length == 3) {
        if (args[0].equals("set")) {
            return set(args[1], args[2]);
        }
        else if (args[0].equals("add")) {
            return add(args[1], args[2]);
        }
        else if (args[0].equals("subtract")) {
            return subtract(args[1], args[2]);
        }
    }
    return getUsage(args[0]);
}
runPlaceholder();

Add to javascript_placeholders.yml

data:
    file: 'data.js'

Has Permission

  • Author: aBooDyy
  • Description: Check if a player has permission.test permission and send a custom message. It's very useful and you can use this method with a lot of things, it's a true/false result.
  • Usage: %javascript_has_permission%

NOTE: this method works if you haven't changed the true boolean option in PlaceholderAPI config ('true': 'yes') if you changed it and don't want to use the default one change "yes" in (haspermission === "yes") to the option you set for true in the PlaceholderAPI config.

Javascript Code

haspermission.js
// create a variable and name it wantever you want like this
// and use the placeholder you want, i'm using this one
var haspermission = "%player_has_permission_permission.test%";

// create a function with the name you want
function permission() {

// if the haspermission variable that we created before return yes (true boolean)
// the js placeholder will return what we set in the return down
   if (haspermission === "yes") {
       return "&aYou have the Test permission!";
   }

// if the haspermission varibale wasnt true it will return what we set down
   else {
       return "&cYou don't have the Test permission!";
   }
}
// by this we are calling the function to run
permission();

Add to javascript_placeholders.yml

haspermission:
  file: has_permission.js

Animated Text

  • Authors: aBooDyy && NathanG
  • Description: Change the return value every 1 seconds the placeholder called. It has 3 different values (you can add more). This placeholder is useful for plugins which don't have animated text feature (e.g. DeluxeMenus Lore).
  • Usage: %javascript_animated_text_<ID>,<Text1>,<Text2>,<Text3>%
  • Example: %javascript_animated_text_1,&aA,&bB,&6C%

IMPORTANT: If you have 2 placeholders or more have the same the placeholders won't work as they should. so make sure you change the (set it form 0-100+).

NOTE: If you need help in adding/removing values OR got some issues with it, feel free to ask me or anyone else in the HelpChat Discord.

Javascript Code

animated_text.js
var messages = ["This is", "This is a", "This is a test message"];
var numdata = "%player_name%." + IDv + "." + messages;
var IDv = 0;

function getMessage(ID) {
    if ( args.length == 4) {
        IDv = args[0];
        messages = [args[1], args[2], args[3]];
    }

    var msgnumber = Data.exists(numdata) ? Data.get(numdata) : 0;
    msgnumber++;

    if (msgnumber >= messages.length) {
        msgnumber = 0;
    }

    Data.set(numdata, msgnumber);

    return messages[msgnumber];
}
getMessage(IDv);

Add to javascript_placeholders.yml

animated_text:
  file: animated_text.js

Rounded Player Health

  • Author: xDizasterCYx
  • Description: Changes the ugly health placeholder to a rounded integer.
  • Usage: %javascript_health%

Save as health.js

function hp() {
    return Math.round(parseInt('%player_health%') * 100) / 100;
}
hp();

Add to javascript_placeholders.yml

health:
   file: health.js

Rounded Max Player Health

  • Author: xDizasterCYx
  • Description: Changes the ugly max health placeholder to a rounded integer.
  • Usage: %javascript_maxhealth%

Save as maxhealth.js

function hp() {
    return Math.round(parseInt('%player_max_health%') * 100) / 100;
}
hp();

Add to javascript_placeholders.yml

maxhealth:
   file: maxhealth.js

Held Item Display Name

  • Author: aBooDyy
  • Description: Return the display name of the item you're holding in your hand.
  • Usage: %javascript_displayname%

Javascript Code

displayname.js
var player = BukkitPlayer;
var material = '%player_item_in_hand%';

function displayname() {
    if ( material !== 'AIR' ) {
        var has = player.getInventory().getItemInHand().getItemMeta().hasDisplayName();
        var name = player.getInventory().getItemInHand().getItemMeta().getDisplayName();
    }

    if ( material === 'AIR' ) {
    // return 'AIR' when you aren't holding an item (You can change it to whatever you want)
        return 'AIR';
    } else if ( has ) {
        return name;
    } else {
    // returns the material name (%player_item_in_hand%) when it an item doesn't has a display name
    // You can change it to whatever you want by replacing material with 'WHAT YOU WANT'
        return material;
    }
}
displayname();

Add to javascript_placeholders.yml

displayname:
  file: displayname.js

Lore Lines

  • Author: aBooDyy
  • Description: Returns how many lore line of the item you're holding.
  • Usage: %javascript_lorelines%

Save as lorelines.js

var player = BukkitPlayer;
var material = '%player_item_in_hand%';


function lorelines() {
    if ( material !== 'AIR' ) {
        var lore = player.getInventory().getItemInHand().getItemMeta().getLore();
        var has = player.getInventory().getItemInHand().getItemMeta().hasLore();
    }

    if ( material === 'AIR' ) {
    // return 'AIR' when you aren't holding an item (You can change it to whatever you want)
        return 'AIR';
    } else if ( has ) {
        return lore.length;
    } else {
    // return '0' when the item you're holding doesn't has lore (You can change it to whatever you want)
        return '0';
    }
}
lorelines();

Add to javascript_placeholders.yml

lorelines:
  file: lorelines.js

Held Item Lore

  • Author: aBooDyy
  • Description: Returns the lore of the item you're holding. Can return all lines, or specific lines.
  • Usage: %javascript_lore% OR %javascript_lore_<LineNumber>%
  • Example: %javascript_lore% to return all lore lines, %javascript_lore_1% to return lore line number 1

Javascript Code

lore.js
var player = BukkitPlayer;
var material = '%player_item_in_hand%';

var line = ' ';


function itemlore() {
   if ( material !== 'AIR' ) {
       var has = player.getInventory().getItemInHand().getItemMeta().hasLore();
       var linelore = player.getInventory().getItemInHand().getItemMeta().getLore();
   }

   if ( material !== 'AIR' && has === true ) {
       var lore = player.getInventory().getItemInHand().getItemMeta().getLore().toString();
   }

   if ( material !== 'AIR' && has === true && lore.indexOf(', ,') !== -1 ) {
       lore = lore.replace(/, ,/g, ',  ,');
   }

   if ( args.length == 1 ) {
       line = args[0];
   }

   if ( material === 'AIR' ) {
   // return 'AIR' when you aren't holding an item (You can change it to whatever you want)
       return 'AIR';
   } else if ( has && line === ' ' ) {
       return lore.replace(/^\[/, "").replace(/.$/,"").replace(/, /g, '\n');
   } else if ( has && line !== ' ' ) {
       if (linelore.length >= line) {
         line = parseInt(line) - 1;
         return linelore[line];
       }
       // return ' ' (Nothing/blank line) when the item you're holding doesn't has the requested line (You can change it to whatever you want)
       return ' ';
   } else {
   // return ' ' (Nothing/blank line) when the item you're holding doesn't has lore (You can change it to whatever you want)
       return ' ';
   }

}
itemlore();

Add to javascript_placeholders.yml

lore:
  file: lore.js

Check/Remove Item

  • Author: aBooDyy
  • Description: Check if player has an item you set in the placeholder (Material, Data, Amount, Name, Lore), It supports color codes for Name and Lore also it supports more than one lore line. It returns 'yes' if the player has the item, and 'no' if he doesn't. And remove item from player inventory if he has the item when the placeholder is parsed. You can run papi parse command to parse it (/papi parse %player_name% %javascript_item_check_{player_name}_mat: 1%) or send the placeholder to the player.
  • Usage: %javascript_item_check/remove_[PLAYER]_mat: [MATERIAL/ID]_data: [DATA]_amt: [AMOUNT]_name: [DISPLAYNAME]_lore: [LORE]%

Examples:

  • %javascript_item_check_aBooDyy_mat: STONE_data: 0_amt: 1_name: &aName_lore: &7Lore%
  • %javascript_item_check_{player_name}_mat: 1_data: 1_amt: 2_name: &aName_lore: &7Lore1|&7Lore2%
  • %javascript_item_check_aBooDyy_mat: STONE_data: 0_amt: 1_name: &aName%
  • %javascript_item_check_{player_name}_mat: STONE_data: 1_amt: 2%
  • %javascript_item_check_aBooDyy_mat: STONE_data: 0%
  • %javascript_item_check_{player_name}_mat: 1%
  • %javascript_item_remove_aBooDyy_mat: STONE_data: 0_amt: 1_name: &aName_lore: &7Lore%
  • %javascript_item_remove_{player_name}_mat: 1_data: 1_amt: 2_name: &aName_lore: &7Lore1|&7Lore2%
  • %javascript_item_remove_aBooDyy_mat: STONE_data: 0_amt: 1_name: &aName%
  • %javascript_item_remove_{player_name}_mat: STONE_data: 1_amt: 2%
  • %javascript_item_remove_aBooDyy_mat: STONE_data: 0%
  • %javascript_item_remove_{player_name}_mat: 1%

Note: If you didn't set the data and the amount it will be by default data = 0 and amount = 1. You can add as much lore lines as you want just add | between each line as seen in the example above.

Javascript Code

item.js
var vbukkit = org.bukkit.Bukkit;

if (args.length === 1) {
    var arg = args[0].split("_");
}
var playerArg = arg[1];
var player = vbukkit.getPlayer(playerArg);

if (player !== null) {
    var invItems = player.getInventory().getContents();
}

var mat;
var data = '0';
var amt = 1;
var name;
var lore;

var hasitemv = 'no';
var matchlores = 0;
var slot;

function checkItem() {

    if ( arg.length === 3 ) {
        mat = arg[2].replace("mat: ", "");
    } else if ( arg.length === 4 ) {
        mat = arg[2].replace("mat: ", "");
        data = arg[3].replace("data: ", "");
    } else if ( arg.length === 5 ) {
        mat = arg[2].replace("mat: ", "");
        data = arg[3].replace("data: ", "");
        amt = arg[4].replace("amt: ", "");
    } else if ( arg.length === 6 ) {
        mat = arg[2].replace("mat: ", "");
        data = arg[3].replace("data: ", "");
        amt = arg[4].replace("amt: ", "");
        name = arg[5].replace("name: ", "");
    } else if ( arg.length === 7 ) {
        mat = arg[2].replace("mat: ", "");
        data = arg[3].replace("data: ", "");
        amt = arg[4].replace("amt: ", "");
        name = arg[5].replace("name: ", "");
        lore = arg[6].replace("lore: ", "").split("|");
    }

    for ( s = 0; s < invItems.length; s++ ) {
        if ( invItems[s] !== null ) {
            if ( lore !== undefined && invItems[s].getItemMeta().hasLore() === false ) {
                    hasitemv = 'no';
            } else if ( lore !== undefined ) {
                if ( invItems[s].getType().toString() === mat || invItems[s].getTypeId() === parseInt(mat) ) {
                    if ( invItems[s].getData().toString().match(/\d+/)[0] === data ) {
                        if ( invItems[s].getAmount() >= parseInt(amt) ) {
                            if ( invItems[s].getItemMeta().getDisplayName() === name ) {
                                for ( l = 0; l < lore.length; l++ ) {
                                    if ( invItems[s].getItemMeta().getLore()[l] === lore[l] ) {
                                        matchlores++;
                                    }
                                }
                                }
                            }
                        }
                    }
                    if ( matchlores === lore.length ) {
                        hasitemv = 'yes';
                        slot = s;
                    }
                } else if ( name !== undefined ) {
                    if ( invItems[s].getType().toString() === mat || invItems[s].getTypeId() === parseInt(mat) ) {
                        if ( invItems[s].getData().toString().match(/\d+/)[0] === data ) {
                            if ( invItems[s].getAmount() >= parseInt(amt) ) {
                                if ( invItems[s].getItemMeta().getDisplayName() === name ) {
                                    hasitemv = 'yes';
                                    slot = s;
                                }
                            }
                        }
                    }
                } else {
                    if ( invItems[s].getType().toString() === mat || invItems[s].getTypeId() === parseInt(mat) ) {
                        if ( invItems[s].getData().toString().match(/\d+/)[0] === data ) {
                            if ( invItems[s].getAmount() >= parseInt(amt) ) {
                                hasitemv = 'yes';
                                slot = s;
                            }
                        }
                    }
                }
            }
        }
        return hasitemv;
}

function removeItem() {
    if ( checkItem() === 'yes' ) {
        if ( invItems[slot].getAmount() >= parseInt(amt) ) {
            var newAMT = invItems[slot].getAmount() - parseInt(amt);
            invItems[slot].setAmount(newAMT);
            return '&aItem removed successfully';
        }
    } else {
        return "&7" + playerArg + " &cdoesn't have the item.";
    }
}

function run() {

    if (args.length === 0 || args.length > 1 || arg.length === 1 || arg.length === 2 || arg[0].toUpperCase() !== 'CHECK' && arg[0].toUpperCase() !== 'REMOVE') {
        return "&cInvalid syntax. &7javascript_item_check/remove_[PLAYER]_mat: [MATERIAL/ID]_data: [DATA]_amt: [AMOUNT]_name: [DISPLAYNAME]_lore: [LORE]";
    } else if (arg[0].toUpperCase() === 'CHECK' && player !== null) {
        return checkItem();
    } else if (arg[0].toUpperCase() === 'REMOVE' && player !== null) {
        return removeItem();
    } else if (player === null) {
        return '&7' + playerArg + ' &cIs not online.'
    }
}

run();

Add to javascript_placeholders.yml

item:
  file: item.js

Difference Between 2 Dates

  • Author: aBooDyy
  • Description: Give you the difference between 2 dates you set or how many until that date or how many time passed from that date
  • Usage: %javascript_difference_dates%

Save as difference_dates.js

function time() {
    // year, month, day, hour, minute, second
    // months start at 0 and end at 11
    // January is 0. December is 11
    var startDate = new Date(2018, 0, 1);
    var endDate = new Date();
    var difference = endDate - startDate;

    var months = Math.floor(difference / (1000 * 60 * 60 * 24 * 31));
    var days = Math.floor(difference % (1000 * 60 * 60 * 24 * 31) / (1000 * 60 * 60 * 24));
    var hours   = Math.floor(difference % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
    var minutes = Math.floor(difference % (1000 * 60 * 60) / (1000 * 60));
    var seconds = Math.floor(difference % (1000 * 60) / (1000));

    // XXmo XXd XXh XXm XXs (changeable)
    return months + "mo "+ days + "d " + hours + "h " + minutes + "m " + seconds + "s";
}

time();

Add to javascript_placeholders.yml

difference_dates:
  file: difference_dates.js

Cooldown

  • Author: aBooDyy
  • Description: cooldown placeholder made for DeluxeMenus (not only for DeluxeMenus) to set a duration between clicking an item.

Usage: %javascript_cooldown_[ID]_[COOLDOWN/Start]%

  • [ID] - Can use letters/numbers. Should be unique. Can be used for multiple cooldowns at once.
  • [COOLDOWN] - Cooldown in seconds.
  • [Start] - To set the start date.
  • [Reset] - To reset the start date.

Examples:

  • %javascript_cooldown_1_20%
  • %javascript_cooldown_premium1_100%
  • %javascript_cooldown_name_start%
  • %javascript_cooldown_name_reset%
Example of using with DeluxeMenus
menu_title: '&aExample GUI menu'
open_command: cooldown
update_interval: 1
size: 18
items:
  '1':
    material: 251
    data: 5
    slot: 0
    priority: 1
    view_requirement:
      requirements:
        name:
          type: string equals
          input: "%javascript_cooldown_1_60%"
          output: "0s"
    display_name: '&aUnlocked'
    left_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_1_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_1_start'
    - '[message] Do whatever u want'
    - '[refresh]'
  '2':
    material: 251
    data: 14
    priority: 2
    update: true
    slot: 0
    lore:
    - '&7Wait for: &8%javascript_cooldown_1_60%'
    display_name: '&cLocked'
    left_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
  '3':
    material: 251
    data: 5
    slot: 1
    priority: 1
    view_requirement:
      requirements:
        name:
          type: string equals
          input: "%javascript_cooldown_2_3600%"
          output: "0s"
    display_name: '&aUnlocked'
    left_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_2_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_2_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
  '4':
    material: 251
    data: 14
    priority: 2
    update: true
    slot: 1
    lore:
    - '&7Wait for: &8%javascript_cooldown_2_3600%'
    display_name: '&cLocked'
    left_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
  '5':
    material: 251
    data: 5
    slot: 2
    priority: 1
    view_requirement:
      requirements:
        name:
          type: string equals
          input: "%javascript_cooldown_3_36000%"
          output: "0s"
    display_name: '&aUnlocked'
    left_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_3_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_3_start'
    - '[message] Do whatever u want'
    - '[refresh]'
  '6':
    material: 251
    data: 14
    priority: 2
    update: true
    slot: 2
    lore:
    - '&7Wait for: &8%javascript_cooldown_3_36000%'
    display_name: '&cLocked'
    left_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
  '7':
    material: 251
    data: 5
    slot: 9
    priority: 1
    view_requirement:
      requirements:
        name:
          type: string equals
          input: "%javascript_cooldown_4_2160000%"
          output: "0s"
    display_name: '&aUnlocked'
    left_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_4_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_4_start'
    - '[message] Do whatever u want'
    - '[refresh]'
  '8':
    material: 251
    data: 14
    priority: 2
    update: true
    slot: 9
    lore:
    - '&7Wait for: &8%javascript_cooldown_4_2160000%'
    display_name: '&cLocked'
    left_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
  '9':
    material: 251
    data: 5
    slot: 10
    priority: 1
    view_requirement:
      requirements:
        name:
          type: string equals
          input: "%javascript_cooldown_5_13140000%"
          output: "0s"
    display_name: '&aUnlocked'
    left_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_5_start%'
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[console] papi parse %player_name% %javascript_cooldown_5_start'
    - '[message] Do whatever u want'
    - '[refresh]'
  '10':
    material: 251
    data: 14
    priority: 2
    update: true
    slot: 10
    lore:
    - '&7Wait for: &8%javascript_cooldown_5_13140000%'
    display_name: '&cLocked'
    left_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'
    right_click_commands:
    - '[message] Do whatever u want'
    - '[refresh]'

Javascript Code

cooldown.js
var monthSymbol = "mo";
var daySymbol = "d";
var hourSymbol = "h";
var minuteSymbol = "m";
var secondSymbol = "s";

var arg = args[0].split("_");
if (arg.length === 2) {
    var ID = arg[0];
    var cooldown = arg[1];
}

var dataLoc = "%player_name%." + ID + ".date";
var currentDate = new Date();

function Cooldown() {
    if (!Data.exists(dataLoc)) {
        return "0s";
    } else {
        var startDate = new Date(Data.get(dataLoc));
        var difference = currentDate - startDate;
        var result = Math.floor(difference / 1000);
        if (result >= cooldown) {
            return "0s";
        } else {
            startDate = new Date(startDate.getTime() + (cooldown * 1000));
            var result = startDate - currentDate;

            var months = Math.floor(result / (1000 * 60 * 60 * 24 * 31));
            var days = Math.floor(result % (1000 * 60 * 60 * 24 * 31) / (1000 * 60 * 60 * 24));
                var hours   = Math.floor(result % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
              var minutes = Math.floor(result % (1000 * 60 * 60) / (1000 * 60));
            var seconds = Math.floor(result % (1000 * 60) / (1000));

            if (months === 0 && days === 0 && hours === 0 && minutes === 0) {
                return seconds + secondSymbol;
            } else if (months === 0 && days === 0 && hours === 0) {
                return minutes + minuteSymbol + seconds + secondSymbol;
            } else if (months === 0 && days === 0) {
                return hours + hourSymbol + minutes + minuteSymbol + seconds + secondSymbol;
            } else if (months === 0) {
                return days + daySymbol + hours + hourSymbol + minutes + minuteSymbol + seconds + secondSymbol;
            } else {
                return months + monthSymbol + days + daySymbol + hours + hourSymbol + minutes + minuteSymbol + seconds + secondSymbol;
            }
        }
    }
}

function start() {
    var data = currentDate.toString();

    Data.set(dataLoc, data);
    Placeholder.saveData();
}

function resetCooldown() {
    if(Data.exists(dataLoc)){
        Data.remove(dataLoc);
    }
    Placeholder.saveData();
}

function run() {
    if (args.length !== 1 || arg.length !== 2) {
        return "&cInvalid syntax, Please use this syntax:\n&7%" + "javascript_cooldown_[ID]_[Cooldown/Start]" + "%";
    } else if (cooldown.toUpperCase() === "START") {
        return start();
    } else if (cooldown.toUpperCase() === "RESET") {
        return resetCooldown();
    } else if (isNaN(cooldown)) {
        return "&cPlease set a valid cooldown.";
    } else if (!isNaN(cooldown)) {
        return Cooldown();
    } else {
        return "&cInvalid syntax, Please use this syntax:\n&7%" + "javascript_cooldown_[ID]_[Cooldown/Start]" + "%";
    }
}
run();

Add to javascript_placeholders.yml

cooldown:
  file: cooldown.js

TokenEnchant Token Value

  • Author: vk2gpz
  • Description: Give you the token value of the player without comma(s) so that you can use it in DeluxeMenus.
  • Usage: %javascript_tokenenchant_token%

Save as TokenEnchant_token.js

function tokenenchant_token() {
    return "%tokenenchant_token_num%".replace(/,/g, '');
}
tokenenchant_token();

Add to javascript_placeholders.yml

tokenenchant_token:
  file: TokenEnchant_token.js

Health Bar

  • Author: aBooDyy
  • Description: A javascript placeholder to return the player's health bar (with hearts).
  • Usage: %javascript_healthbar%

You can use the first 3 lines in the javascript code to change the colors and heart symbol.

Save as healthbar.js

var full = "&4\u2764";
var half = "&c\u2764";
var empty = "&7\u2764";

function healthBar() {
  var bar = "";
  var health = parseInt("%player_health_rounded%");
  var fullHearts = Math.floor(health / 2);
  for (i = 0; i < fullHearts; i++) {
    bar += full;
  }
  if (health % 2 !== 0) {
    bar += half;
  }
  var emptyHearts = Math.floor((20 - health) / 2);
  for (i = 0; i < emptyHearts; i++) {
    bar += empty;
  }
  return bar;
}
healthBar();

Add to javascript_placeholders.yml

healthbar:
  file: healthbar.js

Player Exp Points

  • Author: BlitzGamer_88
  • Description: A javascript placeholder to return the player's exp points.
  • Usage: %javascript_exp_points%

Save as exp_points.js

var player = BukkitPlayer
var expPrc = player.getExp()
var levels = player.getLevel()

function expPoints() {

  var exp = Math.round(getExpAtLevel(levels) * expPrc)
  var currentLevel = player.getLevel()
  while (currentLevel > 0) {
    currentLevel--
    exp += getExpAtLevel(currentLevel)
  }
  if (exp < 0) exp = Integer.MAX_VALUE
  return parseInt(exp)

}



function getExpAtLevel(level) {

  if (level <= 15) return (2*level) + 7
  if ((level >= 16) && (level <=30)) return (5 * level) -38
  return (9*level)-158

}

expPoints()

Add to javascript_placeholders.yml

exp_points:
  file: exp_points.js

Number of Players in Group of Worlds

  • Author: meowsome
  • Description: Get the number of players for multiple different worlds and add them together. This is useful for holograms and menus that display the number of players for each section of a server.
  • Usage: %javascript_number_in_group_of_worlds_<world1>,<world2>,<etc>%
  • Example: %javascript_number_in_group_of_worlds_Survival,Survival_nether,Survival_the_end% will return the number of players in the overworld, nether, and end for Survival, and add them together.

Save as number_in_group_of_worlds.js

function numInGroupOfWorlds() {
    var num = 0;

    for (var i = 0; i < args.length; i++) {
        var world = BukkitServer.getWorld(args[i]);

        if (world == null) {
            continue;
        }

        num += world.getPlayers().length;
    }

    return num.toFixed(0);
}

numInGroupOfWorlds();

Add to javascript_placeholders.yml

number_in_group_of_worlds:
  file: number_in_group_of_worlds.js

Number Suffix

  • Author: cj89898
  • Description: Formats numbers to a shortened version with a suffix. Suffixes and Decimals can both be customized.
  • Usage: %javascript_numberSuffix_<raw number>% - Can use placeholders surrounded by {}
  • Example: %javascript_numberSuffix_{vault_eco_balance}% could return 1.89S

Save as numberSuffix.js

var num = Number(args[0]);

function formatNum(num){
    var suffixes = ['', 'k', 'm', 'b', 't', 'qd', 'qn', 's']; //More Suffixes: 'sp', 'o', 'n', 'd', 'ud', 'dd', 'td'
    var decimals = 2;
    for(i=0;i<suffixes.length;i++){
        if(num>=1000){
            num = (num/1000);
        } else {
            return num.toFixed(decimals)+suffixes[i];
        }
    }
    return (num*1000).toFixed(decimals)+suffixes[suffixes.length-1];
}

formatNum(num);

Add to javascript_placeholders.yml

numberSuffix:
  file: numberSuffix.js