Added 2 new example plugins and changed drone so that public extensions (box, sphere, etc) pass 'self' as first param to Drone constructor (part of eventual phase-out of 'self' variable).

This commit is contained in:
walterhiggins 2013-12-31 18:21:40 +00:00
parent 0afa5aea90
commit 686285dcfb
8 changed files with 273 additions and 91 deletions

View File

@ -74,6 +74,7 @@
<target name="zip_js" depends="init">
<delete file="${build}/${js-plugins-dir}.zip"/>
<zip destfile="${build}/${js-plugins-dir}.zip">
<zipfileset dir="./src/main/javascript" />
</zip>

View File

@ -648,10 +648,9 @@ The following example illustrates how to use http.request to make a request to a
Miscellaneous utility functions and classes to help with programming.
* locationToString(Location) - returns a bukkit Location object in string form.
* locationToString(Location) - returns a [bukkit Location][bkloc] object in string form.
* getPlayerObject(playerName) - returns the Player object for a named
player or `self` if no name is provided.
* player(playerName) - returns the Player object for a named player or `self` if no name is provided.
* getPlayerPos(playerName) - returns the player's x,y,z and yaw (direction) for a named player
or player or `self` if no parameter is provided.
@ -659,6 +658,28 @@ Miscellaneous utility functions and classes to help with programming.
* getMousePos(playerName) - returns the x,y,z of the current block being targeted by the named player
or player or `self` if no paramter is provided.
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html
### player() function
The utils.player() function will return a [bukkit Player][bkpl] object
with the given name. This function takes a single parameter
`playerName` which can be either a String or a [Player][bkpl] object -
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.
#### Parameters
* playerName : A String or Player object. If no parameter is provided then player() will try to return the `self` variable . It is strongly recommended to provide a parameter.
#### Example
var utils = require('utils');
var player = utils.player('walterh');
player.sendMessage('Got you!');
[bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html
### foreach() function
The utils.foreach() function is a utility function for iterating over
@ -707,19 +728,19 @@ 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"];
var players = ['moe', 'larry', 'curly'];
utils.foreach (players, function(item){
server.getPlayer(item).sendMessage("Hi " + 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!");
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...
@ -739,7 +760,7 @@ without hogging CPU usage...
// assume this code is within a function/closure
var player = self;
var onDone = function(){
player.sendMessage("Job Done!");
player.sendMessage('Job Done!');
};
utils.foreach (a, processItem, null, 10, onDone);
@ -773,8 +794,8 @@ The utils.at() function will perform a given task at a given time every
#### Parameters
* time24hr : The time in 24hr form - e.g. 9:30 in the morning is "09:30" while
9:30 pm is "21:30", midnight is "00:00" and midday is "12:00"
* time24hr : The time in 24hr form - e.g. 9:30 in the morning is '09:30' while
9:30 pm is '21:30', midnight is '00:00' and midday is '12:00'
* callback : A javascript function which will be invoked at the given time.
* worlds : (optional) An array of worlds. Each world has its own clock. If no array of worlds is specified, all the server's worlds are used.
@ -784,10 +805,10 @@ To warn players when night is approaching...
var utils = require('utils');
utils.at( "19:00", function() {
utils.at( '19:00', function() {
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!');
});
});

View File

@ -3,10 +3,9 @@
Miscellaneous utility functions and classes to help with programming.
* locationToString(Location) - returns a bukkit Location object in string form.
* locationToString(Location) - returns a [bukkit Location][bkloc] object in string form.
* getPlayerObject(playerName) - returns the Player object for a named
player or `self` if no name is provided.
* player(playerName) - returns the Player object for a named player or `self` if no name is provided.
* getPlayerPos(playerName) - returns the player's x,y,z and yaw (direction) for a named player
or player or `self` if no parameter is provided.
@ -14,36 +13,87 @@ Miscellaneous utility functions and classes to help with programming.
* getMousePos(playerName) - returns the x,y,z of the current block being targeted by the named player
or player or `self` if no paramter is provided.
[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html
***/
var _getPlayerObject = function ( playerName ) {
if (typeof playerName == "undefined"){
if (typeof self == "undefined"){
/************************************************************************
### player() function
The utils.player() function will return a [bukkit Player][bkpl] object
with the given name. This function takes a single parameter
`playerName` which can be either a String or a [Player][bkpl] object -
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.
#### Parameters
* playerName : A String or Player object. If no parameter is provided then player() will try to return the `self` variable . It is strongly recommended to provide a parameter.
#### Example
var utils = require('utils');
var player = utils.player('walterh');
player.sendMessage('Got you!');
[bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html
***/
var _player = function ( playerName ) {
if (typeof playerName == 'undefined'){
if (typeof self == 'undefined'){
return null;
} else {
return self;
}
} else {
if (typeof playerName == "string")
if (typeof playerName == 'string')
return org.bukkit.Bukkit.getPlayer(playerName);
else
return playerName; // assumes it's a player object
}
};
var _locationToJSON = function(location){
return {
world: ''+location.world.name,
x: location.x,
y: location.y,
z: location.z,
yaw: location.yaw,
pitch: location.pitch
};
};
exports.locationToString = function(location){
return JSON.stringify([""+location.world.name,location.x, location.y, location.z]);
return JSON.stringify(_locationToJSON(location));
};
exports.locationToJSON = _locationToJSON;
exports.locationFromJSON = function(json){
var world = org.bukkit.Bukkit.getWorld(json.world);
return new org.bukkit.Location(world, json.x, json.y , json.z, json.yaw, json.pitch);
};
exports.getPlayerObject = _getPlayerObject;
exports.player = _player;
exports.getPlayerObject = function(player){
console.warn('utils.getPlayerObject() is deprecated. Use utils.player() instead.');
return _player(player);
};
exports.getPlayerPos = function( player ) {
player = _getPlayerObject(player);
return player.location;
player = _player(player);
if (player){
if (player instanceof org.bukkit.command.BlockCommandSender)
return player.block.location;
else
return player.location;
}
else
return null;
};
exports.getMousePos = function (player) {
player = _getPlayerObject(player);
player = _player(player);
if (!player)
return null;
// player might be CONSOLE or a CommandBlock
@ -104,19 +154,19 @@ 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"];
var players = ['moe', 'larry', 'curly'];
utils.foreach (players, function(item){
server.getPlayer(item).sendMessage("Hi " + 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!");
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...
@ -136,7 +186,7 @@ without hogging CPU usage...
// assume this code is within a function/closure
var player = self;
var onDone = function(){
player.sendMessage("Job Done!");
player.sendMessage('Job Done!');
};
utils.foreach (a, processItem, null, 10, onDone);
@ -202,8 +252,8 @@ The utils.at() function will perform a given task at a given time every
#### Parameters
* time24hr : The time in 24hr form - e.g. 9:30 in the morning is "09:30" while
9:30 pm is "21:30", midnight is "00:00" and midday is "12:00"
* time24hr : The time in 24hr form - e.g. 9:30 in the morning is '09:30' while
9:30 pm is '21:30', midnight is '00:00' and midday is '12:00'
* callback : A javascript function which will be invoked at the given time.
* worlds : (optional) An array of worlds. Each world has its own clock. If no array of worlds is specified, all the server's worlds are used.
@ -213,10 +263,10 @@ To warn players when night is approaching...
var utils = require('utils');
utils.at( "19:00", function() {
utils.at( '19:00', function() {
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!');
});
});
@ -224,14 +274,14 @@ To warn players when night is approaching...
***/
exports.at = function(time24hr, callback, worlds) {
var forever = function(){ return true;};
var timeParts = time24hr.split(":");
var timeParts = time24hr.split(':');
var hrs = ((timeParts[0] * 1000) + 18000) % 24000;
var mins;
if (timeParts.length > 1)
mins = (timeParts[1] / 60) * 1000;
var timeMc = hrs + mins;
if (typeof worlds == "undefined"){
if (typeof worlds == 'undefined'){
worlds = server.worlds;
}
_nicely(function(){
@ -271,7 +321,7 @@ exports.find = function( dir , filter){
var recurse = function(dir, store){
var files, dirfile = new java.io.File(dir);
if (typeof filter == "undefined")
if (typeof filter == 'undefined')
files = dirfile.list();
else
files = dirfile.list(filter);

View File

@ -76,8 +76,11 @@ for (var type in _types)
{
arrows[type] = (function(n){
return function(player){
player = utils.getPlayerObject(player);
arrows.store.players[player.name] = n;
player = utils.player(player);
if (player)
arrows.store.players[player.name] = n;
else
console.warn('arrows.' + n + ' No player ' + player);
};
})(_types[type]);
}

View File

@ -1,4 +1,4 @@
var _utils = require('utils');
var utils = require('utils');
var blocks = require('blocks');
/*********************************************************************
@ -670,17 +670,26 @@ Drone = function(x,y,z,dir,world)
{
this.record = false;
var usePlayerCoords = false;
var playerPos = _utils.getPlayerPos();
if (typeof x == "undefined")
var player = self;
if (x instanceof org.bukkit.entity.Player){
player = x;
}
var playerPos = utils.getPlayerPos(player);
var that = this;
var populateFromLocation = function(loc){
that.x = loc.x;
that.y = loc.y;
that.z = loc.z;
that.dir = _getDirFromRotation(loc.yaw);
that.world = loc.world;
};
var mp = utils.getMousePos(player);
if (typeof x == "undefined" || x instanceof org.bukkit.entity.Player)
{
var mp = _utils.getMousePos();
if (mp){
this.x = mp.x;
this.y = mp.y;
this.z = mp.z;
populateFromLocation(mp);
if (playerPos)
this.dir = _getDirFromRotation(playerPos.yaw);
this.world = mp.world;
}else{
// base it on the player's current location
usePlayerCoords = true;
@ -691,19 +700,11 @@ Drone = function(x,y,z,dir,world)
if (!playerPos){
return null;
}
this.x = playerPos.x;
this.y = playerPos.y;
this.z = playerPos.z;
this.dir = _getDirFromRotation(playerPos.yaw);
this.world = playerPos.world;
populateFromLocation(playerPos);
}
}else{
if (arguments[0] instanceof org.bukkit.Location){
this.x = arguments[0].x;
this.y = arguments[0].y;
this.z = arguments[0].z;
this.dir = _getDirFromRotation(arguments[0].yaw);
this.world = arguments[0].world;
populateFromLocation(arguments[0]);
}else{
this.x = x;
this.y = y;
@ -714,7 +715,7 @@ Drone = function(x,y,z,dir,world)
this.dir = dir%4;
}
if (typeof world == "undefined"){
this.world = _getWorld();
this.world = playerPos.world;
}else{
this.world = world;
}
@ -755,7 +756,7 @@ Drone.extend = function(name, func)
};
global[name] = function(){
var result = new Drone();
var result = new Drone(self);
result[name].apply(result,arguments);
return result;
};
@ -1071,13 +1072,6 @@ Drone.PLAYER_STAIRS_FACING = [0,2,1,3];
Drone.PLAYER_SIGN_FACING = [4,2,5,3];
Drone.PLAYER_TORCH_FACING = [2,4,1,3];
var _getWorld = function(){
var pl = org.bukkit.entity.Player;
var cs = org.bukkit.command.BlockCommandSender;
var world = (self instanceof pl)?self.location.world:(self instanceof cs)?self.block.location.world:null;
return world;
};
var _STAIRBLOCKS = {53: '5:0' // oak wood
,67: 4 // cobblestone
,108: 45 // brick

View File

@ -0,0 +1,36 @@
/*
A simple minecraft plugin.
Usage: At the in-game prompt type ...
/jsp hello-byname {player-name}
... substituting {player-name} with the name of a player currently
online and a message `Hello ...` will be sent to the named
player.
This example builds on example-5 and also introduces a new concept -
use of shared modules. That is : modules which are not specific to
any one plugin or set of plugins but which can be used by all
plugins. Shared modules should be placed in the
`scriptcraft/modules` directory.
* The utils module is used. Because the 'utils' module is
located in the modules folder we don't need to specify an exact
path, just 'utils' will do.
* The `utils.player()` function is used to obtain a player object
matching the player name. Once a player object is obtained, a
message is sent to that player.
*/
var utils = require('utils');
var greetings = require('./example-1-hello-module');
command('hello-byname', function( parameters, sender ) {
var playerName = parameters[0];
var recipient = utils.player(playerName);
if (recipient)
greetings.hello(recipient);
else
sender.sendMessage('Player ' + playerName + ' not found.');
});

View File

@ -0,0 +1,83 @@
/*
A simple event-driven minecraft plugin.
This example demonstrates event-driven programming. The code below
will display the version of ScriptCraft every time an operator joins
the game. This module is notable from previous modules for the
following reasons...
1. It does not export any functions or variables. That's fine. Not
all modules need export stuff. Code in this module will be
executed when the module is first loaded. Because it is in the
`/scriptcraft/plugins` directory, it will be loaded automatically
when the server starts up.
2. It uses ScriptCraft's `events.on()` function to add a new *Event
Handler*. An *Event Handler* is a just a function which gets
called whenever a particular *event* happens in the game. The
function defined below will only be executed whenever a player
joins the game. This style of program is sometimes refered to as
*Event-Driven Programming*.
Adding new *Event Handlers* in ScriptCraft is relatively easy. Use the
`events.on()` function to add a new event handler. It takes 2
parameters...
1. The Event Name, in this case `'player.PlayerJoinEvent'`. You can
browse [all possible Bukkit events][bkevts] (click the 'Next
Package' and 'Previous Package' links to browse).
2. The event handling function (also sometimes refered to as a
'callback'). In ScriptCraft, this function takes 2 parameters, a
listener object and 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,
then the ScriptCraft plugin information will be displayed to that
player.
What's also notable about this example is how it uses the [Bukkit
API][bkapi]. The code...
if (event.player.op)
... is a succinct way of accessing object properties which in Java
would have to be written as ...
if (event.getPlayer().isOp())
... 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 (listener, event){
if (event.player.op) {
event.player.sendMessage('Welcome to ' + __plugin);
}
});

View File

@ -96,8 +96,8 @@ var homes = plugin("homes", {
go: function(guest, host){
if (typeof host == "undefined")
host = guest;
guest = utils.getPlayerObject(guest);
host = utils.getPlayerObject(host);
guest = utils.player(guest);
host = utils.player(host);
var loc = _store.houses[host.name];
if (!loc){
guest.sendMessage(host.name + " has no home");
@ -107,9 +107,8 @@ var homes = plugin("homes", {
guest.sendMessage("You can't visit " + host.name + "'s home yet");
return;
}
var worldName = loc[0], x = loc[1], y = loc[2], z=loc[3], yaw=loc[4];
var teleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
var homeLoc = new org.bukkit.Location(org.bukkit.Bukkit.getWorld(worldName),x,y,z,yaw,0);
var homeLoc = utils.locationFromJSON(loc);
guest.teleport(homeLoc, teleportCause.PLUGIN);
},
/*
@ -128,17 +127,12 @@ var homes = plugin("homes", {
return false;
},
set: function(player){
player = utils.getPlayerObject(player);
player = utils.player(player);
var loc = player.location;
_store.houses[player.name] = [""+loc.world.name
,Math.floor(loc.x)
,Math.floor(loc.y)
,Math.floor(loc.z)
,Math.floor(loc.yaw)
,Math.floor(loc.pitch)];
_store.houses[player.name] = utils.locationToJSON(loc);
},
remove: function(player){
player = utils.getPlayerObject(player);
player = utils.player(player);
delete _store.houses[player.name];
},
/* ========================================================================
@ -152,7 +146,7 @@ var homes = plugin("homes", {
var result = [];
for (var ohp in _store.openHouses)
result.push(ohp);
player = utils.getPlayerObject(player);
player = utils.player(player);
for (var host in _store.invites){
var guests = _store.invites[host];
for (var i = 0;i < guests.length; i++)
@ -165,7 +159,7 @@ var homes = plugin("homes", {
list who can visit the player's home
*/
ilist: function(player){
player = utils.getPlayerObject(player);
player = utils.player(player);
var result = [];
// if home is public - all players
if (_store.openHouses[player.name]){
@ -185,8 +179,8 @@ var homes = plugin("homes", {
Invite a player to the home
*/
invite: function(host, guest){
host = utils.getPlayerObject(host);
guest = utils.getPlayerObject(guest);
host = utils.player(host);
guest = utils.player(guest);
var invitations = [];
if (_store.invites[host.name])
invitations = _store.invites[host.name];
@ -199,8 +193,8 @@ var homes = plugin("homes", {
Uninvite someone to the home
*/
uninvite: function(host, guest){
host = utils.getPlayerObject(host);
guest = utils.getPlayerObject(guest);
host = utils.player(host);
guest = utils.player(guest);
var invitations = _store.invites[host.name];
if (!invitations)
return;
@ -214,7 +208,7 @@ var homes = plugin("homes", {
make the player's house public
*/
open: function(player, optionalMsg){
player = utils.getPlayerObject(player);
player = utils.player(player);
_store.openHouses[player.name] = true;
if (typeof optionalMsg != "undefined")
__plugin.server.broadcastMessage(optionalMsg);
@ -223,7 +217,7 @@ var homes = plugin("homes", {
make the player's house private
*/
close: function(player){
player = utils.getPlayerObject(player);
player = utils.player(player);
delete _store.openHouses[player.name];
},
/* ========================================================================
@ -236,7 +230,7 @@ var homes = plugin("homes", {
return result;
},
clear: function(player){
player = utils.getPlayerObject(player);
player = utils.player(player);
delete _store.houses[player.name];
delete _store.openHouses[player.name];
},
@ -249,8 +243,8 @@ exports.homes = homes;
define a set of command options that can be used by players
*/
var options = {
'set': function(){homes.set();},
'delete': function(){ homes.remove();},
'set': function(params, sender){ homes.set(sender); },
'delete': function(params, sender ){ homes.remove(sender);},
'help': function(params, sender){ sender.sendMessage(homes.help());},
'list': function(params, sender){
var visitable = homes.list();
@ -279,7 +273,7 @@ var options = {
return;
}
var playerName = params[1];
var guest = utils.getPlayerObject(playerName);
var guest = utils.player(playerName);
if (!guest)
sender.sendMessage(playerName + " is not here");
else
@ -291,7 +285,7 @@ var options = {
return;
}
var playerName = params[1];
var guest = utils.getPlayerObject(playerName);
var guest = utils.player(playerName);
if (!guest)
sender.sendMessage(playerName + " is not here");
else
@ -333,7 +327,7 @@ command("home", function ( params , sender) {
if (option)
option(params,sender);
else{
var host = utils.getPlayerObject(params[0]);
var host = utils.player(params[0]);
if (!host)
sender.sendMessage(params[0] + " is not here");
else