added syntax-highlighting to code samples

This commit is contained in:
walterhiggins 2014-02-04 21:36:00 +00:00
parent fe62f61883
commit f1925efd87
7 changed files with 614 additions and 483 deletions

View file

@ -156,21 +156,23 @@ loads the module circle.js in the same directory.
The contents of foo.js: The contents of foo.js:
var circle = require('./circle.js'); ```javascript
console.log( 'The area of a circle of radius 4 is ' var circle = require('./circle.js');
+ circle.area(4)); console.log( 'The area of a circle of radius 4 is '
+ circle.area(4));
```
The contents of circle.js: The contents of circle.js:
var PI = Math.PI; ```javascript
var PI = Math.PI;
exports.area = function (r) { exports.area = function (r) {
return PI * r * r; return PI * r * r;
}; };
exports.circumference = function (r) {
exports.circumference = function (r) { return 2 * PI * r;
return 2 * PI * r; };
}; ```
The module circle.js has exported the functions area() and The module circle.js has exported the functions area() and
circumference(). To add functions and objects to the root of your 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 variable. For example, if you have a module greeting.js in the plugins
directory.... directory....
exports.greet = function(player) { ```javascript
player.sendMessage('Hello ' + player.name); exports.greet = function(player) {
}; player.sendMessage('Hello ' + player.name);
};
```
... then `greet` becomes a global function and can be used at the ... then `greet` becomes a global function and can be used at the
in-game (or server) command prompt like so... in-game (or server) command prompt like so...
@ -400,10 +404,12 @@ restored using the `scload()` function.
#### Example #### Example
var myObject = { name: 'John Doe', ```javascript
aliases: ['John Ray', 'John Mee'], var myObject = { name: 'John Doe',
date_of_birth: '1982/01/31' }; aliases: ['John Ray', 'John Mee'],
scsave(myObject, 'johndoe.json'); date_of_birth: '1982/01/31' };
scsave(myObject, 'johndoe.json');
```
##### johndoe.json contents... ##### johndoe.json contents...
@ -490,13 +496,15 @@ If Node.js supports setTimeout() then it's probably good for ScriptCraft to supp
#### Example #### Example
// ```javascript
// start a storm in 5 seconds //
// // start a storm in 5 seconds
setTimeout( function() { //
var world = server.worlds.get(0); setTimeout( function() {
world.setStorm(true); var world = server.worlds.get(0);
}, 5000); world.setStorm(true);
}, 5000);
```
### clearTimeout() function ### clearTimeout() function
@ -566,23 +574,29 @@ For example imagine you have 3 files program.js, inc.js and math.js ...
### math.js ### math.js
exports.add = function(a,b){ ```javascript
return a + b; exports.add = function(a,b){
} return a + b;
}
```
### inc.js ### inc.js
var math = require('./math'); ```javascript
exports.increment = function(n){ var math = require('./math');
return math.add(n, 1); exports.increment = function(n){
} return math.add(n, 1);
}
```
### program.js ### program.js
var inc = require('./inc').increment; ```javascript
var a = 7; var inc = require('./inc').increment;
a = inc(a); var a = 7;
print(a); a = inc(a);
print(a);
```
You can see from the above sample code that programs can use modules You can see from the above sample code that programs can use modules
and modules themeselves can use other modules. Modules have full 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 craftbukkit-sc-mqtt.bat and edit it to include the following
command... 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 If you're using Mac OS, create a new craftbukkit-sc-mqtt.command
file and edit it (using TextWrangler or another text editor) ... 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 4. Execute the craftbukkit-sc-mqtt batch file / command file to start
Craftbukkit. You can now begin using this module to send and receive 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 messages to/from a Net-enabled Arduino or any other device which uses
the [MQTT protocol][mqtt] the [MQTT protocol][mqtt]
var mqtt = require('sc-mqtt'); ```javascript
// create a new client var mqtt = require('sc-mqtt');
var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); // create a new client
// connect to the broker var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' );
client.connect( { keepAliveInterval: 15 } ); // connect to the broker
// publish a message to the broker client.connect( { keepAliveInterval: 15 } );
client.publish( 'minecraft', 'loaded' ); // publish a message to the broker
// subscribe to messages on 'arduino' topic client.publish( 'minecraft', 'loaded' );
client.subscribe( 'arduino' ); // subscribe to messages on 'arduino' topic
// do something when an incoming message arrives... client.subscribe( 'arduino' );
client.onMessageArrived( function( topic, message ) { // do something when an incoming message arrives...
console.log( 'Message arrived: topic=' + topic + ', message=' + message ); 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 The `sc-mqtt` module provides a very simple minimal wrapper around the
[Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT [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 #### Example
var utils = require('utils'); ```javascript
var name = 'walterh'; var utils = require('utils');
var player = utils.player(name); var name = 'walterh';
if (player) { var player = utils.player(name);
player.sendMessage('Got ' + name); if ( player ) {
}else{ player.sendMessage('Got ' + name);
console.log('No player named ' + name); } else {
} console.log('No player named ' + name);
}
```
[bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html [bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.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. keys in a lookup table.
#### Example #### Example
var utils = require('utils'); ```javascript
... var utils = require('utils');
var key = utils.locationToString(player.location); ...
lookupTable[key] = player.name; var key = utils.locationToString(player.location);
lookupTable[key] = player.name;
```
### utils.locationFromJSON() function ### 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... The following code will strike lightning at the location the player is looking at...
var utils = require('utils'); ```javascript
var playerName = 'walterh'; var utils = require('utils');
var targetPos = utils.getMousePos(playerName); var playerName = 'walterh';
if (targetPos){ var targetPos = utils.getMousePos(playerName);
targetPos.world.strikeLightning(targetPos); if (targetPos){
} targetPos.world.strikeLightning(targetPos);
}
```
### utils.foreach() function ### 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... The following example illustrates how to use foreach for immediate processing of an array...
var utils = require('utils'); ```javascript
var players = ['moe', 'larry', 'curly']; var utils = require('utils');
utils.foreach (players, function(item){ var players = ['moe', 'larry', 'curly'];
server.getPlayer(item).sendMessage('Hi ' + item); 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 ... 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... because many objects in the Bukkit API use Java-style collections...
utils.foreach( server.onlinePlayers, function(player){ ```javascript
player.chat('Hello!'); utils.foreach( server.onlinePlayers, function(player){
}); player.chat('Hello!');
});
```
... the above code sends a 'Hello!' to every online player. ... 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 The following example is a more complex use case - The need to build an enormous structure
without hogging CPU usage... without hogging CPU usage...
// build a structure 200 wide x 200 tall x 200 long ```javascript
// (That's 8 Million Blocks - enough to tax any machine!) // build a structure 200 wide x 200 tall x 200 long
var utils = require('utils'); // (That's 8 Million Blocks - enough to tax any machine!)
var utils = require('utils');
var a = []; var a = [];
a.length = 200; a.length = 200;
var drone = new Drone(); var drone = new Drone();
var processItem = function(item, index, object, array){ var processItem = function(item, index, object, array){
// build a box 200 wide by 200 long then move up // build a box 200 wide by 200 long then move up
drone.box(blocks.wood, 200, 1, 200).up(); drone.box(blocks.wood, 200, 1, 200).up();
}; };
// by the time the job's done 'self' might be someone else // by the time the job's done 'self' might be someone else
// assume this code is within a function/closure // assume this code is within a function/closure
var player = self; var player = self;
var onDone = function(){ var onDone = function(){
player.sendMessage('Job Done!'); player.sendMessage('Job Done!');
}; };
utils.foreach (a, processItem, null, 10, onDone); utils.foreach (a, processItem, null, 10, onDone);
```
### utils.nicely() function ### 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... 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!' ); player.chat( 'The night is dark and full of terrors!' );
});
}); });
});
```
### utils.find() function ### utils.find() function
@ -1286,10 +1321,12 @@ a given directory and recursiving trawling all sub-directories.
#### Example #### Example
var utils = require('utils'); ```javascript
var jsFiles = utils.find('./', function(dir,name){ var utils = require('utils');
return name.match(/\.js$/); var jsFiles = utils.find('./', function(dir,name){
}); return name.match(/\.js$/);
});
```
## Drone Plugin ## Drone Plugin

View file

@ -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... Once you've installed Notepad++, Launch it, create a new file and type the following...
exports.greet = function(player){ ```javascript
player.sendMessage('Hi ' + player.name); exports.greet = function( player ) {
} player.sendMessage('Hi ' + player.name);
}
```
... then save the file in a new directory ... then save the file in a new directory
`craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace `craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace
@ -514,12 +516,14 @@ one or more functions, objects or variables. For example...
#### thrower.js #### thrower.js
exports.egg = function(player){ ```javascript
player.throwEgg(); exports.egg = function(player){
} player.throwEgg();
exports.snowball = function(player){ }
player.throwSnowball(); exports.snowball = function(player){
} player.throwSnowball();
}
```
... is a plugin which provides 2 javascript functions called `egg()` ... is a plugin which provides 2 javascript functions called `egg()`
and `snowball()` which can be invoked from the in-game prompt like 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... Change the `greet()` function so that it looks like this...
exports.greet = function ( greeting , player) { ```javascript
player.sendMessage( greeting + player.name ); exports.greet = function ( greeting , player) {
} player.sendMessage( greeting + player.name );
}
```
... Save your greet.js file and issue the `/js refresh()` command in ... Save your greet.js file and issue the `/js refresh()` command in
minecraft. Now enter the following command in Minecraft... 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 on a single line at the in-game command prompt but the
statements could be written like this... statements could be written like this...
var players = server.onlinePlayers; ```javascript
for (var i = 0; i < players.length; i++) { var players = server.onlinePlayers;
var player = players[i]; var player;
player.sendMessage('Hi!'); 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 ... On the first line, a new variable `players` is created from the
server object's onlinePlayers property. `players` is more concise and server object's onlinePlayers property. `players` is more concise and
easier to type than the long-winded `server.onlinePlayers`. On the 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 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 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` 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 TextWrangler or your editor of choice) and add the following code at
the bottom of the file... the bottom of the file...
exports.hiAll = function (){ ```javascript
var players = server.onlinePlayers; exports.hiAll = function () {
for (var i = 0; i < players.length; i++) { var players = server.onlinePlayers,
var player = players[i]; player,
player.sendMessage('Hi!'); 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 ... 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 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` Another way to repeat things over and over is to use a `while`
loop. The following `while` loop counts to 100... loop. The following `while` loop counts to 100...
var i = 1; ```javascript
while (i <= 100){ var i = 1;
console.log( i ); while (i <= 100){
i = i + 1; console.log( i );
} i = i + 1;
}
```
A `while` loop will repeat until its condition is `false` - the 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 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 through arrays. The following loop prints out all of the players on
the server... the server...
var players = server.onlinePlayers; ```javascript
var i = 0; var players = server.onlinePlayers;
while ( i < players.length ) { var i = 0;
console.log( players[i] ); while ( i < players.length ) {
i = i + 1; console.log( players[i] );
} i = i + 1;
}
```
... whether you chose to use a `for` loop or a `while` loop is largely ... 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 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 you can also create new functions on-the-fly and pass them to the
utils.foreach() function... utils.foreach() function...
/* ```javascript
give every player the ability to fly. /*
*/ give every player the ability to fly.
var utils = require('utils'); */
utils.foreach( server.onlinePlayers, var utils = require('utils');
function (player) { utils.foreach( server.onlinePlayers, function( player ) {
player.setAllowFlight(true); player.setAllowFlight(true);
} } );
); ```
... Another example, this time each player will hear a Cat's Meow... ... Another example, this time each player will hear a Cat's Meow...
/* ```javascript
Play a Cat's Meow sound for each player. /*
*/ Play a Cat's Meow sound for each player.
var utils = require('utils'); */
utils.foreach( server.onlinePlayers, var utils = require('utils');
function (player) { utils.foreach( server.onlinePlayers, function( player ) {
player.playSound(player.location, player.playSound(player.location,
org.bukkit.Sound.CAT_MEOW, org.bukkit.Sound.CAT_MEOW,
1, 1,
1); 1);
} );
} ```
);
### Exercise ### Exercise
Try changing the above function so that different sounds are played 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 your scriptcraft/plugins/{your-name} directory, name the file `myskyscraper.js`, then
type the following... type the following...
var myskyscraper = function(floors) { ```javascript
if (typeof floors == 'undefined'){ var myskyscraper = function(floors) {
floors = 10; 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.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() this.box(blocks.iron,20,1,20)
.box0(blocks.glass_pane,20,3,20) .up()
.up(3); .box0(blocks.glass_pane,20,3,20)
} .up(3);
return this.move('myskyscraper'); // return to where we started }
}; return this.move('myskyscraper'); // return to where we started
};
var Drone = require('../drone/drone.js').Drone; var Drone = require('../drone/drone.js').Drone;
Drone.extend('myskyscraper',myskyscraper); Drone.extend('myskyscraper',myskyscraper);
```
... so this takes a little explaining. First I create a new function ... so this takes a little explaining. First I create a new function
called myskyscraper that will take a single parameter `floors` so that 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 Open your favorite editor and type the following code into a new file
in your scriptcraft/plugins directory... in your scriptcraft/plugins directory...
function flightStatus(player) ```javascript
{ function flightStatus( player ) {
if ( player.flying ) if ( player.flying ) {
{ player.sendMessage( 'Hey, You are flying!' );
player.sendMessage( 'Hey, You are flying!' ); } else {
} player.sendMessage( 'You are not flying.' );
else }
{ }
player.sendMessage( 'You are not flying.' ); ```
}
}
... now type `/reload` at the in-game prompt then type `/js ... now type `/reload` at the in-game prompt then type `/js
flightStatus(self)` and an appropriate message will appear based on 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 following code sends a message to any player who breaks a block in the
game... game...
events.on('block.BlockBreakEvent', function (listener, event) { ```javascript
var breaker = event.player; events.on('block.BlockBreakEvent', function ( listener, event ) {
breaker.sendMessage('You broke a block'); var breaker = event.player;
}); breaker.sendMessage('You broke a block');
} );
```
The `events.on()` function is how you *register* a function which you 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 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... If you want an event handler to only execute once, you can remove the handler like this...
events.on('block.BlockBreakEvent', function(listener, evt) { ```javascript
var breaker = evt.player; events.on('block.BlockBreakEvent', function( listener, evt ) {
breaker.sendMessage('You broke a block'); var breaker = evt.player;
evt.handlers.unregister( listener ); breaker.sendMessage('You broke a block');
}); evt.handlers.unregister( listener );
} );
```
The `evt.handlers.unregister( listener );` statement will remove this The `evt.handlers.unregister( listener );` statement will remove this
function from the list of listeners for this event. 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 score. In Javascript, an object which stored such a table would look
like this... like this...
var scoreboard = { ```javascript
walter: 5, var scoreboard = {
tom: 6, walter: 5,
jane: 8, tom: 6,
bart: 7 jane: 8,
}; bart: 7
};
```
... and if I wanted to write a function which took a player name as a ... 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... parameter and returned their score, I'd do it like this...
function getScore(player){ ```javascript
return scoreboard[ player ]; function getScore(player){
} return scoreboard[ player ];
}
```
... I might call such a function like this... ... 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 ... putting it all together, a hypothetical scoreboard.js mdoule might
look something like this... look something like this...
var utils = require('utils'); ```javascript
var scores = {}; var utils = require('utils');
var scores = {};
exports.initialise = function(names){ exports.initialise = function(names){
scores = {}; scores = {};
utils.foreach(names, function(name){ utils.foreach(names, function(name){
scores[name] = 0; scores[name] = 0;
}); });
}; };
/* changes score by diff e.g. to add 6 to the player's current score /* 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. updateScore('walter',6); // walter's new score = 5 + 6 = 11.
*/ */
exports.updateScore = function(name, diff){ exports.updateScore = function(name, diff){
scores[name] += diff; scores[name] += diff;
}; };
exports.getScore = function(name){ exports.getScore = function(name){
return scores[name]; return scores[name];
}; };
```
## Counting block break events for each player ## 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 #### block-break-counter.js
var breaks = {}; ```javascript
// every time a player joins the game reset their block-break-count to 0 var breaks = {};
events.on('player.PlayerJoinEvent', function(listener, event){ // every time a player joins the game reset their block-break-count to 0
breaks[event.player] = 0; events.on('player.PlayerJoinEvent', function(listener, event){
}); breaks[event.player] = 0;
events.on('block.BlockBreakEvent', function(listener, event){ });
var breaker = event.player; events.on('block.BlockBreakEvent', function(listener, event){
var breakCount = breaks[breaker.name]; var breaker = event.player;
breakCount++; // increment the count. var breakCount = breaks[breaker.name];
breaks[breaker.name] = breakCount; breakCount++; // increment the count.
breaks[breaker.name] = breakCount;
breaker.sendMessage('You broke ' + breakCount + ' blocks');
breaker.sendMessage('You broke ' + breakCount + ' blocks');
}); });
```
With a little more work, you could turn this into a game where players 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 compete against each other to break as many blocks as possible within

View file

@ -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... Once you've installed Notepad++, Launch it, create a new file and type the following...
exports.greet = function(player){ ```javascript
player.sendMessage('Hi ' + player.name); exports.greet = function( player ) {
} player.sendMessage('Hi ' + player.name);
}
```
... then save the file in a new directory ... then save the file in a new directory
`craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace `craftbukkit/plugins/scriptcraft/plugins/{your_name}` (replace
@ -479,12 +481,14 @@ one or more functions, objects or variables. For example...
#### thrower.js #### thrower.js
exports.egg = function(player){ ```javascript
player.throwEgg(); exports.egg = function(player){
} player.throwEgg();
exports.snowball = function(player){ }
player.throwSnowball(); exports.snowball = function(player){
} player.throwSnowball();
}
```
... is a plugin which provides 2 javascript functions called `egg()` ... is a plugin which provides 2 javascript functions called `egg()`
and `snowball()` which can be invoked from the in-game prompt like 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... Change the `greet()` function so that it looks like this...
exports.greet = function ( greeting , player) { ```javascript
player.sendMessage( greeting + player.name ); exports.greet = function ( greeting , player) {
} player.sendMessage( greeting + player.name );
}
```
... Save your greet.js file and issue the `/js refresh()` command in ... Save your greet.js file and issue the `/js refresh()` command in
minecraft. Now enter the following command in Minecraft... 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 on a single line at the in-game command prompt but the
statements could be written like this... statements could be written like this...
var players = server.onlinePlayers; ```javascript
for (var i = 0; i < players.length; i++) { var players = server.onlinePlayers;
var player = players[i]; var player;
player.sendMessage('Hi!'); 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 ... On the first line, a new variable `players` is created from the
server object's onlinePlayers property. `players` is more concise and server object's onlinePlayers property. `players` is more concise and
easier to type than the long-winded `server.onlinePlayers`. On the 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 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 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` 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 TextWrangler or your editor of choice) and add the following code at
the bottom of the file... the bottom of the file...
exports.hiAll = function (){ ```javascript
var players = server.onlinePlayers; exports.hiAll = function () {
for (var i = 0; i < players.length; i++) { var players = server.onlinePlayers,
var player = players[i]; player,
player.sendMessage('Hi!'); 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 ... 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 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` Another way to repeat things over and over is to use a `while`
loop. The following `while` loop counts to 100... loop. The following `while` loop counts to 100...
var i = 1; ```javascript
while (i <= 100){ var i = 1;
console.log( i ); while (i <= 100){
i = i + 1; console.log( i );
} i = i + 1;
}
```
A `while` loop will repeat until its condition is `false` - the 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 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 through arrays. The following loop prints out all of the players on
the server... the server...
var players = server.onlinePlayers; ```javascript
var i = 0; var players = server.onlinePlayers;
while ( i < players.length ) { var i = 0;
console.log( players[i] ); while ( i < players.length ) {
i = i + 1; console.log( players[i] );
} i = i + 1;
}
```
... whether you chose to use a `for` loop or a `while` loop is largely ... 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 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 you can also create new functions on-the-fly and pass them to the
utils.foreach() function... utils.foreach() function...
/* ```javascript
give every player the ability to fly. /*
*/ give every player the ability to fly.
var utils = require('utils'); */
utils.foreach( server.onlinePlayers, var utils = require('utils');
function (player) { utils.foreach( server.onlinePlayers, function( player ) {
player.setAllowFlight(true); player.setAllowFlight(true);
} } );
); ```
... Another example, this time each player will hear a Cat's Meow... ... Another example, this time each player will hear a Cat's Meow...
/* ```javascript
Play a Cat's Meow sound for each player. /*
*/ Play a Cat's Meow sound for each player.
var utils = require('utils'); */
utils.foreach( server.onlinePlayers, var utils = require('utils');
function (player) { utils.foreach( server.onlinePlayers, function( player ) {
player.playSound(player.location, player.playSound(player.location,
org.bukkit.Sound.CAT_MEOW, org.bukkit.Sound.CAT_MEOW,
1, 1,
1); 1);
} );
} ```
);
### Exercise ### Exercise
Try changing the above function so that different sounds are played 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 your scriptcraft/plugins/{your-name} directory, name the file `myskyscraper.js`, then
type the following... type the following...
var myskyscraper = function(floors) { ```javascript
if (typeof floors == 'undefined'){ var myskyscraper = function(floors) {
floors = 10; 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.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() this.box(blocks.iron,20,1,20)
.box0(blocks.glass_pane,20,3,20) .up()
.up(3); .box0(blocks.glass_pane,20,3,20)
} .up(3);
return this.move('myskyscraper'); // return to where we started }
}; return this.move('myskyscraper'); // return to where we started
};
var Drone = require('../drone/drone.js').Drone; var Drone = require('../drone/drone.js').Drone;
Drone.extend('myskyscraper',myskyscraper); Drone.extend('myskyscraper',myskyscraper);
```
... so this takes a little explaining. First I create a new function ... so this takes a little explaining. First I create a new function
called myskyscraper that will take a single parameter `floors` so that 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 Open your favorite editor and type the following code into a new file
in your scriptcraft/plugins directory... in your scriptcraft/plugins directory...
function flightStatus(player) ```javascript
{ function flightStatus( player ) {
if ( player.flying ) if ( player.flying ) {
{ player.sendMessage( 'Hey, You are flying!' );
player.sendMessage( 'Hey, You are flying!' ); } else {
} player.sendMessage( 'You are not flying.' );
else }
{ }
player.sendMessage( 'You are not flying.' ); ```
}
}
... now type `/reload` at the in-game prompt then type `/js ... now type `/reload` at the in-game prompt then type `/js
flightStatus(self)` and an appropriate message will appear based on 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 following code sends a message to any player who breaks a block in the
game... game...
events.on('block.BlockBreakEvent', function (listener, event) { ```javascript
var breaker = event.player; events.on('block.BlockBreakEvent', function ( listener, event ) {
breaker.sendMessage('You broke a block'); var breaker = event.player;
}); breaker.sendMessage('You broke a block');
} );
```
The `events.on()` function is how you *register* a function which you 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 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... If you want an event handler to only execute once, you can remove the handler like this...
events.on('block.BlockBreakEvent', function(listener, evt) { ```javascript
var breaker = evt.player; events.on('block.BlockBreakEvent', function( listener, evt ) {
breaker.sendMessage('You broke a block'); var breaker = evt.player;
evt.handlers.unregister( listener ); breaker.sendMessage('You broke a block');
}); evt.handlers.unregister( listener );
} );
```
The `evt.handlers.unregister( listener );` statement will remove this The `evt.handlers.unregister( listener );` statement will remove this
function from the list of listeners for this event. 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 score. In Javascript, an object which stored such a table would look
like this... like this...
var scoreboard = { ```javascript
walter: 5, var scoreboard = {
tom: 6, walter: 5,
jane: 8, tom: 6,
bart: 7 jane: 8,
}; bart: 7
};
```
... and if I wanted to write a function which took a player name as a ... 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... parameter and returned their score, I'd do it like this...
function getScore(player){ ```javascript
return scoreboard[ player ]; function getScore(player){
} return scoreboard[ player ];
}
```
... I might call such a function like this... ... 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 ... putting it all together, a hypothetical scoreboard.js mdoule might
look something like this... look something like this...
var utils = require('utils'); ```javascript
var scores = {}; var utils = require('utils');
var scores = {};
exports.initialise = function(names){ exports.initialise = function(names){
scores = {}; scores = {};
utils.foreach(names, function(name){ utils.foreach(names, function(name){
scores[name] = 0; scores[name] = 0;
}); });
}; };
/* changes score by diff e.g. to add 6 to the player's current score /* 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. updateScore('walter',6); // walter's new score = 5 + 6 = 11.
*/ */
exports.updateScore = function(name, diff){ exports.updateScore = function(name, diff){
scores[name] += diff; scores[name] += diff;
}; };
exports.getScore = function(name){ exports.getScore = function(name){
return scores[name]; return scores[name];
}; };
```
## Counting block break events for each player ## 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 #### block-break-counter.js
var breaks = {}; ```javascript
// every time a player joins the game reset their block-break-count to 0 var breaks = {};
events.on('player.PlayerJoinEvent', function(listener, event){ // every time a player joins the game reset their block-break-count to 0
breaks[event.player] = 0; events.on('player.PlayerJoinEvent', function(listener, event){
}); breaks[event.player] = 0;
events.on('block.BlockBreakEvent', function(listener, event){ });
var breaker = event.player; events.on('block.BlockBreakEvent', function(listener, event){
var breakCount = breaks[breaker.name]; var breaker = event.player;
breakCount++; // increment the count. var breakCount = breaks[breaker.name];
breaks[breaker.name] = breakCount; breakCount++; // increment the count.
breaks[breaker.name] = breakCount;
breaker.sendMessage('You broke ' + breakCount + ' blocks');
breaker.sendMessage('You broke ' + breakCount + ' blocks');
}); });
```
With a little more work, you could turn this into a game where players 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 compete against each other to break as many blocks as possible within

View file

@ -18,23 +18,29 @@ For example imagine you have 3 files program.js, inc.js and math.js ...
### math.js ### math.js
exports.add = function(a,b){ ```javascript
return a + b; exports.add = function(a,b){
} return a + b;
}
```
### inc.js ### inc.js
var math = require('./math'); ```javascript
exports.increment = function(n){ var math = require('./math');
return math.add(n, 1); exports.increment = function(n){
} return math.add(n, 1);
}
```
### program.js ### program.js
var inc = require('./inc').increment; ```javascript
var a = 7; var inc = require('./inc').increment;
a = inc(a); var a = 7;
print(a); a = inc(a);
print(a);
```
You can see from the above sample code that programs can use modules You can see from the above sample code that programs can use modules
and modules themeselves can use other modules. Modules have full and modules themeselves can use other modules. Modules have full

View file

@ -12,21 +12,23 @@ loads the module circle.js in the same directory.
The contents of foo.js: The contents of foo.js:
var circle = require('./circle.js'); ```javascript
console.log( 'The area of a circle of radius 4 is ' var circle = require('./circle.js');
+ circle.area(4)); console.log( 'The area of a circle of radius 4 is '
+ circle.area(4));
```
The contents of circle.js: The contents of circle.js:
var PI = Math.PI; ```javascript
var PI = Math.PI;
exports.area = function (r) { exports.area = function (r) {
return PI * r * r; return PI * r * r;
}; };
exports.circumference = function (r) {
exports.circumference = function (r) { return 2 * PI * r;
return 2 * PI * r; };
}; ```
The module circle.js has exported the functions area() and The module circle.js has exported the functions area() and
circumference(). To add functions and objects to the root of your 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 variable. For example, if you have a module greeting.js in the plugins
directory.... directory....
exports.greet = function(player) { ```javascript
player.sendMessage('Hello ' + player.name); exports.greet = function(player) {
}; player.sendMessage('Hello ' + player.name);
};
```
... then `greet` becomes a global function and can be used at the ... then `greet` becomes a global function and can be used at the
in-game (or server) command prompt like so... in-game (or server) command prompt like so...
@ -256,10 +260,12 @@ restored using the `scload()` function.
#### Example #### Example
var myObject = { name: 'John Doe', ```javascript
aliases: ['John Ray', 'John Mee'], var myObject = { name: 'John Doe',
date_of_birth: '1982/01/31' }; aliases: ['John Ray', 'John Mee'],
scsave(myObject, 'johndoe.json'); date_of_birth: '1982/01/31' };
scsave(myObject, 'johndoe.json');
```
##### johndoe.json contents... ##### johndoe.json contents...
@ -346,13 +352,15 @@ If Node.js supports setTimeout() then it's probably good for ScriptCraft to supp
#### Example #### Example
// ```javascript
// start a storm in 5 seconds //
// // start a storm in 5 seconds
setTimeout( function() { //
var world = server.worlds.get(0); setTimeout( function() {
world.setStorm(true); var world = server.worlds.get(0);
}, 5000); world.setStorm(true);
}, 5000);
```
### clearTimeout() function ### clearTimeout() function
@ -477,7 +485,6 @@ function __onEnable ( __engine, __plugin, __script )
var canonizedFilename = _canonize( file ); var canonizedFilename = _canonize( file );
if ( file.exists() ) { if ( file.exists() ) {
parent = file.getParentFile();
reader = new FileReader( file ); reader = new FileReader( file );
br = new BufferedReader( reader ); br = new BufferedReader( reader );
code = ''; code = '';

View file

@ -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 craftbukkit-sc-mqtt.bat and edit it to include the following
command... 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 If you're using Mac OS, create a new craftbukkit-sc-mqtt.command
file and edit it (using TextWrangler or another text editor) ... 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 4. Execute the craftbukkit-sc-mqtt batch file / command file to start
Craftbukkit. You can now begin using this module to send and receive 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 messages to/from a Net-enabled Arduino or any other device which uses
the [MQTT protocol][mqtt] the [MQTT protocol][mqtt]
var mqtt = require('sc-mqtt'); ```javascript
// create a new client var mqtt = require('sc-mqtt');
var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); // create a new client
// connect to the broker var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' );
client.connect( { keepAliveInterval: 15 } ); // connect to the broker
// publish a message to the broker client.connect( { keepAliveInterval: 15 } );
client.publish( 'minecraft', 'loaded' ); // publish a message to the broker
// subscribe to messages on 'arduino' topic client.publish( 'minecraft', 'loaded' );
client.subscribe( 'arduino' ); // subscribe to messages on 'arduino' topic
// do something when an incoming message arrives... client.subscribe( 'arduino' );
client.onMessageArrived( function( topic, message ) { // do something when an incoming message arrives...
console.log( 'Message arrived: topic=' + topic + ', message=' + message ); 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 The `sc-mqtt` module provides a very simple minimal wrapper around the
[Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT [Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT

View file

@ -22,14 +22,16 @@ String, then it tries to find the player with that name.
#### Example #### Example
var utils = require('utils'); ```javascript
var name = 'walterh'; var utils = require('utils');
var player = utils.player(name); var name = 'walterh';
if (player) { var player = utils.player(name);
player.sendMessage('Got ' + name); if ( player ) {
}else{ player.sendMessage('Got ' + name);
console.log('No player named ' + name); } else {
} console.log('No player named ' + name);
}
```
[bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html [bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.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. keys in a lookup table.
#### Example #### Example
var utils = require('utils'); ```javascript
... var utils = require('utils');
var key = utils.locationToString(player.location); ...
lookupTable[key] = player.name; var key = utils.locationToString(player.location);
lookupTable[key] = player.name;
```
***/ ***/
exports.locationToString = function( location ) { 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... The following code will strike lightning at the location the player is looking at...
var utils = require('utils'); ```javascript
var playerName = 'walterh'; var utils = require('utils');
var targetPos = utils.getMousePos(playerName); var playerName = 'walterh';
if (targetPos){ var targetPos = utils.getMousePos(playerName);
targetPos.world.strikeLightning(targetPos); if (targetPos){
} targetPos.world.strikeLightning(targetPos);
}
```
***/ ***/
exports.getMousePos = function( player ) { 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... The following example illustrates how to use foreach for immediate processing of an array...
var utils = require('utils'); ```javascript
var players = ['moe', 'larry', 'curly']; var utils = require('utils');
utils.foreach (players, function(item){ var players = ['moe', 'larry', 'curly'];
server.getPlayer(item).sendMessage('Hi ' + item); 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 ... 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... because many objects in the Bukkit API use Java-style collections...
utils.foreach( server.onlinePlayers, function(player){ ```javascript
player.chat('Hello!'); utils.foreach( server.onlinePlayers, function(player){
}); player.chat('Hello!');
});
```
... the above code sends a 'Hello!' to every online player. ... 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 The following example is a more complex use case - The need to build an enormous structure
without hogging CPU usage... without hogging CPU usage...
// build a structure 200 wide x 200 tall x 200 long ```javascript
// (That's 8 Million Blocks - enough to tax any machine!) // build a structure 200 wide x 200 tall x 200 long
var utils = require('utils'); // (That's 8 Million Blocks - enough to tax any machine!)
var utils = require('utils');
var a = []; var a = [];
a.length = 200; a.length = 200;
var drone = new Drone(); var drone = new Drone();
var processItem = function(item, index, object, array){ var processItem = function(item, index, object, array){
// build a box 200 wide by 200 long then move up // build a box 200 wide by 200 long then move up
drone.box(blocks.wood, 200, 1, 200).up(); drone.box(blocks.wood, 200, 1, 200).up();
}; };
// by the time the job's done 'self' might be someone else // by the time the job's done 'self' might be someone else
// assume this code is within a function/closure // assume this code is within a function/closure
var player = self; var player = self;
var onDone = function(){ var onDone = function(){
player.sendMessage('Job Done!'); player.sendMessage('Job Done!');
}; };
utils.foreach (a, processItem, null, 10, onDone); utils.foreach (a, processItem, null, 10, onDone);
```
***/ ***/
var _foreach = function( array, callback, context, delay, onCompletion ) { 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... 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!' ); player.chat( 'The night is dark and full of terrors!' );
});
}); });
});
```
***/ ***/
exports.at = function( time24hr, callback, worlds ) { exports.at = function( time24hr, callback, worlds ) {
@ -415,10 +429,12 @@ a given directory and recursiving trawling all sub-directories.
#### Example #### Example
var utils = require('utils'); ```javascript
var jsFiles = utils.find('./', function(dir,name){ var utils = require('utils');
return name.match(/\.js$/); var jsFiles = utils.find('./', function(dir,name){
}); return name.match(/\.js$/);
});
```
***/ ***/
exports.find = function( dir , filter ) { exports.find = function( dir , filter ) {