From b6b589111225f23f1cebfb552b130b5978155372 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Fri, 25 Jan 2013 08:16:35 +0000 Subject: [PATCH 1/5] Added further reading --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f0dd1fa..2e3a352 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,14 @@ the Bukkit ScriptCraft plugin... Further Reading =============== + + * If you want to get started using ScriptCraft to Learn Javascript I recommend [reading this][yp]. + * If you want to delve deeper into creating your own minecraft mod, I recommend [reading this][mm]. + You can find more information about [ScriptCraft on my blog][blog]. [blog]: http://walterhiggins.net/blog/cat-index-scriptcraft.html [buk]: https://github.com/walterhiggins/ScriptCraft/blob/master/bukkit.md +[yp]: http://walterhiggins.net/blog/YoungPersonProgrammingMinecraft +[mm]: http://walterhiggins.net/blog/ScriptCraft-1-Month-later From 460f93ca8d27429153bbdf45235cf190fe371bdd Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Sat, 26 Jan 2013 09:57:43 +0000 Subject: [PATCH 2/5] warn if putSign() is called with block id other than 63 or 68 issue #39 --- src/main/javascript/core/_primitives.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/javascript/core/_primitives.js b/src/main/javascript/core/_primitives.js index 8ae055a..93207aa 100644 --- a/src/main/javascript/core/_primitives.js +++ b/src/main/javascript/core/_primitives.js @@ -52,6 +52,8 @@ var global = this; }; var _putSign = function(texts, x, y, z, blockId, meta){ + if (blockId != 63 && blockId != 68) + throw new Error("Invalid Parameter: blockId must be 63 or 68"); putBlock(x,y,z,blockId,meta); var block = _getBlockObject(x,y,z); state = block.state; From 446ba9ad7bf4b83ddcadcb28b66f948f09baf340 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Sat, 26 Jan 2013 13:47:16 +0000 Subject: [PATCH 3/5] changed to and tweaked tabcomplete --- README.md | 2 +- src/main/javascript/core/_primitives.js | 2 +- src/main/javascript/core/_scriptcraft.js | 4 ++-- src/main/javascript/drone/drone.js | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2e3a352..7bcff9d 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ the Bukkit ScriptCraft plugin... * `__plugin` - the ScriptCraft Plugin itself. This is a useful starting point for accessing other Bukkit objects. The `__plugin` object is of type [org.bukkit.plugin.java.JavaPlugin][api] and all of its properties and methods are accessible. For example... `js __plugin.server.motd` returns the server's message of the day (javascript is more concise than the equivalent java code: __plugin.getServer().getMotd() ). * `self` - The player/command-block or server console operator who invoked the js command. Again, this is a good jumping off point for diving into the Bukkit API. - * `bukkit` - The top-level Bukkit object. See the [Bukkit API docs][bukapi] for reference. + * `server` - The top-level org.bukkit.Server object. See the [Bukkit API docs][bukapi] for reference. [dl]: http://walterhiggins.net/blog/files/scriptcraft/ [api]: http://jd.bukkit.org/apidocs/org/bukkit/plugin/java/JavaPlugin.html diff --git a/src/main/javascript/core/_primitives.js b/src/main/javascript/core/_primitives.js index 93207aa..6341432 100644 --- a/src/main/javascript/core/_primitives.js +++ b/src/main/javascript/core/_primitives.js @@ -56,7 +56,7 @@ var global = this; throw new Error("Invalid Parameter: blockId must be 63 or 68"); putBlock(x,y,z,blockId,meta); var block = _getBlockObject(x,y,z); - state = block.state; + var state = block.state; if (state instanceof org.bukkit.block.Sign){ for (var i = 0;i < texts.length; i++) state.setLine(i%4,texts[i]); diff --git a/src/main/javascript/core/_scriptcraft.js b/src/main/javascript/core/_scriptcraft.js index cc4273e..87848b5 100644 --- a/src/main/javascript/core/_scriptcraft.js +++ b/src/main/javascript/core/_scriptcraft.js @@ -23,7 +23,7 @@ var verbose = verbose || false; /* wph 20130124 - make self, plugin and bukkit public - these are far more useful now that tab-complete works. */ -var bukkit = org.bukkit.Bukkit; +var server = org.bukkit.Bukkit.server; // // private implementation // @@ -241,7 +241,7 @@ var bukkit = org.bukkit.Bukkit; for (var j = 0;j < _javaLangObjectMethods.length; j++) if (_javaLangObjectMethods[j] == i) continue propertyLoop; - if (typeof o[i] == "function") + if (typeof o[i] == "function" ) result.push(i+"()"); else result.push(i); diff --git a/src/main/javascript/drone/drone.js b/src/main/javascript/drone/drone.js index 68e8b4c..67fa155 100644 --- a/src/main/javascript/drone/drone.js +++ b/src/main/javascript/drone/drone.js @@ -341,7 +341,7 @@ var Drone = Drone || { } var bm = _getBlockIdAndMeta(block); block = bm[0]; - meta = bm[1]; + var meta = bm[1]; if (block != 63 && block != 68){ print("ERROR: Invalid block id for use in signs"); return; @@ -653,7 +653,7 @@ var Drone = Drone || { return [parseInt(bs),0]; } b = parseInt(bs.substring(0,sp)); - md = parseInt(bs.substring(sp+1,bs.length)); + var md = parseInt(bs.substring(sp+1,bs.length)); return [b,md]; }else{ return [b,0]; From 1732bf15ddac05b4ead2020ac016c2d2626d3bd8 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Sat, 26 Jan 2013 17:49:11 +0000 Subject: [PATCH 4/5] better tab completion on /jsp issue #35 --- src/main/javascript/alias/alias.js | 132 ++++++++++++----------- src/main/javascript/core/_scriptcraft.js | 44 ++++++-- 2 files changed, 101 insertions(+), 75 deletions(-) diff --git a/src/main/javascript/alias/alias.js b/src/main/javascript/alias/alias.js index 0af7908..c4cf0d7 100644 --- a/src/main/javascript/alias/alias.js +++ b/src/main/javascript/alias/alias.js @@ -1,73 +1,75 @@ plugin("alias", { - help: function(){ - return [ - "/jsp alias set : Set a shortcut/alias for one or more commands (separated by ';')\n" + - "For example: '/jsp alias set sunny time set 4000; weather clear'\n" + - "/jsp sunny (is the same as..\n/time set 4000\n/weather clear", - "/jsp alias delete : Removes a shortcut/alias", - "/jsp alias list : shows a list of the player's command aliases", - "/jsp alias help : Shows this message" - ]; - }, - set: function(player, alias, commands){ - var aliases = this.store.players; - var name = player.name; - aliases[name] = aliases[name] || {}; - aliases[name][alias] = commands; - }, - remove: function(player, alias){ - var aliases = this.store.players; - if (aliases[player.name]) - delete aliases[player.name][alias]; - }, - list: function(player){ - var result = []; - var aliases = this.store.players[player.name]; - for (var a in aliases) - result.push(a + " = " + aliases[a].join(";")); - return result; - } + help: function(){ + return [ + "/jsp alias set : Set a shortcut/alias for one or more commands (separated by ';')\n" + + "For example: '/jsp alias set sunny time set 4000; weather clear'\n" + + "/jsp sunny (is the same as..\n/time set 4000\n/weather clear", + "/jsp alias delete : Removes a shortcut/alias", + "/jsp alias list : shows a list of the player's command aliases", + "/jsp alias help : Shows this message" + ]; + }, + set: function(player, alias, commands){ + var aliases = this.store.players; + var name = player.name; + aliases[name] = aliases[name] || {}; + aliases[name][alias] = commands; + }, + remove: function(player, alias){ + var aliases = this.store.players; + if (aliases[player.name]) + delete aliases[player.name][alias]; + }, + list: function(player){ + var result = []; + var aliases = this.store.players[player.name]; + for (var a in aliases) + result.push(a + " = " + aliases[a].join(";")); + return result; + } },true); alias.store.players = alias.store.players || {}; command("alias",function(params){ - /* - this function also intercepts command options for /jsp - */ - if (params[0] === "help"){ - self.sendMessage(alias.help()); - return; - } - if (params[0] === "set"){ - var aliasCmd = params[1]; - var cmdStr = params.slice(2).join(' '); - var cmds = cmdStr.split(';'); - alias.set(self,aliasCmd,cmds); - return; - } - if (params[0] === "delete"){ - alias.remove(self,params[1]); - return ; - } - if (params[0] === "list"){ - self.sendMessage(alias.list(self)); - return; - } - - var playerHasAliases = alias.store.players[self.name]; - if (!playerHasAliases) - return false; - // is it an alias? - var commands = playerHasAliases[params[0]]; - if (!commands) - return false; - for (var i = 0;i < commands.length; i++){ - // fill in template - var cmd = commands[i]; - cmd = cmd.replace(/{([0-9]*)}/g,function(dummy,index){ return params[index];}) - self.performCommand(cmd); - } - return true; + /* + this function also intercepts command options for /jsp + */ + if (params[0] === "help"){ + self.sendMessage(alias.help()); + return; + } + if (params[0] === "set"){ + var aliasCmd = params[1]; + var cmdStr = params.slice(2).join(' '); + var cmds = cmdStr.split(';'); + alias.set(self,aliasCmd,cmds); + return; + } + if (params[0] === "delete"){ + alias.remove(self,params[1]); + return ; + } + if (params[0] === "list"){ + self.sendMessage(alias.list(self)); + return; + } + if (params.length == 0) + return self.sendMessage(alias.help()); + + var playerHasAliases = alias.store.players[self.name]; + if (!playerHasAliases) + return false; + // is it an alias? + var commands = playerHasAliases[params[0]]; + if (!commands) + return false; + for (var i = 0;i < commands.length; i++){ + // fill in template + var cmd = commands[i]; + cmd = cmd.replace(/{([0-9]*)}/g,function(dummy,index){ return params[index] || "";}) + self.performCommand(cmd); + } + return true; },["help","set","delete","list"],true); diff --git a/src/main/javascript/core/_scriptcraft.js b/src/main/javascript/core/_scriptcraft.js index 87848b5..b759cbe 100644 --- a/src/main/javascript/core/_scriptcraft.js +++ b/src/main/javascript/core/_scriptcraft.js @@ -21,7 +21,7 @@ var global = this; var verbose = verbose || false; /* - wph 20130124 - make self, plugin and bukkit public - these are far more useful now that tab-complete works. + wph 20130124 - make self, plugin and server public - these are far more useful now that tab-complete works. */ var server = org.bukkit.Bukkit.server; // @@ -128,7 +128,6 @@ var server = org.bukkit.Bukkit.server; Save a javascript object to a file (saves using JSON notation) */ var _save = function(object, filename){ - print(filename); var objectToStr = null; try{ objectToStr = JSON.stringify(object); @@ -175,7 +174,8 @@ var server = org.bukkit.Bukkit.server; command management - allow for non-ops to execute approved javascript code. */ var _commands = {}; - var _command = function(name,func,options,intercepts){ + var _command = function(name,func,options,intercepts) + { if (typeof name == "undefined"){ // it's an invocation from the Java Plugin! if (__cmdArgs.length === 0) @@ -266,13 +266,37 @@ var server = org.bukkit.Bukkit.server; var __onTabCompleteJSP = function() { var result = global.__onTC_result; var args = global.__onTC_args; - var cmd = _commands[args[0]]; - if (cmd) - for (var i = 0;i < cmd.options.length; i++) - result.add(cmd.options[i]); - else - for (var i in _commands) - result.add(i); + var cmdInput = args[0]; + var cmd = _commands[cmdInput]; + if (cmd){ + var opts = cmd.options; + var len = opts.length; + if (args.length == 1){ + for (var i = 0;i < len; i++) + result.add(opts[i]); + }else{ + // partial e.g. /jsp chat_color dar + for (var i = 0;i < len; i++){ + if (opts[i].indexOf(args[1]) == 0){ + result.add(opts[i]); + } + } + } + }else{ + if (args.length == 0){ + for (var i in _commands) + result.add(i); + }else{ + // partial e.g. /jsp al + // should tabcomplete to alias + // + for (var c in _commands){ + if (c.indexOf(cmdInput) == 0){ + result.add(c); + } + } + } + } return result; }; /* From 871ae40e3708a1acc8dc75a2c4d9a37557fb485d Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Sat, 26 Jan 2013 22:40:58 +0000 Subject: [PATCH 5/5] ScriptCraft's first Mini-Game git add minigames/SnowBallFight.js git add minigames/SnowBallFight.js --- .../javascript/minigames/SnowBallFight.js | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/javascript/minigames/SnowBallFight.js diff --git a/src/main/javascript/minigames/SnowBallFight.js b/src/main/javascript/minigames/SnowBallFight.js new file mode 100644 index 0000000..5a6f123 --- /dev/null +++ b/src/main/javascript/minigames/SnowBallFight.js @@ -0,0 +1,94 @@ +load(__folder + "events/events.js"); +/* + 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... + + /js var redTeam = ['','',...etc] + /js var blueTeam = ['',',...etc] + /js var greenTeam = ['',',...etc] + /js new SnowBallFight({red: redTeam,blue: blueTeam,green: greenTeam},60).start(); + + (where 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. + + When the game starts, each player is put in survival mode and given 192 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 :-) + +*/ +var SnowBallFight = function(teams,duration) +{ + this.teams = teams; + this.duration = duration; +}; +SnowBallFight.prototype.start = function() +{ + // put all players in survival mode and give them each 200 snowballs + var snowBalls = new org.bukkit.inventory.ItemStack(org.bukkit.Material.SNOW_BALL, 64); + var teamScores = {}; + var gameOver = false; + for (var teamName in this.teams){ + teamScores[teamName] = 0; + var team = this.teams[teamName]; + for (var i = 0;i < team.length;i++) + { + var player = server.getPlayer(team[i]); + player.gameMode = org.bukkit.GameMode.SURVIVAL; + player.inventory.addItem([snowBalls,snowBalls,snowBalls]); + } + } + var that = this; + var _getTeam = function(player){ + for (var teamName in that.teams){ + var team = that.teams[teamName]; + for (var i = 0;i < team.length; i++){ + if (team[i] == player.name) + return teamName; + } + } + return null; + }; + var listener = events.on("entity.EntityDamageByEntityEvent",function(l,e){ + var damager = e.damager; + var damagee = e.entity; + var damage = e.damage; + var shooter = damager.shooter; + if (damager instanceof org.bukkit.entity.Snowball){ + var damagerTeam = _getTeam(shooter); + if (!damagerTeam) + return; // shooter wasn't in game + var damageeTeam = _getTeam(damagee); + if (!damageeTeam) + return; // damagee wasn't in game + + if (damagerTeam != damageeTeam){ + teamScores[damagerTeam]++; + }else{ + teamScores[damagerTeam]--; + } + } + if (gameOver) + e.handlers.unregister(l); + }); + var tick = function(){ + while (that.duration--){ + java.lang.Thread.sleep(1000); + } + if (that.duration <=0){ + for (var tn in teamScores){ + server.broadcastMessage("Team " + tn + " scored " + teamScores[tn]); + } + gameOver = true; + } + }; + new java.lang.Thread(tick).start(); +}; +