diff --git a/docs/API-Reference.md b/docs/API-Reference.md index 2d7b345..a53566b 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -53,6 +53,9 @@ Walter Higgins * [http.request() function](#httprequest-function) * [Parameters](#parameters) * [Example](#example) + * [Signs Module](#signs-module) + * [signs.menu() function](#signsmenu-function) + * [signs.getTargetedBy() function](#signsgettargetedby-function) * [Utilities Module](#utilities-module) * [utils.player() function](#utilsplayer-function) * [utils.locationToJSON() function](#utilslocationtojson-function) @@ -821,6 +824,95 @@ The following example illustrates how to use http.request to make a request to a var jsObj = eval("(" + responseBody + ")"); }); +## Signs Module + +The Signs Module can be used by plugin authors to create interactive +signs - that is - signs which display a list of choices which can be +changed by interacting (right-clicking) with the sign. + +### signs.menu() function + +This function is used to construct a new interactive menu on top of an +existing sign in the game world. + +#### Parameters + + * Label : A string which will be displayed in the topmost line of the + sign. This label is not interactive. + * options : An array of strings which can be selected on the sign by + right-clicking/interacting. + * callback : A function which will be called whenever a player + interacts (changes selection) on a sign. This callback in turn + takes as its parameter, an object with the following properties... + + * player : The player who interacted with the sign. + * sign : The [org.bukkit.block.Sign][buksign] which the player interacted with. + * text : The text for the currently selected option on the sign. + * number : The index of the currently selected option on the sign. + + * selectedIndex : optional: A number (starting at 0) indicating which + of the options should be selected by default. 0 is the default. + +#### Returns +This function does not itself do much. It does however return a +function which when invoked with a given +[org.bukkit.block.Sign][buksign] object, will convert that sign into +an interactive sign. + +#### Example: Create a sign which changes the time of day. + +##### plugins/signs/time-of-day.js + + var utils = require('utils'), + signs = require('signs'); + + var onTimeChoice = function(event){ + var selectedIndex = event.number; + // convert to Minecraft time 0 = Dawn, 6000 = midday, 12000 = dusk, 18000 = midnight + var time = selectedIndex * 6000; + event.player.location.world.setTime(time); + }; + + // signs.menu returns a function which can be called for one or more signs in the game. + var convertToTimeMenu = signs.menu('Time of Day', + ['Dawn', 'Midday', 'Dusk', 'Midnight'], + onTimeChoice); + + exports.time_sign = function( player ){ + + var sign = signs.getTargetedBy(player); + if (!sign){ + throw new Error('You must look at a sign'); + } + convertToTimeMenu(sign); + }; + +To use the above function at the in-game prompt, look at an existing +sign and type... + + /js time_sign(self); + +... and the sign you're looking at will become an interactive sign +which changes the time each time you interact (right-click) with it. + +### signs.getTargetedBy() function + +This function takes a [org.bukkit.entity.LivingEntity][bukle] as a +parameter and returns a [org.bukkit.block.Sign][buksign] object which +the entity has targeted. It is a utility function for use by plugin authors. + +#### Example + + var signs = require('signs'), + utils = require('utils'); + var player = utils.player('tom1234'); + var sign = signs.getTargetedBy( player ); + if (!sign){ + player.sendMessage('Not looking at a sign'); + } + +[buksign]: http://jd.bukkit.org/dev/apidocs/org/bukkit/block/Sign.html + String class extensions ----------------------- The following chat-formatting methods are added to the javascript String class.. diff --git a/src/main/javascript/modules/http/request.js b/src/main/javascript/modules/http/request.js index 9be0b36..00d2965 100644 --- a/src/main/javascript/modules/http/request.js +++ b/src/main/javascript/modules/http/request.js @@ -1,5 +1,10 @@ /************************************************************************* -## http.request() function +## Http Module + +For handling http requests. Not to be confused with the more robust +and functional 'http' module bundled with Node.js. + +### http.request() function The http.request() function will fetch a web address asynchronously (on a separate thread)and pass the URL's response to a callback function @@ -7,7 +12,7 @@ which will be executed synchronously (on the main thread). In this way, http.request() can be used to fetch web content without blocking the main thread of execution. -### Parameters +#### Parameters * request: The request details either a plain URL e.g. "http://scriptcraft.js/sample.json" or an object with the following properties... @@ -19,7 +24,7 @@ main thread of execution. - responseCode: The numeric response code from the server. If the server did not respond with 200 OK then the response parameter will be undefined. - response: A string (if the response is of type text) or object containing the HTTP response body. -### Example +#### Example The following example illustrates how to use http.request to make a request to a JSON web service and evaluate its response... diff --git a/src/main/javascript/modules/signs/menu.js b/src/main/javascript/modules/signs/menu.js index f07cb84..32aba39 100644 --- a/src/main/javascript/modules/signs/menu.js +++ b/src/main/javascript/modules/signs/menu.js @@ -48,12 +48,12 @@ signs.menu = function( /* String */ label, /* Array */ options, /* Function */ callback, - /* Number */ selectedIndex) + /* Number */ selectedIndex +) { if (typeof selectedIndex == "undefined") selectedIndex = 0; - // // variables common to all instances of this menu can go here // @@ -76,15 +76,24 @@ signs.menu = function( { if (typeof save == "undefined") save = true; - + /* + @deprecated start + all calls should explicitly provide a [org.bukkit.block.Sign][buksign] parameter. + */ if (typeof sign == "undefined"){ var mouseLoc = utils.getMousePos(); if (mouseLoc){ sign = mouseLoc.block.state; + if (!(sign && sign.setLine)){ + throw new Error("You must first provide a sign!"); + } }else{ - throw new Exception("You must provide a sign!"); + throw new Error("You must first provide a sign!"); } } + /* + @deprecated end + */ // // per-sign variables go here // diff --git a/src/main/javascript/modules/signs/package.json b/src/main/javascript/modules/signs/package.json index e59258e..520d7aa 100644 --- a/src/main/javascript/modules/signs/package.json +++ b/src/main/javascript/modules/signs/package.json @@ -1,4 +1,4 @@ { name: 'signs', - main: './menu.js' + main: './signs.js' } diff --git a/src/main/javascript/modules/signs/signs.js b/src/main/javascript/modules/signs/signs.js new file mode 100644 index 0000000..686a6b1 --- /dev/null +++ b/src/main/javascript/modules/signs/signs.js @@ -0,0 +1,107 @@ +/************************************************************************ +## Signs Module + +The Signs Module can be used by plugin authors to create interactive +signs - that is - signs which display a list of choices which can be +changed by interacting (right-clicking) with the sign. + +### signs.menu() function + +This function is used to construct a new interactive menu on top of an +existing sign in the game world. + +#### Parameters + + * Label : A string which will be displayed in the topmost line of the + sign. This label is not interactive. + * options : An array of strings which can be selected on the sign by + right-clicking/interacting. + * callback : A function which will be called whenever a player + interacts (changes selection) on a sign. This callback in turn + takes as its parameter, an object with the following properties... + + * player : The player who interacted with the sign. + * sign : The [org.bukkit.block.Sign][buksign] which the player interacted with. + * text : The text for the currently selected option on the sign. + * number : The index of the currently selected option on the sign. + + * selectedIndex : optional: A number (starting at 0) indicating which + of the options should be selected by default. 0 is the default. + +#### Returns +This function does not itself do much. It does however return a +function which when invoked with a given +[org.bukkit.block.Sign][buksign] object, will convert that sign into +an interactive sign. + +#### Example: Create a sign which changes the time of day. + +##### plugins/signs/time-of-day.js + + var utils = require('utils'), + signs = require('signs'); + + var onTimeChoice = function(event){ + var selectedIndex = event.number; + // convert to Minecraft time 0 = Dawn, 6000 = midday, 12000 = dusk, 18000 = midnight + var time = selectedIndex * 6000; + event.player.location.world.setTime(time); + }; + + // signs.menu returns a function which can be called for one or more signs in the game. + var convertToTimeMenu = signs.menu('Time of Day', + ['Dawn', 'Midday', 'Dusk', 'Midnight'], + onTimeChoice); + + exports.time_sign = function( player ){ + + var sign = signs.getTargetedBy(player); + if (!sign){ + throw new Error('You must look at a sign'); + } + convertToTimeMenu(sign); + }; + +To use the above function at the in-game prompt, look at an existing +sign and type... + + /js time_sign(self); + +... and the sign you're looking at will become an interactive sign +which changes the time each time you interact (right-click) with it. + +### signs.getTargetedBy() function + +This function takes a [org.bukkit.entity.LivingEntity][bukle] as a +parameter and returns a [org.bukkit.block.Sign][buksign] object which +the entity has targeted. It is a utility function for use by plugin authors. + +#### Example + + var signs = require('signs'), + utils = require('utils'); + var player = utils.player('tom1234'); + var sign = signs.getTargetedBy( player ); + if (!sign){ + player.sendMessage('Not looking at a sign'); + } + +[buksign]: http://jd.bukkit.org/dev/apidocs/org/bukkit/block/Sign.html + +***/ +var utils = require('utils'); +var menu = require('./menu'); +// include all menu exports +for (var i in menu){ + exports[i] = menu[i]; +} + +exports.getTargetedBy = function( livingEntity ){ + var location = utils.getMousePos( livingEntity ); + if (!location) + return null; + var state = location.block.state; + if (!(state || state.setLine)) + return null; + return state; +}; diff --git a/src/main/javascript/plugins/arrows.js b/src/main/javascript/plugins/arrows.js index 9b0bbe7..dcac397 100644 --- a/src/main/javascript/plugins/arrows.js +++ b/src/main/javascript/plugins/arrows.js @@ -91,9 +91,19 @@ for (var type in _types) var _onMenuChoice = function(event){ arrows.store.players[event.player.name] = event.number; }; -arrows.sign = signs.menu("Arrow", - ["Normal","Explosive","Teleport","Flourish","Lightning","Firework"], - _onMenuChoice ); +var convertToArrowSign = signs.menu( + "Arrow", + ["Normal","Explosive","Teleport","Flourish","Lightning","Firework"], + _onMenuChoice); + +arrows.sign = function(cmdSender) +{ + var sign = signs.getTargetedBy(cmdSender); + if (!sign){ + throw new Error('You must first look at a sign!'); + } + return convertToArrowSign(sign,true); +}; /* event handler called when a projectile hits something diff --git a/src/main/javascript/plugins/signs/examples.js b/src/main/javascript/plugins/signs/examples.js index dd1cdd3..179ee3f 100644 --- a/src/main/javascript/plugins/signs/examples.js +++ b/src/main/javascript/plugins/signs/examples.js @@ -10,12 +10,25 @@ var signs = require('signs'); // // /js signs.menu_time() // + +var onDinnerChoice = function(event){ + event.player.sendMessage("You chose " + event.text); +}; +var convertToDinnerMenu = signs.menu("Dinner", ["Lamb","Pork","Chicken","Duck","Beef"], onDinnerChoice); + +var onTimeChoice = function(event){ + event.player.location.world.setTime( event.number * 6000 ); +}; +var convertToTimeMenu = signs.menu("Time", ["Dawn","Midday","Dusk","Midnight"], onTimeChoice); + exports.signs = { - menu_food: signs.menu("Dinner", - ["Lamb","Pork","Chicken","Duck","Beef"], - function(event){ - event.player.sendMessage("You chose " + event.text); - }), + menu_food: function(cmdSender){ + var sign = signs.getTargetedBy(cmdSender); + if (!sign){ + throw new Error('You must look at an existing sign'); + } + convertToDinnerMenu(sign); + }, // // This is an example sign that displays a menu of times of day // interacting with the sign will change the time of day accordingly. @@ -25,10 +38,12 @@ exports.signs = { // /js var signExamples = require('./signs/examples'); // /js signExamples.timeOfDay() // - menu_time: signs.menu("Time", - ["Dawn","Midday","Dusk","Midnight"], - function(event){ - event.player.location.world.setTime( event.number * 6000 ); - }) + menu_time: function(cmdSender){ + var sign = signs.getTargetedBy(cmdSender); + if (!sign){ + throw new Error('You must look at an existing sign'); + } + convertToTimeMenu(sign); + } }