diff --git a/docs/API-Reference.md b/docs/API-Reference.md index 87596b1..9bbba5a 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -156,21 +156,23 @@ loads the module circle.js in the same directory. The contents of foo.js: - var circle = require('./circle.js'); - console.log( 'The area of a circle of radius 4 is ' - + circle.area(4)); +```javascript +var circle = require('./circle.js'); +console.log( 'The area of a circle of radius 4 is ' + + circle.area(4)); +``` The contents of circle.js: - var PI = Math.PI; - - exports.area = function (r) { - return PI * r * r; - }; - - exports.circumference = function (r) { - return 2 * PI * r; - }; +```javascript +var PI = Math.PI; +exports.area = function (r) { + return PI * r * r; +}; +exports.circumference = function (r) { + return 2 * PI * r; +}; +``` The module circle.js has exported the functions area() and circumference(). To add functions and objects to the root of your @@ -210,9 +212,11 @@ module in the `plugins` directory exports becomes a global variable. For example, if you have a module greeting.js in the plugins directory.... - exports.greet = function(player) { - player.sendMessage('Hello ' + player.name); - }; +```javascript +exports.greet = function(player) { + player.sendMessage('Hello ' + player.name); +}; +``` ... then `greet` becomes a global function and can be used at the in-game (or server) command prompt like so... @@ -400,10 +404,12 @@ restored using the `scload()` function. #### Example - var myObject = { name: 'John Doe', - aliases: ['John Ray', 'John Mee'], - date_of_birth: '1982/01/31' }; - scsave(myObject, 'johndoe.json'); +```javascript +var myObject = { name: 'John Doe', + aliases: ['John Ray', 'John Mee'], + date_of_birth: '1982/01/31' }; +scsave(myObject, 'johndoe.json'); +``` ##### johndoe.json contents... @@ -490,13 +496,15 @@ If Node.js supports setTimeout() then it's probably good for ScriptCraft to supp #### Example - // - // start a storm in 5 seconds - // - setTimeout( function() { - var world = server.worlds.get(0); - world.setStorm(true); - }, 5000); +```javascript +// +// start a storm in 5 seconds +// +setTimeout( function() { + var world = server.worlds.get(0); + world.setStorm(true); +}, 5000); +``` ### clearTimeout() function @@ -566,23 +574,29 @@ For example imagine you have 3 files program.js, inc.js and math.js ... ### math.js - exports.add = function(a,b){ - return a + b; - } +```javascript +exports.add = function(a,b){ + return a + b; +} +``` ### inc.js - var math = require('./math'); - exports.increment = function(n){ - return math.add(n, 1); - } +```javascript +var math = require('./math'); +exports.increment = function(n){ + return math.add(n, 1); +} +``` ### program.js - var inc = require('./inc').increment; - var a = 7; - a = inc(a); - print(a); +```javascript +var inc = require('./inc').increment; +var a = 7; +a = inc(a); +print(a); +``` You can see from the above sample code that programs can use modules and modules themeselves can use other modules. Modules have full @@ -857,31 +871,38 @@ present in the CraftBukkit classpath. To use this module, you should craftbukkit-sc-mqtt.bat and edit it to include the following command... - java -classpath sc-mqtt.jar;craftbukit.jar org.bukkit.craftbukkit.Main - + ```sh + java -classpath sc-mqtt.jar;craftbukit.jar org.bukkit.craftbukkit.Main + ``` + If you're using Mac OS, create a new craftbukkit-sc-mqtt.command file and edit it (using TextWrangler or another text editor) ... - java -classpath sc-mqtt.jar:craftbukkit.jar org.bukit.craftbukkit.Main + ```sh + java -classpath sc-mqtt.jar:craftbukkit.jar org.bukit.craftbukkit.Main + ``` 4. Execute the craftbukkit-sc-mqtt batch file / command file to start Craftbukkit. You can now begin using this module to send and receive messages to/from a Net-enabled Arduino or any other device which uses the [MQTT protocol][mqtt] - var mqtt = require('sc-mqtt'); - // create a new client - var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); - // connect to the broker - client.connect( { keepAliveInterval: 15 } ); - // publish a message to the broker - client.publish( 'minecraft', 'loaded' ); - // subscribe to messages on 'arduino' topic - client.subscribe( 'arduino' ); - // do something when an incoming message arrives... - client.onMessageArrived( function( topic, message ) { - console.log( 'Message arrived: topic=' + topic + ', message=' + message ); - }); + ```javascript + var mqtt = require('sc-mqtt'); + // create a new client + var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); + // connect to the broker + client.connect( { keepAliveInterval: 15 } ); + // publish a message to the broker + client.publish( 'minecraft', 'loaded' ); + // subscribe to messages on 'arduino' topic + client.subscribe( 'arduino' ); + // do something when an incoming message arrives... + client.onMessageArrived( function( topic, message ) { + console.log( 'Message arrived: topic=' + topic + ', message=' + message ); + }); + + ``` The `sc-mqtt` module provides a very simple minimal wrapper around the [Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT @@ -1042,14 +1063,16 @@ String, then it tries to find the player with that name. #### Example - var utils = require('utils'); - var name = 'walterh'; - var player = utils.player(name); - if (player) { - player.sendMessage('Got ' + name); - }else{ - console.log('No player named ' + name); - } +```javascript +var utils = require('utils'); +var name = 'walterh'; +var player = utils.player(name); +if ( player ) { + player.sendMessage('Got ' + name); +} else { + console.log('No player named ' + name); +} +``` [bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html [bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html @@ -1087,11 +1110,13 @@ The utils.locationToString() function returns a keys in a lookup table. #### Example - - var utils = require('utils'); - ... - var key = utils.locationToString(player.location); - lookupTable[key] = player.name; + +```javascript +var utils = require('utils'); +... +var key = utils.locationToString(player.location); +lookupTable[key] = player.name; +``` ### utils.locationFromJSON() function @@ -1132,12 +1157,14 @@ is the location of the block the player is looking at (targeting). The following code will strike lightning at the location the player is looking at... - var utils = require('utils'); - var playerName = 'walterh'; - var targetPos = utils.getMousePos(playerName); - if (targetPos){ - targetPos.world.strikeLightning(targetPos); - } +```javascript +var utils = require('utils'); +var playerName = 'walterh'; +var targetPos = utils.getMousePos(playerName); +if (targetPos){ + targetPos.world.strikeLightning(targetPos); +} +``` ### utils.foreach() function @@ -1186,42 +1213,48 @@ and put the code there. The following example illustrates how to use foreach for immediate processing of an array... - var utils = require('utils'); - var players = ['moe', 'larry', 'curly']; - utils.foreach (players, function(item){ - server.getPlayer(item).sendMessage('Hi ' + item); - }); +```javascript +var utils = require('utils'); +var players = ['moe', 'larry', 'curly']; +utils.foreach (players, function(item){ + server.getPlayer(item).sendMessage('Hi ' + item); +}); +``` ... The `utils.foreach()` function can work with Arrays or any Java-style collection. This is important because many objects in the Bukkit API use Java-style collections... - utils.foreach( server.onlinePlayers, function(player){ - player.chat('Hello!'); - }); +```javascript +utils.foreach( server.onlinePlayers, function(player){ + player.chat('Hello!'); +}); +``` ... the above code sends a 'Hello!' to every online player. The following example is a more complex use case - The need to build an enormous structure without hogging CPU usage... - // build a structure 200 wide x 200 tall x 200 long - // (That's 8 Million Blocks - enough to tax any machine!) - var utils = require('utils'); +```javascript +// build a structure 200 wide x 200 tall x 200 long +// (That's 8 Million Blocks - enough to tax any machine!) +var utils = require('utils'); - var a = []; - a.length = 200; - var drone = new Drone(); - var processItem = function(item, index, object, array){ - // build a box 200 wide by 200 long then move up - drone.box(blocks.wood, 200, 1, 200).up(); - }; - // by the time the job's done 'self' might be someone else - // assume this code is within a function/closure - var player = self; - var onDone = function(){ - player.sendMessage('Job Done!'); - }; - utils.foreach (a, processItem, null, 10, onDone); +var a = []; +a.length = 200; +var drone = new Drone(); +var processItem = function(item, index, object, array){ + // build a box 200 wide by 200 long then move up + drone.box(blocks.wood, 200, 1, 200).up(); +}; +// by the time the job's done 'self' might be someone else +// assume this code is within a function/closure +var player = self; +var onDone = function(){ + player.sendMessage('Job Done!'); +}; +utils.foreach (a, processItem, null, 10, onDone); +``` ### utils.nicely() function @@ -1262,15 +1295,17 @@ The utils.at() function will perform a given task at a given time every To warn players when night is approaching... - var utils = require('utils'); +```javascript +var utils = require('utils'); - utils.at( '19:00', function() { +utils.at( '19:00', function() { - utils.foreach( server.onlinePlayers, function( player ) { + utils.foreach( server.onlinePlayers, function( player ) { player.chat( 'The night is dark and full of terrors!' ); - }); - }); + +}); +``` ### utils.find() function @@ -1286,10 +1321,12 @@ a given directory and recursiving trawling all sub-directories. #### Example - var utils = require('utils'); - var jsFiles = utils.find('./', function(dir,name){ - return name.match(/\.js$/); - }); +```javascript +var utils = require('utils'); +var jsFiles = utils.find('./', function(dir,name){ + return name.match(/\.js$/); +}); +``` ## Drone Plugin diff --git a/docs/YoungPersonsGuideToProgrammingMinecraft.md b/docs/YoungPersonsGuideToProgrammingMinecraft.md index 532d32f..2c704da 100644 --- a/docs/YoungPersonsGuideToProgrammingMinecraft.md +++ b/docs/YoungPersonsGuideToProgrammingMinecraft.md @@ -474,9 +474,11 @@ object can do, let's use that knowledge to create a Minecraft Mod! Once you've installed Notepad++, Launch it, create a new file and type the following... - exports.greet = function(player){ - player.sendMessage('Hi ' + player.name); - } +```javascript +exports.greet = function( player ) { + player.sendMessage('Hi ' + player.name); +} +``` ... then save the file in a new directory `craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace @@ -514,12 +516,14 @@ one or more functions, objects or variables. For example... #### thrower.js - exports.egg = function(player){ - player.throwEgg(); - } - exports.snowball = function(player){ - player.throwSnowball(); - } +```javascript +exports.egg = function(player){ + player.throwEgg(); +} +exports.snowball = function(player){ + player.throwSnowball(); +} +``` ... is a plugin which provides 2 javascript functions called `egg()` and `snowball()` which can be invoked from the in-game prompt like @@ -536,9 +540,11 @@ differently each time it is called. Change the `greet()` function so that it looks like this... - exports.greet = function ( greeting , player) { - player.sendMessage( greeting + player.name ); - } +```javascript +exports.greet = function ( greeting , player) { + player.sendMessage( greeting + player.name ); +} +``` ... Save your greet.js file and issue the `/js refresh()` command in minecraft. Now enter the following command in Minecraft... @@ -696,16 +702,20 @@ At the in-game command prompt type the following then hit Enter... statements on a single line at the in-game command prompt but the statements could be written like this... - var players = server.onlinePlayers; - for (var i = 0; i < players.length; i++) { - var player = players[i]; - player.sendMessage('Hi!'); - } +```javascript +var players = server.onlinePlayers; +var player; +var i; +for ( i = 0; i < players.length; i++ ) { + player = players[i]; + player.sendMessage( 'Hi!' ); +} +``` ... On the first line, a new variable `players` is created from the server object's onlinePlayers property. `players` is more concise and easier to type than the long-winded `server.onlinePlayers`. On the -second line, the for loop is declared, a counter variable `i` is set +fourth line, the for loop is declared, a counter variable `i` is set to 0 (zero - arrays in javascript start at 0 not 1) and each time around the loop is tested to see if it's less than the number of players online. At the end of each run around the loop the `i` @@ -729,13 +739,17 @@ function. Open the `hi.js` file you created earlier (using NotePad++ , TextWrangler or your editor of choice) and add the following code at the bottom of the file... - exports.hiAll = function (){ - var players = server.onlinePlayers; - for (var i = 0; i < players.length; i++) { - var player = players[i]; - player.sendMessage('Hi!'); - } +```javascript +exports.hiAll = function () { + var players = server.onlinePlayers, + player, + i; + for ( i = 0; i < players.length; i++) { + player = players[i]; + player.sendMessage( 'Hi!' ); } +} +``` ... save the file, at the in-game command prompt type `reload` and then type `/js hiAll()`. This will send the message `Hi!` to all of @@ -749,11 +763,13 @@ use `for` loops and Arrays to get things done. Another way to repeat things over and over is to use a `while` loop. The following `while` loop counts to 100... - var i = 1; - while (i <= 100){ - console.log( i ); - i = i + 1; - } +```javascript +var i = 1; +while (i <= 100){ + console.log( i ); + i = i + 1; +} +``` A `while` loop will repeat until its condition is `false` - the condition in the above example is `i <= 100` so while i is less than @@ -775,12 +791,14 @@ Just like `for` loops, `while` loops can be also be used to loop through arrays. The following loop prints out all of the players on the server... - var players = server.onlinePlayers; - var i = 0; - while ( i < players.length ) { - console.log( players[i] ); - i = i + 1; - } +```javascript +var players = server.onlinePlayers; +var i = 0; +while ( i < players.length ) { + console.log( players[i] ); + i = i + 1; +} +``` ... whether you chose to use a `for` loop or a `while` loop is largely a matter of personal taste, `for` loops are more commonly used with @@ -814,31 +832,30 @@ above example uses a named function which already exists ( `console.log` ), you can also create new functions on-the-fly and pass them to the utils.foreach() function... - /* - give every player the ability to fly. - */ - var utils = require('utils'); - utils.foreach( server.onlinePlayers, - function (player) { - player.setAllowFlight(true); - } - ); +```javascript +/* + give every player the ability to fly. +*/ +var utils = require('utils'); +utils.foreach( server.onlinePlayers, function( player ) { + player.setAllowFlight(true); +} ); +``` ... Another example, this time each player will hear a Cat's Meow... - /* - Play a Cat's Meow sound for each player. - */ - var utils = require('utils'); - utils.foreach( server.onlinePlayers, - function (player) { - player.playSound(player.location, - org.bukkit.Sound.CAT_MEOW, - 1, - 1); - - } - ); +```javascript +/* + Play a Cat's Meow sound for each player. +*/ +var utils = require('utils'); +utils.foreach( server.onlinePlayers, function( player ) { + player.playSound(player.location, + org.bukkit.Sound.CAT_MEOW, + 1, + 1); +} ); +``` ### Exercise Try changing the above function so that different sounds are played @@ -873,23 +890,24 @@ loops come in. Open your favorite text editor and create a new file in your scriptcraft/plugins/{your-name} directory, name the file `myskyscraper.js`, then type the following... - var myskyscraper = function(floors) { - if (typeof floors == 'undefined'){ - floors = 10; - } - this.chkpt('myskyscraper'); // saves the drone position so it can return there later - for (var i = 0; i < floors; i++) - { - this.box(blocks.iron,20,1,20) - .up() - .box0(blocks.glass_pane,20,3,20) - .up(3); - } - return this.move('myskyscraper'); // return to where we started - }; - - var Drone = require('../drone/drone.js').Drone; - Drone.extend('myskyscraper',myskyscraper); +```javascript +var myskyscraper = function(floors) { + if (typeof floors == 'undefined'){ + floors = 10; + } + this.chkpt('myskyscraper'); // saves the drone position so it can return there later + for (var i = 0; i < floors; i++) + { + this.box(blocks.iron,20,1,20) + .up() + .box0(blocks.glass_pane,20,3,20) + .up(3); + } + return this.move('myskyscraper'); // return to where we started +}; +var Drone = require('../drone/drone.js').Drone; +Drone.extend('myskyscraper',myskyscraper); +``` ... so this takes a little explaining. First I create a new function called myskyscraper that will take a single parameter `floors` so that @@ -969,17 +987,15 @@ flying or not? This is where the `if - else` construct comes in handy. Open your favorite editor and type the following code into a new file in your scriptcraft/plugins directory... - function flightStatus(player) - { - if ( player.flying ) - { - player.sendMessage( 'Hey, You are flying!' ); - } - else - { - player.sendMessage( 'You are not flying.' ); - } - } +```javascript +function flightStatus( player ) { + if ( player.flying ) { + player.sendMessage( 'Hey, You are flying!' ); + } else { + player.sendMessage( 'You are not flying.' ); + } +} +``` ... now type `/reload` at the in-game prompt then type `/js flightStatus(self)` and an appropriate message will appear based on @@ -1009,10 +1025,12 @@ of event occurs, it's probably best to illustrate this by example. The following code sends a message to any player who breaks a block in the game... - events.on('block.BlockBreakEvent', function (listener, event) { - var breaker = event.player; - breaker.sendMessage('You broke a block'); - }); +```javascript +events.on('block.BlockBreakEvent', function ( listener, event ) { + var breaker = event.player; + breaker.sendMessage('You broke a block'); +} ); +``` The `events.on()` function is how you *register* a function which you want to be called whenever a particular type of event occurs. In the @@ -1063,11 +1081,13 @@ just specify the fully qualified class name instead. E.g. ... If you want an event handler to only execute once, you can remove the handler like this... - events.on('block.BlockBreakEvent', function(listener, evt) { - var breaker = evt.player; - breaker.sendMessage('You broke a block'); - evt.handlers.unregister( listener ); - }); +```javascript +events.on('block.BlockBreakEvent', function( listener, evt ) { + var breaker = evt.player; + breaker.sendMessage('You broke a block'); + evt.handlers.unregister( listener ); +} ); +``` The `evt.handlers.unregister( listener );` statement will remove this function from the list of listeners for this event. @@ -1121,47 +1141,55 @@ the name column until I find 'jane' then look *across* to get her score. In Javascript, an object which stored such a table would look like this... - var scoreboard = { - walter: 5, - tom: 6, - jane: 8, - bart: 7 - }; +```javascript +var scoreboard = { + walter: 5, + tom: 6, + jane: 8, + bart: 7 +}; +``` ... and if I wanted to write a function which took a player name as a parameter and returned their score, I'd do it like this... - function getScore(player){ - return scoreboard[ player ]; - } +```javascript +function getScore(player){ + return scoreboard[ player ]; +} +``` ... I might call such a function like this... - var janesScore = getScore('jane'); // returns 8 +```javascript +var janesScore = getScore('jane'); // returns 8 +``` ... putting it all together, a hypothetical scoreboard.js mdoule might look something like this... - var utils = require('utils'); - var scores = {}; +```javascript +var utils = require('utils'); +var scores = {}; - exports.initialise = function(names){ - scores = {}; - utils.foreach(names, function(name){ - scores[name] = 0; - }); - }; +exports.initialise = function(names){ + scores = {}; + utils.foreach(names, function(name){ + scores[name] = 0; + }); +}; - /* changes score by diff e.g. to add 6 to the player's current score - updateScore('walter',6); // walter's new score = 5 + 6 = 11. - */ - exports.updateScore = function(name, diff){ - scores[name] += diff; - }; +/* changes score by diff e.g. to add 6 to the player's current score + updateScore('walter',6); // walter's new score = 5 + 6 = 11. +*/ +exports.updateScore = function(name, diff){ + scores[name] += diff; +}; - exports.getScore = function(name){ - return scores[name]; - }; +exports.getScore = function(name){ + return scores[name]; +}; +``` ## Counting block break events for each player @@ -1170,20 +1198,21 @@ keep a count of how many blocks each player has broken ... #### block-break-counter.js - var breaks = {}; - // every time a player joins the game reset their block-break-count to 0 - events.on('player.PlayerJoinEvent', function(listener, event){ - breaks[event.player] = 0; - }); - events.on('block.BlockBreakEvent', function(listener, event){ - var breaker = event.player; - var breakCount = breaks[breaker.name]; - breakCount++; // increment the count. - breaks[breaker.name] = breakCount; - - breaker.sendMessage('You broke ' + breakCount + ' blocks'); - - }); +```javascript +var breaks = {}; +// every time a player joins the game reset their block-break-count to 0 +events.on('player.PlayerJoinEvent', function(listener, event){ + breaks[event.player] = 0; +}); +events.on('block.BlockBreakEvent', function(listener, event){ + var breaker = event.player; + var breakCount = breaks[breaker.name]; + breakCount++; // increment the count. + breaks[breaker.name] = breakCount; + + breaker.sendMessage('You broke ' + breakCount + ' blocks'); +}); +``` With a little more work, you could turn this into a game where players compete against each other to break as many blocks as possible within diff --git a/src/docs/templates/ypgpm.md b/src/docs/templates/ypgpm.md index 2ecd292..98349a4 100644 --- a/src/docs/templates/ypgpm.md +++ b/src/docs/templates/ypgpm.md @@ -439,9 +439,11 @@ object can do, let's use that knowledge to create a Minecraft Mod! Once you've installed Notepad++, Launch it, create a new file and type the following... - exports.greet = function(player){ - player.sendMessage('Hi ' + player.name); - } +```javascript +exports.greet = function( player ) { + player.sendMessage('Hi ' + player.name); +} +``` ... then save the file in a new directory `craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace @@ -479,12 +481,14 @@ one or more functions, objects or variables. For example... #### thrower.js - exports.egg = function(player){ - player.throwEgg(); - } - exports.snowball = function(player){ - player.throwSnowball(); - } +```javascript +exports.egg = function(player){ + player.throwEgg(); +} +exports.snowball = function(player){ + player.throwSnowball(); +} +``` ... is a plugin which provides 2 javascript functions called `egg()` and `snowball()` which can be invoked from the in-game prompt like @@ -501,9 +505,11 @@ differently each time it is called. Change the `greet()` function so that it looks like this... - exports.greet = function ( greeting , player) { - player.sendMessage( greeting + player.name ); - } +```javascript +exports.greet = function ( greeting , player) { + player.sendMessage( greeting + player.name ); +} +``` ... Save your greet.js file and issue the `/js refresh()` command in minecraft. Now enter the following command in Minecraft... @@ -661,16 +667,20 @@ At the in-game command prompt type the following then hit Enter... statements on a single line at the in-game command prompt but the statements could be written like this... - var players = server.onlinePlayers; - for (var i = 0; i < players.length; i++) { - var player = players[i]; - player.sendMessage('Hi!'); - } +```javascript +var players = server.onlinePlayers; +var player; +var i; +for ( i = 0; i < players.length; i++ ) { + player = players[i]; + player.sendMessage( 'Hi!' ); +} +``` ... On the first line, a new variable `players` is created from the server object's onlinePlayers property. `players` is more concise and easier to type than the long-winded `server.onlinePlayers`. On the -second line, the for loop is declared, a counter variable `i` is set +fourth line, the for loop is declared, a counter variable `i` is set to 0 (zero - arrays in javascript start at 0 not 1) and each time around the loop is tested to see if it's less than the number of players online. At the end of each run around the loop the `i` @@ -694,13 +704,17 @@ function. Open the `hi.js` file you created earlier (using NotePad++ , TextWrangler or your editor of choice) and add the following code at the bottom of the file... - exports.hiAll = function (){ - var players = server.onlinePlayers; - for (var i = 0; i < players.length; i++) { - var player = players[i]; - player.sendMessage('Hi!'); - } +```javascript +exports.hiAll = function () { + var players = server.onlinePlayers, + player, + i; + for ( i = 0; i < players.length; i++) { + player = players[i]; + player.sendMessage( 'Hi!' ); } +} +``` ... save the file, at the in-game command prompt type `reload` and then type `/js hiAll()`. This will send the message `Hi!` to all of @@ -714,11 +728,13 @@ use `for` loops and Arrays to get things done. Another way to repeat things over and over is to use a `while` loop. The following `while` loop counts to 100... - var i = 1; - while (i <= 100){ - console.log( i ); - i = i + 1; - } +```javascript +var i = 1; +while (i <= 100){ + console.log( i ); + i = i + 1; +} +``` A `while` loop will repeat until its condition is `false` - the condition in the above example is `i <= 100` so while i is less than @@ -740,12 +756,14 @@ Just like `for` loops, `while` loops can be also be used to loop through arrays. The following loop prints out all of the players on the server... - var players = server.onlinePlayers; - var i = 0; - while ( i < players.length ) { - console.log( players[i] ); - i = i + 1; - } +```javascript +var players = server.onlinePlayers; +var i = 0; +while ( i < players.length ) { + console.log( players[i] ); + i = i + 1; +} +``` ... whether you chose to use a `for` loop or a `while` loop is largely a matter of personal taste, `for` loops are more commonly used with @@ -779,31 +797,30 @@ above example uses a named function which already exists ( `console.log` ), you can also create new functions on-the-fly and pass them to the utils.foreach() function... - /* - give every player the ability to fly. - */ - var utils = require('utils'); - utils.foreach( server.onlinePlayers, - function (player) { - player.setAllowFlight(true); - } - ); +```javascript +/* + give every player the ability to fly. +*/ +var utils = require('utils'); +utils.foreach( server.onlinePlayers, function( player ) { + player.setAllowFlight(true); +} ); +``` ... Another example, this time each player will hear a Cat's Meow... - /* - Play a Cat's Meow sound for each player. - */ - var utils = require('utils'); - utils.foreach( server.onlinePlayers, - function (player) { - player.playSound(player.location, - org.bukkit.Sound.CAT_MEOW, - 1, - 1); - - } - ); +```javascript +/* + Play a Cat's Meow sound for each player. +*/ +var utils = require('utils'); +utils.foreach( server.onlinePlayers, function( player ) { + player.playSound(player.location, + org.bukkit.Sound.CAT_MEOW, + 1, + 1); +} ); +``` ### Exercise Try changing the above function so that different sounds are played @@ -838,23 +855,24 @@ loops come in. Open your favorite text editor and create a new file in your scriptcraft/plugins/{your-name} directory, name the file `myskyscraper.js`, then type the following... - var myskyscraper = function(floors) { - if (typeof floors == 'undefined'){ - floors = 10; - } - this.chkpt('myskyscraper'); // saves the drone position so it can return there later - for (var i = 0; i < floors; i++) - { - this.box(blocks.iron,20,1,20) - .up() - .box0(blocks.glass_pane,20,3,20) - .up(3); - } - return this.move('myskyscraper'); // return to where we started - }; - - var Drone = require('../drone/drone.js').Drone; - Drone.extend('myskyscraper',myskyscraper); +```javascript +var myskyscraper = function(floors) { + if (typeof floors == 'undefined'){ + floors = 10; + } + this.chkpt('myskyscraper'); // saves the drone position so it can return there later + for (var i = 0; i < floors; i++) + { + this.box(blocks.iron,20,1,20) + .up() + .box0(blocks.glass_pane,20,3,20) + .up(3); + } + return this.move('myskyscraper'); // return to where we started +}; +var Drone = require('../drone/drone.js').Drone; +Drone.extend('myskyscraper',myskyscraper); +``` ... so this takes a little explaining. First I create a new function called myskyscraper that will take a single parameter `floors` so that @@ -934,17 +952,15 @@ flying or not? This is where the `if - else` construct comes in handy. Open your favorite editor and type the following code into a new file in your scriptcraft/plugins directory... - function flightStatus(player) - { - if ( player.flying ) - { - player.sendMessage( 'Hey, You are flying!' ); - } - else - { - player.sendMessage( 'You are not flying.' ); - } - } +```javascript +function flightStatus( player ) { + if ( player.flying ) { + player.sendMessage( 'Hey, You are flying!' ); + } else { + player.sendMessage( 'You are not flying.' ); + } +} +``` ... now type `/reload` at the in-game prompt then type `/js flightStatus(self)` and an appropriate message will appear based on @@ -974,10 +990,12 @@ of event occurs, it's probably best to illustrate this by example. The following code sends a message to any player who breaks a block in the game... - events.on('block.BlockBreakEvent', function (listener, event) { - var breaker = event.player; - breaker.sendMessage('You broke a block'); - }); +```javascript +events.on('block.BlockBreakEvent', function ( listener, event ) { + var breaker = event.player; + breaker.sendMessage('You broke a block'); +} ); +``` The `events.on()` function is how you *register* a function which you want to be called whenever a particular type of event occurs. In the @@ -1028,11 +1046,13 @@ just specify the fully qualified class name instead. E.g. ... If you want an event handler to only execute once, you can remove the handler like this... - events.on('block.BlockBreakEvent', function(listener, evt) { - var breaker = evt.player; - breaker.sendMessage('You broke a block'); - evt.handlers.unregister( listener ); - }); +```javascript +events.on('block.BlockBreakEvent', function( listener, evt ) { + var breaker = evt.player; + breaker.sendMessage('You broke a block'); + evt.handlers.unregister( listener ); +} ); +``` The `evt.handlers.unregister( listener );` statement will remove this function from the list of listeners for this event. @@ -1086,47 +1106,55 @@ the name column until I find 'jane' then look *across* to get her score. In Javascript, an object which stored such a table would look like this... - var scoreboard = { - walter: 5, - tom: 6, - jane: 8, - bart: 7 - }; +```javascript +var scoreboard = { + walter: 5, + tom: 6, + jane: 8, + bart: 7 +}; +``` ... and if I wanted to write a function which took a player name as a parameter and returned their score, I'd do it like this... - function getScore(player){ - return scoreboard[ player ]; - } +```javascript +function getScore(player){ + return scoreboard[ player ]; +} +``` ... I might call such a function like this... - var janesScore = getScore('jane'); // returns 8 +```javascript +var janesScore = getScore('jane'); // returns 8 +``` ... putting it all together, a hypothetical scoreboard.js mdoule might look something like this... - var utils = require('utils'); - var scores = {}; +```javascript +var utils = require('utils'); +var scores = {}; - exports.initialise = function(names){ - scores = {}; - utils.foreach(names, function(name){ - scores[name] = 0; - }); - }; +exports.initialise = function(names){ + scores = {}; + utils.foreach(names, function(name){ + scores[name] = 0; + }); +}; - /* changes score by diff e.g. to add 6 to the player's current score - updateScore('walter',6); // walter's new score = 5 + 6 = 11. - */ - exports.updateScore = function(name, diff){ - scores[name] += diff; - }; +/* changes score by diff e.g. to add 6 to the player's current score + updateScore('walter',6); // walter's new score = 5 + 6 = 11. +*/ +exports.updateScore = function(name, diff){ + scores[name] += diff; +}; - exports.getScore = function(name){ - return scores[name]; - }; +exports.getScore = function(name){ + return scores[name]; +}; +``` ## Counting block break events for each player @@ -1135,20 +1163,21 @@ keep a count of how many blocks each player has broken ... #### block-break-counter.js - var breaks = {}; - // every time a player joins the game reset their block-break-count to 0 - events.on('player.PlayerJoinEvent', function(listener, event){ - breaks[event.player] = 0; - }); - events.on('block.BlockBreakEvent', function(listener, event){ - var breaker = event.player; - var breakCount = breaks[breaker.name]; - breakCount++; // increment the count. - breaks[breaker.name] = breakCount; - - breaker.sendMessage('You broke ' + breakCount + ' blocks'); - - }); +```javascript +var breaks = {}; +// every time a player joins the game reset their block-break-count to 0 +events.on('player.PlayerJoinEvent', function(listener, event){ + breaks[event.player] = 0; +}); +events.on('block.BlockBreakEvent', function(listener, event){ + var breaker = event.player; + var breakCount = breaks[breaker.name]; + breakCount++; // increment the count. + breaks[breaker.name] = breakCount; + + breaker.sendMessage('You broke ' + breakCount + ' blocks'); +}); +``` With a little more work, you could turn this into a game where players compete against each other to break as many blocks as possible within diff --git a/src/main/js/lib/require.js b/src/main/js/lib/require.js index 6c85142..fa1b91e 100644 --- a/src/main/js/lib/require.js +++ b/src/main/js/lib/require.js @@ -18,23 +18,29 @@ For example imagine you have 3 files program.js, inc.js and math.js ... ### math.js - exports.add = function(a,b){ - return a + b; - } +```javascript +exports.add = function(a,b){ + return a + b; +} +``` ### inc.js - var math = require('./math'); - exports.increment = function(n){ - return math.add(n, 1); - } +```javascript +var math = require('./math'); +exports.increment = function(n){ + return math.add(n, 1); +} +``` ### program.js - var inc = require('./inc').increment; - var a = 7; - a = inc(a); - print(a); +```javascript +var inc = require('./inc').increment; +var a = 7; +a = inc(a); +print(a); +``` You can see from the above sample code that programs can use modules and modules themeselves can use other modules. Modules have full diff --git a/src/main/js/lib/scriptcraft.js b/src/main/js/lib/scriptcraft.js index 38ca67b..4d80c78 100644 --- a/src/main/js/lib/scriptcraft.js +++ b/src/main/js/lib/scriptcraft.js @@ -12,21 +12,23 @@ loads the module circle.js in the same directory. The contents of foo.js: - var circle = require('./circle.js'); - console.log( 'The area of a circle of radius 4 is ' - + circle.area(4)); +```javascript +var circle = require('./circle.js'); +console.log( 'The area of a circle of radius 4 is ' + + circle.area(4)); +``` The contents of circle.js: - var PI = Math.PI; - - exports.area = function (r) { - return PI * r * r; - }; - - exports.circumference = function (r) { - return 2 * PI * r; - }; +```javascript +var PI = Math.PI; +exports.area = function (r) { + return PI * r * r; +}; +exports.circumference = function (r) { + return 2 * PI * r; +}; +``` The module circle.js has exported the functions area() and circumference(). To add functions and objects to the root of your @@ -66,9 +68,11 @@ module in the `plugins` directory exports becomes a global variable. For example, if you have a module greeting.js in the plugins directory.... - exports.greet = function(player) { - player.sendMessage('Hello ' + player.name); - }; +```javascript +exports.greet = function(player) { + player.sendMessage('Hello ' + player.name); +}; +``` ... then `greet` becomes a global function and can be used at the in-game (or server) command prompt like so... @@ -256,10 +260,12 @@ restored using the `scload()` function. #### Example - var myObject = { name: 'John Doe', - aliases: ['John Ray', 'John Mee'], - date_of_birth: '1982/01/31' }; - scsave(myObject, 'johndoe.json'); +```javascript +var myObject = { name: 'John Doe', + aliases: ['John Ray', 'John Mee'], + date_of_birth: '1982/01/31' }; +scsave(myObject, 'johndoe.json'); +``` ##### johndoe.json contents... @@ -346,13 +352,15 @@ If Node.js supports setTimeout() then it's probably good for ScriptCraft to supp #### Example - // - // start a storm in 5 seconds - // - setTimeout( function() { - var world = server.worlds.get(0); - world.setStorm(true); - }, 5000); +```javascript +// +// start a storm in 5 seconds +// +setTimeout( function() { + var world = server.worlds.get(0); + world.setStorm(true); +}, 5000); +``` ### clearTimeout() function @@ -477,7 +485,6 @@ function __onEnable ( __engine, __plugin, __script ) var canonizedFilename = _canonize( file ); if ( file.exists() ) { - parent = file.getParentFile(); reader = new FileReader( file ); br = new BufferedReader( reader ); code = ''; diff --git a/src/main/js/modules/sc-mqtt.js b/src/main/js/modules/sc-mqtt.js index 99069ab..96197ab 100644 --- a/src/main/js/modules/sc-mqtt.js +++ b/src/main/js/modules/sc-mqtt.js @@ -17,31 +17,38 @@ present in the CraftBukkit classpath. To use this module, you should craftbukkit-sc-mqtt.bat and edit it to include the following command... - java -classpath sc-mqtt.jar;craftbukit.jar org.bukkit.craftbukkit.Main - + ```sh + java -classpath sc-mqtt.jar;craftbukit.jar org.bukkit.craftbukkit.Main + ``` + If you're using Mac OS, create a new craftbukkit-sc-mqtt.command file and edit it (using TextWrangler or another text editor) ... - java -classpath sc-mqtt.jar:craftbukkit.jar org.bukit.craftbukkit.Main + ```sh + java -classpath sc-mqtt.jar:craftbukkit.jar org.bukit.craftbukkit.Main + ``` 4. Execute the craftbukkit-sc-mqtt batch file / command file to start Craftbukkit. You can now begin using this module to send and receive messages to/from a Net-enabled Arduino or any other device which uses the [MQTT protocol][mqtt] - var mqtt = require('sc-mqtt'); - // create a new client - var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); - // connect to the broker - client.connect( { keepAliveInterval: 15 } ); - // publish a message to the broker - client.publish( 'minecraft', 'loaded' ); - // subscribe to messages on 'arduino' topic - client.subscribe( 'arduino' ); - // do something when an incoming message arrives... - client.onMessageArrived( function( topic, message ) { - console.log( 'Message arrived: topic=' + topic + ', message=' + message ); - }); + ```javascript + var mqtt = require('sc-mqtt'); + // create a new client + var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); + // connect to the broker + client.connect( { keepAliveInterval: 15 } ); + // publish a message to the broker + client.publish( 'minecraft', 'loaded' ); + // subscribe to messages on 'arduino' topic + client.subscribe( 'arduino' ); + // do something when an incoming message arrives... + client.onMessageArrived( function( topic, message ) { + console.log( 'Message arrived: topic=' + topic + ', message=' + message ); + }); + + ``` The `sc-mqtt` module provides a very simple minimal wrapper around the [Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT diff --git a/src/main/js/modules/utils/utils.js b/src/main/js/modules/utils/utils.js index 6c438bc..20f27de 100644 --- a/src/main/js/modules/utils/utils.js +++ b/src/main/js/modules/utils/utils.js @@ -22,14 +22,16 @@ String, then it tries to find the player with that name. #### Example - var utils = require('utils'); - var name = 'walterh'; - var player = utils.player(name); - if (player) { - player.sendMessage('Got ' + name); - }else{ - console.log('No player named ' + name); - } +```javascript +var utils = require('utils'); +var name = 'walterh'; +var player = utils.player(name); +if ( player ) { + player.sendMessage('Got ' + name); +} else { + console.log('No player named ' + name); +} +``` [bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html [bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html @@ -95,11 +97,13 @@ The utils.locationToString() function returns a keys in a lookup table. #### Example - - var utils = require('utils'); - ... - var key = utils.locationToString(player.location); - lookupTable[key] = player.name; + +```javascript +var utils = require('utils'); +... +var key = utils.locationToString(player.location); +lookupTable[key] = player.name; +``` ***/ exports.locationToString = function( location ) { @@ -179,12 +183,14 @@ is the location of the block the player is looking at (targeting). The following code will strike lightning at the location the player is looking at... - var utils = require('utils'); - var playerName = 'walterh'; - var targetPos = utils.getMousePos(playerName); - if (targetPos){ - targetPos.world.strikeLightning(targetPos); - } +```javascript +var utils = require('utils'); +var playerName = 'walterh'; +var targetPos = utils.getMousePos(playerName); +if (targetPos){ + targetPos.world.strikeLightning(targetPos); +} +``` ***/ exports.getMousePos = function( player ) { @@ -251,42 +257,48 @@ and put the code there. The following example illustrates how to use foreach for immediate processing of an array... - var utils = require('utils'); - var players = ['moe', 'larry', 'curly']; - utils.foreach (players, function(item){ - server.getPlayer(item).sendMessage('Hi ' + item); - }); +```javascript +var utils = require('utils'); +var players = ['moe', 'larry', 'curly']; +utils.foreach (players, function(item){ + server.getPlayer(item).sendMessage('Hi ' + item); +}); +``` ... The `utils.foreach()` function can work with Arrays or any Java-style collection. This is important because many objects in the Bukkit API use Java-style collections... - utils.foreach( server.onlinePlayers, function(player){ - player.chat('Hello!'); - }); +```javascript +utils.foreach( server.onlinePlayers, function(player){ + player.chat('Hello!'); +}); +``` ... the above code sends a 'Hello!' to every online player. The following example is a more complex use case - The need to build an enormous structure without hogging CPU usage... - // build a structure 200 wide x 200 tall x 200 long - // (That's 8 Million Blocks - enough to tax any machine!) - var utils = require('utils'); +```javascript +// build a structure 200 wide x 200 tall x 200 long +// (That's 8 Million Blocks - enough to tax any machine!) +var utils = require('utils'); - var a = []; - a.length = 200; - var drone = new Drone(); - var processItem = function(item, index, object, array){ - // build a box 200 wide by 200 long then move up - drone.box(blocks.wood, 200, 1, 200).up(); - }; - // by the time the job's done 'self' might be someone else - // assume this code is within a function/closure - var player = self; - var onDone = function(){ - player.sendMessage('Job Done!'); - }; - utils.foreach (a, processItem, null, 10, onDone); +var a = []; +a.length = 200; +var drone = new Drone(); +var processItem = function(item, index, object, array){ + // build a box 200 wide by 200 long then move up + drone.box(blocks.wood, 200, 1, 200).up(); +}; +// by the time the job's done 'self' might be someone else +// assume this code is within a function/closure +var player = self; +var onDone = function(){ + player.sendMessage('Job Done!'); +}; +utils.foreach (a, processItem, null, 10, onDone); +``` ***/ var _foreach = function( array, callback, context, delay, onCompletion ) { @@ -366,15 +378,17 @@ The utils.at() function will perform a given task at a given time every To warn players when night is approaching... - var utils = require('utils'); +```javascript +var utils = require('utils'); - utils.at( '19:00', function() { +utils.at( '19:00', function() { - utils.foreach( server.onlinePlayers, function( player ) { + utils.foreach( server.onlinePlayers, function( player ) { player.chat( 'The night is dark and full of terrors!' ); - }); - }); + +}); +``` ***/ exports.at = function( time24hr, callback, worlds ) { @@ -415,10 +429,12 @@ a given directory and recursiving trawling all sub-directories. #### Example - var utils = require('utils'); - var jsFiles = utils.find('./', function(dir,name){ - return name.match(/\.js$/); - }); +```javascript +var utils = require('utils'); +var jsFiles = utils.find('./', function(dir,name){ + return name.match(/\.js$/); +}); +``` ***/ exports.find = function( dir , filter ) {