diff --git a/docs/API-Reference.md b/docs/API-Reference.md index f167618..de1a3be 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -1653,26 +1653,147 @@ To construct a spiral staircase 5 floors high made of oak... spiral_stairs('oak', 5); - -## The arrows mod adds fancy arrows to the game. - -### Usage: +# Arrows Module - /js var arrows = require('./arrows/arrows') +## Description +The arrows mod adds fancy arrows to the game. Arrows which... - * `/js arrows.sign()` turns a targeted sign into a Arrows menu - * `/js arrows.normal()` sets arrow type to normal. - * `/js arrows.explosive()` - makes arrows explode. + * Launch fireworks. + * Explode on impact. + * Force Lightning to strike where they land. + * Teleport the player to the landing spot. + * Spawn Trees at the landing spot. + +## Usage: + + * `/js arrows.firework()` - A firework launches where the the arrow lands. + * `/js arrows.lightning()` - lightning strikes where the arrow lands. * `/js arrows.teleport()` - makes player teleport to where arrow has landed. * `/js arrows.flourish()` - makes a tree grow where the arrow lands. - * `/js arrows.lightning()` - lightning strikes where the arrow lands. - * `/js arrows.firework()` - A firework launches where the the arrow lands. + * `/js arrows.explosive()` - makes arrows explode. + * `/js arrows.normal()` sets arrow type to normal. + * `/js arrows.sign()` turns a targeted sign into a Arrows menu - All of the above functions can take an optional player object or name as - a parameter. E.g. - - `/js arrows.explosive('player23')` makes player23's arrows explosive. +All of the above functions can take an optional player object or name as +a parameter. For example: `/js arrows.explosive('player23')` makes player23's arrows explosive. +# Commando Plugin + +## Description + +commando is a plugin which can be used to add completely new commands +to Minecraft. Normally ScriptCraft only allows for provision of new +commands as extensions to the jsp command. For example, to create a +new simple command for use by all players... + + /js command('hi', function(){ echo('Hi ' + self.name); }); + +... then players can use this command by typing... + + /jsp hi + +... A couple of ScriptCraft users have asked for the ability to take +this a step further and allow the global command namespace to be +populated so that when a developer creates a new command using the +'command' function, then the command is added to the global command +namespace so that players can use it simply like this... + + /hi + +... There are good reasons why ScriptCraft's core `command()` function +does not do this. Polluting the global namespace with commands would +make ScriptCraft a bad citizen in that Plugins should be able to work +together in the same server and - as much as possible - not step on +each others' toes. The CraftBukkit team have very good reasons for +forcing Plugins to declare their commands in the plugin.yml +configuration file. It makes approving plugins easier and ensures that +craftbukkit plugins behave well together. While it is possible to +override other plugins' commands, the CraftBukkit team do not +recommend this. However, as ScriptCraft users have suggested, it +should be at the discretion of server administrators as to when +overriding or adding new commands to the global namespace is good. + +So this is where `commando()` comes in. It uses the exact same +signature as the core `command()` function but will also make the +command accessible without the `jsp` prefix so instead of having to +type `/jsp hi` for the above command example, players simply type +`/hi` . This functionality is provided as a plugin rather than as part +of the ScriptCraft core. + +## Example hi-command.js + + var commando = require('../commando'); + commando('hi', function(){ + echo('Hi ' + self.name); + }); + +...Displays a greeting to any player who issues the `/hi` command. + +## Example - timeofday-command.js + + var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000}; + commando('timeofday', function(params){ + self.location.world.setTime(times[params[0]]); + }, + ['Dawn','Midday','Dusk','Midnight']); + +... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight) + +## Caveats + +Since commands registered using commando are really just appendages to +the `/jsp` command and are not actually registered globally (it just +looks like that to the player), you won't be able to avail of tab +completion for the command itself or its parameters (unless you go the +traditional route of adding the `jsp` prefix). This plugin uses the +[PlayerCommandPreprocessEvent][pcppevt] which allows plugins to +intercepts all commands and inject their own commands instead. If +anyone reading this knows of a better way to programmatically add new +global commands for a plugin, please let me know. + +[pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html + +Classroom Module +================ +The `classroom` object contains a couple of utility functions for use +in a classroom setting. The goal of these functions is to make it +easier for tutors to facilitate ScriptCraft for use by students in a +classroom environment. Although granting ScriptCraft access to +students on a shared server is potentially risky (Students can +potentially abuse it), it is slighlty less risky than granting +operator privileges to each student. (Enterprising students will +quickly realise how to grant themselves and others operator privileges +once they have access to ScriptCraft). + +The goal of this module is not so much to enforce restrictions +(security or otherwise) but to make it easier for tutors to setup a shared server +so students can learn Javascript. + +classroom.allowScripting() function +=================================== +Allow or disallow anyone who connects to the server (or is already +connected) to use ScriptCraft. This function is preferable to granting 'ops' privileges +to every student in a Minecraft classroom environment. + +Parameters +---------- + + * canScript : true or false + +Example +------- +To allow all players (and any players who connect to the server) to +use the `js` and `jsp` commands... + + /js classroom.allowScripting(true) + +To disallow scripting (and prevent players who join the server from using the commands)... + + /js classroom.allowScripting(false) + +Only ops users can run the classroom.allowScripting() function - this is so that students +don't try to bar themselves and each other from scripting. + ### Commando Plugin #### Description @@ -1750,53 +1871,59 @@ global commands for a plugin, please let me know. [pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html -Classroom Module -================ -The `classroom` object contains a couple of utility functions for use -in a classroom setting. The goal of these functions is to make it -easier for tutors to facilitate ScriptCraft for use by students in a -classroom environment. Although granting ScriptCraft access to -students on a shared server is potentially risky (Students can -potentially abuse it), it is slighlty less risky than granting -operator privileges to each student. (Enterprising students will -quickly realise how to grant themselves and others operator privileges -once they have access to ScriptCraft). +# SnowballFight mini-game -The goal of this module is not so much to enforce restrictions -(security or otherwise) but to make it easier for tutors to setup a shared server -so students can learn Javascript. +## Description -classroom.allowScripting() function -=================================== -Allow or disallow anyone who connects to the server (or is already -connected) to use ScriptCraft. This function is preferable to granting 'ops' privileges -to every student in a Minecraft classroom environment. +This is a rough and ready prototype of a simple multi-player +shoot-em-up. To start a game with all players playing against one another... -Parameters ----------- + /js new Game_SnowballFight(60).start(); - * canScript : true or false +... this obviously works best if all of the players are in close +proximity within the same game world. Alternatively you can have team +matches... -Example -------- -To allow all players (and any players who connect to the server) to -use the `js` and `jsp` commands... - /js classroom.allowScripting(true) + /js var redTeam = ['','',...etc] + /js var blueTeam = ['',',...etc] + /js var greenTeam = ['',',...etc] + /js new Game_SnowballFight(60, {red: redTeam,blue: blueTeam,green: greenTeam}).start(); -To disallow scripting (and prevent players who join the server from using the commands)... +Or you can just have specific players play against each other... - /js classroom.allowScripting(false) + /js new Game_SnowballFight(60, ['player1','player2','player3']).start(); -Only ops users can run the classroom.allowScripting() function - this is so that students -don't try to bar themselves and each other from scripting. +(where 'player1' etc are the names of actual players) + +You specify the teams in the game as an object where each property's +name is a team name and each property's value is the list of players +on that team. You specify the duration of the game (in seconds) You +kick off the game with the start() method. I need to work on a +better in-game mechanism for players to choose teams and start the +game but this will do for now. -## Minigame: Guess the number +When the game starts, each player is put in survival mode and given +snowballs. The aim of the game is to hit players on opposing teams. If +you hit a player on your own team, you lose a point. + +At the end of the game the scores for each team are broadcast and each +player returns to their previous mode of play (creative or +survival). Create a small arena with a couple of small buildings for +cover to make the game more fun. + +# NumberGuess mini-game: -### Example +## Description +This is a very simple number guessing game. Minecraft will ask you to +guess a number between 1 and 10 and you will tell you if you're too +hight or too low when you guess wrong. The purpose of this mini-game +code is to demonstrate use of Bukkit's Conversation API. + +## Example /js Game_NumberGuess.start() -... Begins a number-guessing game where you must guess the number (between 1 and 10) chosen by the computer. - - A basic number-guessing game that uses the Bukkit Conversation API. +Once the game begins, guess a number by typing the `/` character +followed by a number between 1 and 10. + diff --git a/docs/release-notes.md b/docs/release-notes.md index e229274..b4286ec 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,3 +1,10 @@ +# 2013 12 26 + +Made the `events` variable global because it is use by modules and +plugins. This means there is no longer any need to explicitly +`require('events')` since `events` is now a free variable in the +global namespace. + # 2013 12 25 Added the 'commando' module. diff --git a/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java b/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java index 4b7d3c4..64bac6a 100644 --- a/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java +++ b/src/main/java/net/walterhiggins/scriptcraft/ScriptCraftPlugin.java @@ -156,10 +156,10 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener this.engine.put("__cmdArgs",args); result = true; } else if (cmd.getName().equalsIgnoreCase("coffee")) { - for (int i = 0;i < args.length; i++) + for (int i = 0;i < args.length; i++) javascriptCode += args[i] + " "; - javascriptCode = "eval(CoffeeScript.compile(\""+javascriptCode+"\", {bare: true}))"; - result = true; + javascriptCode = "eval(CoffeeScript.compile(\""+javascriptCode+"\", {bare: true}))"; + result = true; } if (result){ @@ -181,5 +181,4 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener } return result; } - } diff --git a/src/main/javascript/lib/require.js b/src/main/javascript/lib/require.js index fd08ee4..74648b4 100644 --- a/src/main/javascript/lib/require.js +++ b/src/main/javascript/lib/require.js @@ -86,6 +86,18 @@ module specification, the '.js' suffix is optional. } }; + var fileExists = function(file) { + if (file.isDirectory()){ + return readModuleFromDirectory(file); + }else { + return file; + } + }; + + var _canonize = function(file){ + return "" + file.canonicalPath.replaceAll("\\\\","/"); + }; + var resolveModuleToFile = function(moduleName, parentDir) { /********************************************************************** ## When resolving module names to file paths, ScriptCraft uses the following rules... @@ -119,18 +131,8 @@ module specification, the '.js' suffix is optional. 3.2 if no package.json file exists then look for an index.js file in the directory ***/ - var file = new File(moduleName); - var fileExists = function(file) { - - if (file.isDirectory()){ - return readModuleFromDirectory(file); - }else { - return file; - } - }; - if (file.exists()){ return fileExists(file); } @@ -156,11 +158,7 @@ module specification, the '.js' suffix is optional. // it's of the form ./path file = new File(parentDir, moduleName); if (file.exists()){ - if (file.isDirectory()){ - return readModuleFromDirectory(file); - }else { - return file; - } + return fileExists(file); }else { // try appending a .js to the end @@ -169,7 +167,6 @@ module specification, the '.js' suffix is optional. if (file.exists()) return file; else{ - file = new File(pathWithJSExt); if (file.exists()) return file; @@ -186,10 +183,6 @@ module specification, the '.js' suffix is optional. var _require = function(parentFile, path) { - var _canonize = function(file){ - return "" + file.canonicalPath.replaceAll("\\\\","/"); - }; - var file = resolveModuleToFile(path, parentFile); if (!file){ throw new Error("require('" + path + "'," + parentFile.canonicalPath + ") failed"); @@ -215,7 +208,8 @@ module specification, the '.js' suffix is optional. moduleInfo = { loaded: false, id: canonizedFilename, - exports: {} + exports: {}, + require: _requireClosure(file.parentFile) }; var tail = "})"; code = head + code + tail; @@ -228,14 +222,18 @@ module specification, the '.js' suffix is optional. logger.severe("Error:" + e + " while evaluating module " + canonizedFilename); throw e; } - var __dirname = file.parentFile.canonicalPath; + var __dirname = "" + file.parentFile.canonicalPath; + var parameters = [ + moduleInfo.exports, /* exports */ + moduleInfo, /* module */ + moduleInfo.require, /* require */ + canonizedFilename, /* __filename */ + __dirname /* __dirname */ + ]; try { - compiledWrapper.apply(moduleInfo.exports, - [moduleInfo.exports, - moduleInfo, - _requireClosure(file.parentFile), - canonizedFilename, - "" + __dirname]); + compiledWrapper + .apply(moduleInfo.exports, /* this */ + parameters); } catch (e){ logger.severe("Error:" + e + " while executing module " + canonizedFilename); throw e; diff --git a/src/main/javascript/lib/scriptcraft.js b/src/main/javascript/lib/scriptcraft.js index 143fd0d..d006db6 100644 --- a/src/main/javascript/lib/scriptcraft.js +++ b/src/main/javascript/lib/scriptcraft.js @@ -757,7 +757,6 @@ See [issue #69][issue69] for more information. global.plugin = plugins.plugin; global.command = plugins.command; global.save = plugins.save; - plugins.autoload(jsPluginsRootDir); var events = require('events'); events.on('server.PluginDisableEvent',function(l,e){ @@ -767,6 +766,11 @@ See [issue #69][issue69] for more information. _runUnloadHandlers(); org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin); }); + // wph 20131226 - make events global as it is used by many plugins/modules + global.events = events; + + plugins.autoload(jsPluginsRootDir); + }()); diff --git a/src/main/javascript/modules/signs/menu.js b/src/main/javascript/modules/signs/menu.js index 8f9bbce..0d08b86 100644 --- a/src/main/javascript/modules/signs/menu.js +++ b/src/main/javascript/modules/signs/menu.js @@ -1,6 +1,6 @@ var _utils = require('utils'); var stringExt = require('utils/string-exts'); -var events = require('events'); +var _store = {}; /* Define the signs module - signs are persistent (that is - a menu sign will still be a menu after the @@ -14,7 +14,8 @@ var signs = plugin("signs", { /* String */ label, /* Array */ options, /* Function */ onInteract, - /* Number */ defaultSelection ){} + /* Number */ defaultSelection ){}, + store: _store },true); module.exports = signs; @@ -37,9 +38,8 @@ var _redrawMenuSign = function(p_sign,p_selectedIndex,p_displayOptions) } p_sign.update(true); }; + var _updaters = {}; -var _store = {}; -signs.store = _store; /* construct an interactive menu to be subsequently attached to one or more Signs. @@ -169,7 +169,7 @@ signs.menu = function( // // update it every time player interacts with it. // -events.on("player.PlayerInteractEvent",function(listener, event) { +events.on('player.PlayerInteractEvent',function(listener, event) { /* look up our list of menu signs. If there's a matching location and there's a sign, then update it. diff --git a/src/main/javascript/plugins/arrows.js b/src/main/javascript/plugins/arrows.js index 534fa04..ef2ed6f 100644 --- a/src/main/javascript/plugins/arrows.js +++ b/src/main/javascript/plugins/arrows.js @@ -1,28 +1,31 @@ /************************************************************************* - -## The arrows mod adds fancy arrows to the game. - -### Usage: +# Arrows Module - /js var arrows = require('./arrows/arrows') +## Description +The arrows mod adds fancy arrows to the game. Arrows which... - * `/js arrows.sign()` turns a targeted sign into a Arrows menu - * `/js arrows.normal()` sets arrow type to normal. - * `/js arrows.explosive()` - makes arrows explode. + * Launch fireworks. + * Explode on impact. + * Force Lightning to strike where they land. + * Teleport the player to the landing spot. + * Spawn Trees at the landing spot. + +## Usage: + + * `/js arrows.firework()` - A firework launches where the the arrow lands. + * `/js arrows.lightning()` - lightning strikes where the arrow lands. * `/js arrows.teleport()` - makes player teleport to where arrow has landed. * `/js arrows.flourish()` - makes a tree grow where the arrow lands. - * `/js arrows.lightning()` - lightning strikes where the arrow lands. - * `/js arrows.firework()` - A firework launches where the the arrow lands. + * `/js arrows.explosive()` - makes arrows explode. + * `/js arrows.normal()` sets arrow type to normal. + * `/js arrows.sign()` turns a targeted sign into a Arrows menu - All of the above functions can take an optional player object or name as - a parameter. E.g. - - `/js arrows.explosive('player23')` makes player23's arrows explosive. +All of the above functions can take an optional player object or name as +a parameter. For example: `/js arrows.explosive('player23')` makes player23's arrows explosive. ***/ var signs = require('signs'); -var events = require('events'); var fireworks = require('fireworks'); var _store = {players: {}}; diff --git a/src/main/javascript/plugins/chat/color.js b/src/main/javascript/plugins/chat/color.js index 76b5e3b..62493e7 100644 --- a/src/main/javascript/plugins/chat/color.js +++ b/src/main/javascript/plugins/chat/color.js @@ -1,8 +1,6 @@ /* TODO: Document this module */ -var events = require('events'); - var _store = {players: {}}; /* declare a new javascript plugin for changing chat text color diff --git a/src/main/javascript/plugins/classroom/classroom.js b/src/main/javascript/plugins/classroom/classroom.js index 42ef205..13f6d1e 100644 --- a/src/main/javascript/plugins/classroom/classroom.js +++ b/src/main/javascript/plugins/classroom/classroom.js @@ -1,5 +1,4 @@ var utils = require('utils'); -var events = require('events'); /************************************************************************ Classroom Module diff --git a/src/main/javascript/plugins/commando/commando.js b/src/main/javascript/plugins/commando/commando.js index b9b43e8..e0f620c 100644 --- a/src/main/javascript/plugins/commando/commando.js +++ b/src/main/javascript/plugins/commando/commando.js @@ -77,7 +77,7 @@ global commands for a plugin, please let me know. [pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html ***/ -var events = require('events'); + var commands = {}; exports.commando = function(name, func, options, intercepts){ var result = command(name, func, options, intercepts); diff --git a/src/main/javascript/plugins/minigames/NumberGuess.js b/src/main/javascript/plugins/minigames/NumberGuess.js index 542086c..d2305cb 100644 --- a/src/main/javascript/plugins/minigames/NumberGuess.js +++ b/src/main/javascript/plugins/minigames/NumberGuess.js @@ -1,13 +1,19 @@ /************************************************************************* -## Minigame: Guess the number +# NumberGuess mini-game: -### Example +## Description +This is a very simple number guessing game. Minecraft will ask you to +guess a number between 1 and 10 and you will tell you if you're too +hight or too low when you guess wrong. The purpose of this mini-game +code is to demonstrate use of Bukkit's Conversation API. + +## Example /js Game_NumberGuess.start() -... Begins a number-guessing game where you must guess the number (between 1 and 10) chosen by the computer. - - A basic number-guessing game that uses the Bukkit Conversation API. +Once the game begins, guess a number by typing the `/` character +followed by a number between 1 and 10. + ***/ exports.Game_NumberGuess = { start: function() { diff --git a/src/main/javascript/plugins/minigames/SnowBallFight.js b/src/main/javascript/plugins/minigames/SnowBallFight.js index 0939ab9..9a95c2e 100644 --- a/src/main/javascript/plugins/minigames/SnowBallFight.js +++ b/src/main/javascript/plugins/minigames/SnowBallFight.js @@ -1,38 +1,47 @@ -var events = require('events'); +/************************************************************************* +# SnowballFight mini-game -/* - OK - this is a rough and ready prototype of a simple multi-player shoot-em-up. - Get a bunch of players in close proximity and issue the following commands... +## Description - /js var redTeam = ['','',...etc] - /js var blueTeam = ['',',...etc] - /js var greenTeam = ['',',...etc] - /js new Game_SnowBallFight({red: redTeam,blue: blueTeam,green: greenTeam},60).start(); +This is a rough and ready prototype of a simple multi-player +shoot-em-up. To start a game with all players playing against one another... - Alternatively you can just have all players play against each other... + /js new Game_SnowballFight(60).start(); - /js new SnowBallFight(['player1','player2','player3'],60).start(); +... this obviously works best if all of the players are in close +proximity within the same game world. Alternatively you can have team +matches... - (where etc are the names of actual players) + + /js var redTeam = ['','',...etc] + /js var blueTeam = ['',',...etc] + /js var greenTeam = ['',',...etc] + /js new Game_SnowballFight(60, {red: redTeam,blue: blueTeam,green: greenTeam}).start(); + +Or you can just have specific players play against each other... + + /js new Game_SnowballFight(60, ['player1','player2','player3']).start(); + +(where 'player1' etc are the names of actual players) - You specify the teams in the game as an object where each property's name is a team name and - each property's value is the list of players on that team. - You specify the duration of the game (in seconds) - You kick off the game with the start() method. - I need to work on a better in-game mechanism for players to choose teams and start the game - but this will do for now. +You specify the teams in the game as an object where each property's +name is a team name and each property's value is the list of players +on that team. You specify the duration of the game (in seconds) You +kick off the game with the start() method. I need to work on a +better in-game mechanism for players to choose teams and start the +game but this will do for now. - When the game starts, each player is put in survival mode and given snowballs. The aim of the - game is to hit players on opposing teams. If you hit a player on your own team, you lose a point. +When the game starts, each player is put in survival mode and given +snowballs. The aim of the game is to hit players on opposing teams. If +you hit a player on your own team, you lose a point. - At the end of the game the scores for each team are broadcast. Create a small arena - with a couple of small buildings for cover to make the game more fun :-) +At the end of the game the scores for each team are broadcast and each +player returns to their previous mode of play (creative or +survival). Create a small arena with a couple of small buildings for +cover to make the game more fun. -*/ +***/ -/* - setup game -*/ var _startGame = function(gameState){ // don't let game start if already in progress (wait for game to finish) if (gameState.inProgress){ @@ -104,7 +113,7 @@ var _getTeam = function(player,pteams) { /* construct a new game */ -var _constructor = function(duration, teams) { +var createGame = function(duration, teams) { var _snowBalls = new org.bukkit.inventory.ItemStack(org.bukkit.Material.SNOW_BALL, 64); @@ -160,7 +169,7 @@ var _constructor = function(duration, teams) { return { start: function() { _startGame(_gameState); - _gameState.listener = events.on("entity.EntityDamageByEntityEvent",_onSnowballHit); + _gameState.listener = events.on('entity.EntityDamageByEntityEvent',_onSnowballHit); new java.lang.Thread(function(){ while (_gameState.duration--) java.lang.Thread.sleep(1000); // sleep 1,000 millisecs (1 second) @@ -169,8 +178,6 @@ var _constructor = function(duration, teams) { } }; }; -var SnowBallFight = _constructor; - -exports.Game_SnowBallFight = SnowBallFight; +exports.Game_SnowballFight = createGame;