Fixes issue #203

This commit is contained in:
walterhiggins 2015-01-17 08:45:32 +00:00
parent 8d09984df7
commit e95c9596a2
5 changed files with 151 additions and 245 deletions

View file

@ -4828,9 +4828,9 @@ miscellaneous utility functions and classes to help with programming.
### utils.player() function ### utils.player() function
The utils.player() function will return a [bukkit Player][bkpl] object The utils.player() function will return a [Player][cmpl] object
with the given name. This function takes a single parameter with the given name. This function takes a single parameter
`playerName` which can be either a String or a [Player][bkpl] object - `playerName` which can be either a String or a [Player][cmpl] object -
if it's a Player object, then the same object is returned. If it's a if it's a Player object, then the same object is returned. If it's a
String, then it tries to find the player with that name. String, then it tries to find the player with that name.
@ -4847,13 +4847,15 @@ var utils = require('utils');
var name = 'walterh'; var name = 'walterh';
var player = utils.player(name); var player = utils.player(name);
if ( player ) { if ( player ) {
echo(player, 'Got ' + name); echo(player, 'Got ' + name);
} else { } else {
console.log('No player named ' + name); 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
[cmpl]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/entity/living/humanoid/Player.html
[cmloc]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/world/position/Location.html
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html [bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html
### utils.world( worldName ) function ### utils.world( worldName ) function
@ -4866,7 +4868,7 @@ Returns the Block at the given location.
### utils.locationToJSON() function ### utils.locationToJSON() function
utils.locationToJSON() returns a [org.bukkit.Location][bkloc] object in JSON form... utils.locationToJSON() returns a [Location][cmloc] object in JSON form...
{ world: 'world5', { world: 'world5',
x: 56.9324, x: 56.9324,
@ -4880,7 +4882,7 @@ This can be useful if you write a plugin that needs to store location data since
#### Parameters #### Parameters
* location: An object of type [org.bukkit.Location][bkloc] * location: An object of type [Location][cmloc]
#### Returns #### Returns
@ -4889,7 +4891,7 @@ A JSON object in the above form.
### utils.locationToString() function ### utils.locationToString() function
The utils.locationToString() function returns a The utils.locationToString() function returns a
[org.bukkit.Location][bkloc] object in string form... [Location][cmloc] object in string form...
'{"world":"world5",x:56.9324,y:103.9954,z:43.1323,yaw:0.0,pitch:0.0}' '{"world":"world5",x:56.9324,y:103.9954,z:43.1323,yaw:0.0,pitch:0.0}'
@ -4907,7 +4909,7 @@ lookupTable[key] = player.name;
### utils.locationFromJSON() function ### utils.locationFromJSON() function
This function reconstructs an [org.bukkit.Location][bkloc] object from This function reconstructs an [Location][cmloc] object from
a JSON representation. This is the counterpart to the a JSON representation. This is the counterpart to the
`locationToJSON()` function. It takes a JSON object of the form `locationToJSON()` function. It takes a JSON object of the form
returned by locationToJSON() and reconstructs and returns a bukkit returned by locationToJSON() and reconstructs and returns a bukkit
@ -4915,7 +4917,7 @@ Location object.
### utils.getPlayerPos() function ### utils.getPlayerPos() function
This function returns the player's [Location][bkloc] (x, y, z, pitch This function returns the player's [Location][cmloc] (x, y, z, pitch
and yaw) for a named player. If the "player" is in fact a and yaw) for a named player. If the "player" is in fact a
[org.bukkit.command.BlockCommandSender][bkbcs] then the attached [org.bukkit.command.BlockCommandSender][bkbcs] then the attached
Block's location is returned. Block's location is returned.
@ -4926,13 +4928,13 @@ Block's location is returned.
#### Returns #### Returns
An [org.bukkit.Location][bkloc] object. A [Location][cmloc] object.
[bkbcs]: http://jd.bukkit.org/dev/apidocs/org/bukkit/command/BlockCommandSender.html [bkbcs]: http://jd.bukkit.org/dev/apidocs/org/bukkit/command/BlockCommandSender.html
[bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html [bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html
### utils.getMousePos() function ### utils.getMousePos() function
This function returns a [org.bukkit.Location][bkloc] object (the This function returns a [Location][cmloc] object (the
x,y,z) of the current block being targeted by the named player. This x,y,z) of the current block being targeted by the named player. This
is the location of the block the player is looking at (targeting). is the location of the block the player is looking at (targeting).
@ -4949,21 +4951,27 @@ var utils = require('utils');
var playerName = 'walterh'; var playerName = 'walterh';
var targetPos = utils.getMousePos(playerName); var targetPos = utils.getMousePos(playerName);
if (targetPos){ if (targetPos){
targetPos.world.strikeLightning(targetPos); if (__plugin.canary){
targetPos.world.makeLightningBolt(targetPos);
}
if (__plugin.bukkit){
targetPos.world.strikeLightning(targetPos);
}
} }
``` ```
### utils.foreach() function ### utils.foreach() function
The utils.foreach() function is a utility function for iterating over The utils.foreach() function is a utility function for iterating over
an array of objects (or a java.util.Collection of objects) and processing each object in turn. Where an array of objects (or a java.util.Collection of objects) and
utils.foreach() differs from other similar functions found in processing each object in turn. Where utils.foreach() differs from
javascript libraries, is that utils.foreach can process the array other similar functions found in javascript libraries, is that
immediately or can process it *nicely* by processing one item at a utils.foreach can process the array immediately or can process it
time then delaying processing of the next item for a given number of *nicely* by processing one item at a time then delaying processing of
server ticks (there are 20 ticks per second on the minecraft main the next item for a given number of server ticks (there are 20 ticks
thread). This method relies on Bukkit's [org.bukkit.scheduler][sched] per second on the minecraft main thread). This method relies on
package for scheduling processing of arrays. Bukkit's [org.bukkit.scheduler][sched] package for scheduling
processing of arrays.
[sched]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scheduler/package-summary.html [sched]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scheduler/package-summary.html
@ -4981,11 +4989,9 @@ package for scheduling processing of arrays.
- array : The entire array. - array : The entire array.
* context (optional) : An object which may be used by the callback. * context (optional) : An object which may be used by the callback.
* delay (optional, numeric) : If a delay is specified (in ticks - 20 * delayInMilliseconds (optional, numeric) : If a delay is specified then the processing will be scheduled so that
ticks = 1 second), then the processing will be scheduled so that
each item will be processed in turn with a delay between the completion of each each item will be processed in turn with a delay between the completion of each
item and the start of the next. This is recommended for big builds (say 200 x 200 x 200 item and the start of the next. This is recommended for any CPU-intensive process.
blocks) or any CPU-intensive process.
* onDone (optional, function) : A function to be executed when all processing * onDone (optional, function) : A function to be executed when all processing
is complete. This parameter is only used when the processing is delayed. (It's optional even if a is complete. This parameter is only used when the processing is delayed. (It's optional even if a
delay parameter is supplied). delay parameter is supplied).
@ -5002,51 +5008,27 @@ The following example illustrates how to use foreach for immediate processing of
```javascript ```javascript
var utils = require('utils'); var utils = require('utils');
var players = ['moe', 'larry', 'curly']; var players = utils.players();
utils.foreach (players, function(item){ utils.foreach (players, function( player ) {
echo( server.getPlayer(item), 'Hi ' + item); echo( player , 'Hi ' + player);
}); });
``` ```
... 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
because many objects in the Bukkit API use Java-style collections... Java-style collection. This is important because many objects in the
CanaryMod and Bukkit APIs use Java-style collections...
```javascript ```javascript
// in bukkit, server.onlinePlayers returns a java.util.Collection object
utils.foreach( server.onlinePlayers, function(player){ utils.foreach( server.onlinePlayers, function(player){
player.chat('Hello!'); 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
without hogging CPU usage...
```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(){
echo( player, 'Job Done!');
};
utils.foreach (a, processItem, null, 10, onDone);
```
### utils.nicely() function ### utils.nicely() function
The utils.nicely() function is for performing processing using the The utils.nicely() function is for performing background processing. utils.nicely() lets you
[org.bukkit.scheduler][sched] package/API. utils.nicely() lets you
process with a specified delay between the completion of each `next()` process with a specified delay between the completion of each `next()`
function and the start of the next `next()` function. function and the start of the next `next()` function.
`utils.nicely()` is a recursive function - that is - it calls itself `utils.nicely()` is a recursive function - that is - it calls itself
@ -5060,7 +5042,7 @@ function and the start of the next `next()` function.
true if the `next` function should be called (processing is not true if the `next` function should be called (processing is not
complete), false otherwise. complete), false otherwise.
* onDone : A function which is to be called when all processing is complete (hasNext returned false). * onDone : A function which is to be called when all processing is complete (hasNext returned false).
* delay : The delay (in server ticks - 20 per second) between each call. * delayInMilliseconds : The delay between each call.
#### Example #### Example
@ -5087,9 +5069,9 @@ var utils = require('utils');
utils.at( '19:00', function() { utils.at( '19:00', function() {
utils.foreach( server.onlinePlayers, function( player ) { utils.players(function( player ) {
player.chat( 'The night is dark and full of terrors!' ); echo( player, 'The night is dark and full of terrors!' );
}); });
}); });
``` ```
@ -5485,78 +5467,46 @@ following reasons...
`/scriptcraft/plugins` directory, it will be loaded automatically `/scriptcraft/plugins` directory, it will be loaded automatically
when the server starts up. when the server starts up.
2. It uses ScriptCraft's `events.on()` function to add a new *Event 2. It uses ScriptCraft's `events` module to add a new *Event
Handler*. An *Event Handler* is a just a function which gets Handler*. An *Event Handler* is a function that gets
called whenever a particular *event* happens in the game. The called whenever a particular *event* happens in the game. The
function defined below will only be executed whenever a player function defined below will only be executed whenever a player
joins the game. This style of program is sometimes refered to as joins the game. This style of program is sometimes refered to as
*Event-Driven Programming*. *Event-Driven Programming*.
Adding new *Event Handlers* in ScriptCraft is relatively easy. Use the Adding new *Event Handlers* in ScriptCraft is relatively easy. Use one
`events.on()` function to add a new event handler. It takes 2 of the `events` module's functions to add a new event handler. The
parameters... events module has many functions - one for each type of event. Each
function takes a single parameter:
1. The Event Name, in this case `'player.PlayerJoinEvent'`. You can * The event handling function (also sometimes refered to as a
browse [all possible Bukkit events][bkevts] (click the 'Next 'callback'). In ScriptCraft, this function takes a single
Package' and 'Previous Package' links to browse). parameter, an event object. All of the information about the event
is in the event object.
2. The event handling function (also sometimes refered to as a
'callback'). In ScriptCraft, this function takes a single
parameter, an event object. All of the information about the event
is in the event object.
In the example below, if a player joins the server and is an operator, In the example below, if a player joins the server and is an operator,
then the ScriptCraft plugin information will be displayed to that then the ScriptCraft plugin information will be displayed to that
player. player.
What's also notable about this example is how it uses the `isOp()` function. The code... ```javascript
function onJoin( event ){
if ( isOp(event.player) ) {
echo( event.player, 'Welcome to ' + __plugin );
}
}
events.connection( onJoin );
```
First the onJoin() function is defined, this is our event handler -
the function we wish to be called every time some new player joins the
game. Then we hook up - or register - that function using the
events.connection() function. The events.connection function is the
function responsible for adding new *connection* event handlers - that
is - functions which should be invoked when there's a new *connection*
event in the game. A new *connection* event is fired whenever a player
joins the game. There are many other types of events you can handle in
Minecraft. You can see [a full list of events here][cmEvtList].
if ( isOp(event.player) ) [cmEvtList]: #events-helper-module-canary-version
ScriptCraft uses a special version of JavaScript which comes
bundled with Java (Minecraft is written in Java) and JavaScript in
Java can access properties of Java objects more succinctly than in
Java itself. What this means in practice is that when you're perusing
the [Bukkit API Reference][bkapi] and come across a method like
[Player.getAllowFlight()][bkgaf], you can write code like this...
var allowFlight = player.getAllowFlight(); // java style
... or the more succinct ...
var allowFlight = player.allowFlight; // javascript style
... Which style you choose is up to you but `player.allowFlight` is
cleaner and more readable. Similarly where you see a method like
[Player.setAllowFlight()][bksaf], you can write ...
player.setAllowFlight(true); // java style
... or the more readable...
player.allowFlight = true; // javascript style
... Which style you choose is up to you.
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
[bkgaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#getAllowFlight()
[bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight()
[bkapi]: http://jd.bukkit.org/dev/apidocs/
events.on( 'player.PlayerJoinEvent', function( event ) {
if ( isOp(event.player) ) {
echo( event.player, 'Welcome to ' + __plugin);
}
});
Update: Since version 2.0.8 the above code can be replaced by the more succinct:
events.playerJoin( function( event ) {
if ( event.player.op ) {
echo( event.player, 'Welcome to ' + __plugin);
}
});
## Arrows Plugin ## Arrows Plugin
The arrows mod adds fancy arrows to the game. Arrows which... The arrows mod adds fancy arrows to the game. Arrows which...

View file

@ -1,3 +1,5 @@
'use strict';
/*global __plugin, module, server*/
function bukkitSetTimeout( callback, delayInMillis ){ function bukkitSetTimeout( callback, delayInMillis ){
var delay = Math.ceil( delayInMillis / 50 ); var delay = Math.ceil( delayInMillis / 50 );
var task = server.scheduler.runTaskLater( __plugin, callback, delay ); var task = server.scheduler.runTaskLater( __plugin, callback, delay );

View file

@ -1,3 +1,5 @@
'use strict';
/*global Packages, __plugin, module*/
/* /*
javascript programmers familiar with setTimeout know that it expects javascript programmers familiar with setTimeout know that it expects
a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks

View file

@ -1,4 +1,4 @@
/*global __plugin, org, exports, server*/ /*global __plugin, org, exports, server, setTimeout, Packages*/
'use strict'; 'use strict';
var File = java.io.File; var File = java.io.File;
@ -19,9 +19,9 @@ miscellaneous utility functions and classes to help with programming.
### utils.player() function ### utils.player() function
The utils.player() function will return a [bukkit Player][bkpl] object The utils.player() function will return a [Player][cmpl] object
with the given name. This function takes a single parameter with the given name. This function takes a single parameter
`playerName` which can be either a String or a [Player][bkpl] object - `playerName` which can be either a String or a [Player][cmpl] object -
if it's a Player object, then the same object is returned. If it's a if it's a Player object, then the same object is returned. If it's a
String, then it tries to find the player with that name. String, then it tries to find the player with that name.
@ -38,13 +38,15 @@ var utils = require('utils');
var name = 'walterh'; var name = 'walterh';
var player = utils.player(name); var player = utils.player(name);
if ( player ) { if ( player ) {
echo(player, 'Got ' + name); echo(player, 'Got ' + name);
} else { } else {
console.log('No player named ' + name); 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
[cmpl]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/entity/living/humanoid/Player.html
[cmloc]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/world/position/Location.html
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html [bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html
***/ ***/
@ -106,7 +108,7 @@ exports.blockAt = _blockAt;
/************************************************************************* /*************************************************************************
### utils.locationToJSON() function ### utils.locationToJSON() function
utils.locationToJSON() returns a [org.bukkit.Location][bkloc] object in JSON form... utils.locationToJSON() returns a [Location][cmloc] object in JSON form...
{ world: 'world5', { world: 'world5',
x: 56.9324, x: 56.9324,
@ -120,7 +122,7 @@ This can be useful if you write a plugin that needs to store location data since
#### Parameters #### Parameters
* location: An object of type [org.bukkit.Location][bkloc] * location: An object of type [Location][cmloc]
#### Returns #### Returns
@ -141,7 +143,7 @@ var _locationToJSON = function( location ) {
### utils.locationToString() function ### utils.locationToString() function
The utils.locationToString() function returns a The utils.locationToString() function returns a
[org.bukkit.Location][bkloc] object in string form... [Location][cmloc] object in string form...
'{"world":"world5",x:56.9324,y:103.9954,z:43.1323,yaw:0.0,pitch:0.0}' '{"world":"world5",x:56.9324,y:103.9954,z:43.1323,yaw:0.0,pitch:0.0}'
@ -166,7 +168,7 @@ exports.locationToJSON = _locationToJSON;
/************************************************************************* /*************************************************************************
### utils.locationFromJSON() function ### utils.locationFromJSON() function
This function reconstructs an [org.bukkit.Location][bkloc] object from This function reconstructs an [Location][cmloc] object from
a JSON representation. This is the counterpart to the a JSON representation. This is the counterpart to the
`locationToJSON()` function. It takes a JSON object of the form `locationToJSON()` function. It takes a JSON object of the form
returned by locationToJSON() and reconstructs and returns a bukkit returned by locationToJSON() and reconstructs and returns a bukkit
@ -200,7 +202,7 @@ exports.getPlayerObject = function( player ) {
/************************************************************************* /*************************************************************************
### utils.getPlayerPos() function ### utils.getPlayerPos() function
This function returns the player's [Location][bkloc] (x, y, z, pitch This function returns the player's [Location][cmloc] (x, y, z, pitch
and yaw) for a named player. If the "player" is in fact a and yaw) for a named player. If the "player" is in fact a
[org.bukkit.command.BlockCommandSender][bkbcs] then the attached [org.bukkit.command.BlockCommandSender][bkbcs] then the attached
Block's location is returned. Block's location is returned.
@ -211,7 +213,7 @@ Block's location is returned.
#### Returns #### Returns
An [org.bukkit.Location][bkloc] object. A [Location][cmloc] object.
[bkbcs]: http://jd.bukkit.org/dev/apidocs/org/bukkit/command/BlockCommandSender.html [bkbcs]: http://jd.bukkit.org/dev/apidocs/org/bukkit/command/BlockCommandSender.html
[bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html [bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html
@ -229,7 +231,7 @@ exports.getPlayerPos = function( player ) {
/************************************************************************ /************************************************************************
### utils.getMousePos() function ### utils.getMousePos() function
This function returns a [org.bukkit.Location][bkloc] object (the This function returns a [Location][cmloc] object (the
x,y,z) of the current block being targeted by the named player. This x,y,z) of the current block being targeted by the named player. This
is the location of the block the player is looking at (targeting). is the location of the block the player is looking at (targeting).
@ -246,7 +248,12 @@ var utils = require('utils');
var playerName = 'walterh'; var playerName = 'walterh';
var targetPos = utils.getMousePos(playerName); var targetPos = utils.getMousePos(playerName);
if (targetPos){ if (targetPos){
targetPos.world.strikeLightning(targetPos); if (__plugin.canary){
targetPos.world.makeLightningBolt(targetPos);
}
if (__plugin.bukkit){
targetPos.world.strikeLightning(targetPos);
}
} }
``` ```
@ -281,14 +288,15 @@ exports.getMousePos = function( player ) {
### utils.foreach() function ### utils.foreach() function
The utils.foreach() function is a utility function for iterating over The utils.foreach() function is a utility function for iterating over
an array of objects (or a java.util.Collection of objects) and processing each object in turn. Where an array of objects (or a java.util.Collection of objects) and
utils.foreach() differs from other similar functions found in processing each object in turn. Where utils.foreach() differs from
javascript libraries, is that utils.foreach can process the array other similar functions found in javascript libraries, is that
immediately or can process it *nicely* by processing one item at a utils.foreach can process the array immediately or can process it
time then delaying processing of the next item for a given number of *nicely* by processing one item at a time then delaying processing of
server ticks (there are 20 ticks per second on the minecraft main the next item for a given number of server ticks (there are 20 ticks
thread). This method relies on Bukkit's [org.bukkit.scheduler][sched] per second on the minecraft main thread). This method relies on
package for scheduling processing of arrays. Bukkit's [org.bukkit.scheduler][sched] package for scheduling
processing of arrays.
[sched]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scheduler/package-summary.html [sched]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scheduler/package-summary.html
@ -306,11 +314,9 @@ package for scheduling processing of arrays.
- array : The entire array. - array : The entire array.
* context (optional) : An object which may be used by the callback. * context (optional) : An object which may be used by the callback.
* delay (optional, numeric) : If a delay is specified (in ticks - 20 * delayInMilliseconds (optional, numeric) : If a delay is specified then the processing will be scheduled so that
ticks = 1 second), then the processing will be scheduled so that
each item will be processed in turn with a delay between the completion of each each item will be processed in turn with a delay between the completion of each
item and the start of the next. This is recommended for big builds (say 200 x 200 x 200 item and the start of the next. This is recommended for any CPU-intensive process.
blocks) or any CPU-intensive process.
* onDone (optional, function) : A function to be executed when all processing * onDone (optional, function) : A function to be executed when all processing
is complete. This parameter is only used when the processing is delayed. (It's optional even if a is complete. This parameter is only used when the processing is delayed. (It's optional even if a
delay parameter is supplied). delay parameter is supplied).
@ -327,47 +333,24 @@ The following example illustrates how to use foreach for immediate processing of
```javascript ```javascript
var utils = require('utils'); var utils = require('utils');
var players = ['moe', 'larry', 'curly']; var players = utils.players();
utils.foreach (players, function(item){ utils.foreach (players, function( player ) {
echo( server.getPlayer(item), 'Hi ' + item); echo( player , 'Hi ' + player);
}); });
``` ```
... 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
because many objects in the Bukkit API use Java-style collections... Java-style collection. This is important because many objects in the
CanaryMod and Bukkit APIs use Java-style collections...
```javascript ```javascript
// in bukkit, server.onlinePlayers returns a java.util.Collection object
utils.foreach( server.onlinePlayers, function(player){ utils.foreach( server.onlinePlayers, function(player){
player.chat('Hello!'); 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
without hogging CPU usage...
```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(){
echo( player, 'Job Done!');
};
utils.foreach (a, processItem, null, 10, onDone);
```
***/ ***/
var _foreach = function( array, callback, context, delay, onCompletion ) { var _foreach = function( array, callback, context, delay, onCompletion ) {
if ( array instanceof java.util.Collection ) { if ( array instanceof java.util.Collection ) {
@ -394,8 +377,7 @@ exports.foreach = _foreach;
/************************************************************************ /************************************************************************
### utils.nicely() function ### utils.nicely() function
The utils.nicely() function is for performing processing using the The utils.nicely() function is for performing background processing. utils.nicely() lets you
[org.bukkit.scheduler][sched] package/API. utils.nicely() lets you
process with a specified delay between the completion of each `next()` process with a specified delay between the completion of each `next()`
function and the start of the next `next()` function. function and the start of the next `next()` function.
`utils.nicely()` is a recursive function - that is - it calls itself `utils.nicely()` is a recursive function - that is - it calls itself
@ -409,7 +391,7 @@ function and the start of the next `next()` function.
true if the `next` function should be called (processing is not true if the `next` function should be called (processing is not
complete), false otherwise. complete), false otherwise.
* onDone : A function which is to be called when all processing is complete (hasNext returned false). * onDone : A function which is to be called when all processing is complete (hasNext returned false).
* delay : The delay (in server ticks - 20 per second) between each call. * delayInMilliseconds : The delay between each call.
#### Example #### Example
@ -419,7 +401,7 @@ See the source code to utils.foreach for an example of how utils.nicely is used.
var _nicely = function( next, hasNext, onDone, delay ) { var _nicely = function( next, hasNext, onDone, delay ) {
if ( hasNext() ){ if ( hasNext() ){
next(); next();
server.scheduler.runTaskLater( __plugin, function() { setTimeout( function() {
_nicely( next, hasNext, onDone, delay ); _nicely( next, hasNext, onDone, delay );
}, delay ); }, delay );
}else{ }else{
@ -451,9 +433,9 @@ var utils = require('utils');
utils.at( '19:00', function() { utils.at( '19:00', function() {
utils.foreach( server.onlinePlayers, function( player ) { utils.players(function( player ) {
player.chat( 'The night is dark and full of terrors!' ); echo( player, 'The night is dark and full of terrors!' );
}); });
}); });
``` ```

View file

@ -1,3 +1,5 @@
'use strict';
/*global events, echo, isOp, __plugin*/
/************************************************************************* /*************************************************************************
## Example Plugin #7 - Listening for events, Greet players when they join the game. ## Example Plugin #7 - Listening for events, Greet players when they join the game.
@ -14,81 +16,49 @@ following reasons...
`/scriptcraft/plugins` directory, it will be loaded automatically `/scriptcraft/plugins` directory, it will be loaded automatically
when the server starts up. when the server starts up.
2. It uses ScriptCraft's `events.on()` function to add a new *Event 2. It uses ScriptCraft's `events` module to add a new *Event
Handler*. An *Event Handler* is a just a function which gets Handler*. An *Event Handler* is a function that gets
called whenever a particular *event* happens in the game. The called whenever a particular *event* happens in the game. The
function defined below will only be executed whenever a player function defined below will only be executed whenever a player
joins the game. This style of program is sometimes refered to as joins the game. This style of program is sometimes refered to as
*Event-Driven Programming*. *Event-Driven Programming*.
Adding new *Event Handlers* in ScriptCraft is relatively easy. Use the Adding new *Event Handlers* in ScriptCraft is relatively easy. Use one
`events.on()` function to add a new event handler. It takes 2 of the `events` module's functions to add a new event handler. The
parameters... events module has many functions - one for each type of event. Each
function takes a single parameter:
1. The Event Name, in this case `'player.PlayerJoinEvent'`. You can * The event handling function (also sometimes refered to as a
browse [all possible Bukkit events][bkevts] (click the 'Next 'callback'). In ScriptCraft, this function takes a single
Package' and 'Previous Package' links to browse). parameter, an event object. All of the information about the event
is in the event object.
2. The event handling function (also sometimes refered to as a
'callback'). In ScriptCraft, this function takes a single
parameter, an event object. All of the information about the event
is in the event object.
In the example below, if a player joins the server and is an operator, In the example below, if a player joins the server and is an operator,
then the ScriptCraft plugin information will be displayed to that then the ScriptCraft plugin information will be displayed to that
player. player.
What's also notable about this example is how it uses the `isOp()` function. The code... ```javascript
function onJoin( event ){
if ( isOp(event.player) ) {
echo( event.player, 'Welcome to ' + __plugin );
}
}
events.connection( onJoin );
```
First the onJoin() function is defined, this is our event handler -
the function we wish to be called every time some new player joins the
game. Then we hook up - or register - that function using the
events.connection() function. The events.connection function is the
function responsible for adding new *connection* event handlers - that
is - functions which should be invoked when there's a new *connection*
event in the game. A new *connection* event is fired whenever a player
joins the game. There are many other types of events you can handle in
Minecraft. You can see [a full list of events here][cmEvtList].
if ( isOp(event.player) ) [cmEvtList]: #events-helper-module-canary-version
ScriptCraft uses a special version of JavaScript which comes
bundled with Java (Minecraft is written in Java) and JavaScript in
Java can access properties of Java objects more succinctly than in
Java itself. What this means in practice is that when you're perusing
the [Bukkit API Reference][bkapi] and come across a method like
[Player.getAllowFlight()][bkgaf], you can write code like this...
var allowFlight = player.getAllowFlight(); // java style
... or the more succinct ...
var allowFlight = player.allowFlight; // javascript style
... Which style you choose is up to you but `player.allowFlight` is
cleaner and more readable. Similarly where you see a method like
[Player.setAllowFlight()][bksaf], you can write ...
player.setAllowFlight(true); // java style
... or the more readable...
player.allowFlight = true; // javascript style
... Which style you choose is up to you.
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
[bkgaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#getAllowFlight()
[bksaf]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html#setAllowFlight()
[bkapi]: http://jd.bukkit.org/dev/apidocs/
events.on( 'player.PlayerJoinEvent', function( event ) {
if ( isOp(event.player) ) {
echo( event.player, 'Welcome to ' + __plugin);
}
});
Update: Since version 2.0.8 the above code can be replaced by the more succinct:
events.playerJoin( function( event ) {
if ( event.player.op ) {
echo( event.player, 'Welcome to ' + __plugin);
}
});
***/ ***/
// wph 20140927 - event handler registration differs depending on framework.
// wph 20140927 - event handler registration differs depending on framework.
function onJoin( event ) { function onJoin( event ) {
if ( isOp(event.player) ) { if ( isOp(event.player) ) {
echo( event.player, 'Welcome to ' + __plugin ); echo( event.player, 'Welcome to ' + __plugin );