From 718475d7b0a081fa675683f3b74981309d346cd0 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Tue, 1 Jan 2013 20:27:48 +0000 Subject: [PATCH] changes to drone.js to support methods in standalone mode. --- drone.js | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++----- fort.js | 50 ++++++++------- 2 files changed, 196 insertions(+), 38 deletions(-) diff --git a/drone.js b/drone.js index 7509e7c..7478f5d 100644 --- a/drone.js +++ b/drone.js @@ -1,4 +1,5 @@ var ScriptCraft = ScriptCraft || {}; +var global = this; // // Interface // ========= @@ -18,6 +19,24 @@ var Drone = { // starting point. // If the cross-hairs are _not_ pointing at a block, then the drone's starting // location will be 2 blocks directly in front of the player. + // TIP: Building always happens right and front of the drone's position... + // + // Plan View: + // + // ^ + // | + // | + // D----> + // + // For convenience you can use a 'corner stone' to begin building. + // The corner stone should be located just above ground level. + // If the cross-hair is point at or into ground level when you create a new Drone(), + // then building begins at that point. You can get around this by pointing at a + // 'corner stone' just above ground level or alternatively use the following statement... + // + // /js d = new Drone().up() + // + // ... which will move the drone up one block as soon as it's created. // // [2] d = new Drone(x,y,z,direction) // This will create a new Drone at the location you specified using x, y, z @@ -97,14 +116,22 @@ var Drone = { // // drone.box(6); // - box: function(b,w,h,d){}, + box: function(block,width,height,depth){}, // // like box but empties out the inside - ideal for buildings. // - box0: function(b,w,h,d){}, - prism: function(b,w,d){}, - prism0: function(b,w,d){}, - + box0: function(block,width,height,depth){}, + prism: function(block,width,depth){}, + prism0: function(block,width,depth){}, + // + // create a cylinder - building begins radius blocks to the right and forward. + // + cylinder: function(block,radius,height){}, + // + // create an empty cylinder + // + cylinder0: function(block,radius,height){}, + // miscellaneous // ============= @@ -338,9 +365,9 @@ var Drone = { // block dirs: 0 = east, 1 = west, 2 = south , 3 = north // sign dirs: 5 = east, 3 = south, 4 = west, 2 = north Drone.PLAYER_STAIRS_FACING = [0,2,1,3]; - // for blocks 68 (wall signs) 65 (ladders) 61,62 (furnaces) 23 (dispenser) and 54 (chest) + // for blocks 68 (wall signs) 65 (ladders) 61,62 (furnaces) 23 (dispenser) and 54 (chest) Drone.PLAYER_SIGN_FACING = [4,2,5,3]; - Drone.PLAYER_TORCH_FACING = [2,4,1,3]; + Drone.PLAYER_TORCH_FACING = [2,4,1,3]; Drone.prototype.prism0 = function(block,w,d){ this.prism(block,w,d).fwd().right().prism(0,w-2,d-2).left().back(); @@ -382,7 +409,8 @@ var Drone = { // 012 // d = 3, m = 1 // - Drone.prototype.prism = function(block,w,d){ + Drone.prototype.prism = function(block,w,d) + { var stairEquiv = Drone.STAIRBLOCKS[block]; if (stairEquiv){ this.fwd().prism(stairEquiv,w,d-2).back(); @@ -435,19 +463,111 @@ var Drone = { } return this; }; + Drone.prototype.box = Drone.prototype.cuboid; Drone.prototype.box0 = Drone.prototype.cuboid0; - Drone.prototype.debug = function(){ - this.debug = true; + // + // show the Drone's position and direction + // + Drone.prototype.toString = function(){ var dirs = ["east","south","west","north"]; - print([this.x,this.y,this.z,this.dir,dirs[this.dir]]); + return "x: " + this.x + " y: "+this.y + " z: " + this.z + " dir: " + this.dir + " "+dirs[this.dir]; + }; + Drone.prototype.debug = function(){ + print(this); return this; - } + }; // ======================================================================== // Private variables and functions // ======================================================================== - + var _cylinderX = function(block,radius,height,drone,fill) + { + drone.chkpt('cylinderX'); + var x0, y0, gotoxy; + drone.right(radius).fwd(radius).chkpt('center'); + switch (drone.dir){ + case 0: // east + x0 = drone.z; + y0 = drone.x; + gotoxy = function(xo,yo){ return drone.right(xo).fwd(yo);}; + break; + case 1: // south + x0 = drone.x; + y0 = drone.z; + gotoxy = function(xo,yo){ return drone.right(xo).fwd(0-yo);}; + break; + case 2: // west + x0 = drone.z; + y0 = drone.x; + gotoxy = function(xo,yo){ return drone.right(0-xo).fwd(0-yo);}; + break; + case 3: // north + x0 = drone.x; + y0 = drone.z; + gotoxy = function(xo,yo){ return drone.right(xo).fwd(0-yo);}; + break; + } + var points = []; + var setPixel = function(a,b){ + var xo = (a-x0); + var yo = (b-y0); + if (fill){ + if (xo < 0 && yo < 0){ + // bottom left quadrant + drone.fwd(yo).right(xo) + .box(block,Math.abs(xo*2)+1,height,Math.abs(yo*2)+1) + .back(yo).left(xo); + } + } + gotoxy(xo,yo).box(block,1,height,1).move('center'); + }; + // + // credit: Following code is copied almost verbatim from + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm + // Bresenham's circle algorithm + // + var f = 1 - radius; + var ddF_x = 1; + var ddF_y = -2 * radius; + var x = 0; + var y = radius; + setPixel(x0, y0 + radius); + setPixel(x0, y0 - radius); + setPixel(x0 + radius, y0); + setPixel(x0 - radius, y0); + + while(x < y) + { + // ddF_x == 2 * x + 1; + // ddF_y == -2 * y; + // f == x*x + y*y - radius*radius + 2*x - y + 1; + if(f >= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + setPixel(x0 + x, y0 + y); + setPixel(x0 - x, y0 + y); + setPixel(x0 + x, y0 - y); + setPixel(x0 - x, y0 - y); + setPixel(x0 + y, y0 + x); + setPixel(x0 - y, y0 + x); + setPixel(x0 + y, y0 - x); + setPixel(x0 - y, y0 - x); + } + return drone.move('cylinderX'); + } + var _cylinder0 = function(block,radius,height){ + return _cylinderX(block,radius,height,this,false); + }; + var _cylinder1 = function(block,radius,height){ + return _cylinderX(block,radius,height,this,true); + }; var _getDirFromRotation = function(r){ var result = 1; r = Math.abs(Math.ceil(r)); @@ -537,14 +657,16 @@ var Drone = { // north _traverse[3].width = _traverse[0].depth; _traverse[3].depth = _traverse[2].width; - _traverseHeight = function(that,n,callback){ + var _traverseHeight = function(that,n,callback){ var s = that.y, e = s + n; for (; that.y < e; that.y++){ callback(that.y-s); } that.y = s; }; - + // + // standard fisher-yates shuffle algorithm + // var _fisherYates = function( myArray ) { var i = myArray.length; if ( i == 0 ) return false; @@ -702,8 +824,38 @@ var Drone = { }); return this; }; + Drone.prototype.cylinder0 = _cylinder0; + Drone.prototype.cylinder = _cylinder1; ScriptCraft.Drone = Drone; - + + // + // make all Drone's methods available also as standalone functions + // which return a drone object + // this way drones can be created and used as follows... + // + // /js box(5,7,3,4) + // + // ... which is a short-hand way to create a wooden building 7x3x4 + // + var ops = ['up','down','left','right','fwd','back','turn', + 'chkpt','move', + 'box','box0','prism','prism0','cylinder','cylinder0', + 'door','door2','sign','oak','spruce','birch','jungle', + 'rand','garden', + 'copy','paste' + ]; + for (var i = 0;i < ops.length; i++){ + global[ops[i]] = function(op){ + return function(){ + for (var i = 0;i < arguments.length;i++) + print ("DEBUG:" + arguments[i]); + var result = new Drone(); + result[op].apply(result,arguments); + return result; + }; + }(ops[i]); + } + }()); Drone = ScriptCraft.Drone; /* diff --git a/fort.js b/fort.js index 7302da2..83b0c97 100644 --- a/fort.js +++ b/fort.js @@ -1,55 +1,61 @@ -var scriptDir = $SCRIPT_DIR; -load(scriptDir + "/drone.js"); - -function fort(d, side, h) +load($SCRIPT_DIR + "/drone.js"); +// +// constructs a medieval fort +// +function fort(side, height, drone) { - if (typeof d == "undefined") - d = new Drone(); + if (typeof drone == "undefined") + drone = new Drone(); if (typeof side == "undefined") side = 18; - if (typeof h == "undefined") - h = 6; - if (h < 4 || side < 10) + if (typeof height == "undefined") + height = 6; + if (height < 4 || side < 10) throw new java.lang.RuntimeException("Forts must be at least 9 wide X 4 tall"); // make sure side is even if (side%2) side++; var brick = 98; + // // build walls. - d.chkpt('fort').box0(brick,side,h-1,side); + // + drone.chkpt('fort').box0(brick,side,height-1,side); // // build turrets // - d.up(h-1); + drone.up(height-1); for (i = 0;i <= 3;i++){ var turret = []; - d.box(brick) // solid brick corners + drone.box(brick) // solid brick corners .up().box('50:5').down() // light a torch on each corner .fwd(); - turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[d.dir]); - turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[(d.dir+2)%4]); - d.box(turret,1,1,side-2).fwd(side-2).turn(); + turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[drone.dir]); + turret.push('109:'+ Drone.PLAYER_STAIRS_FACING[(drone.dir+2)%4]); + drone.box(turret,1,1,side-2).fwd(side-2).turn(); } // // build battlements // - d.move('fort'); - d.up(h-2).fwd().right().box('44:5',side-2,1,side-2); + drone.move('fort'); + drone.up(height-2).fwd().right().box('44:5',side-2,1,side-2); var battlementWidth = 3; if (side <= 12) battlementWidth = 2; - d.fwd(battlementWidth).right(battlementWidth).box(0,side-((1+battlementWidth)*2),1,side-((1+battlementWidth)*2)); + drone.fwd(battlementWidth).right(battlementWidth) + .box(0,side-((1+battlementWidth)*2),1,side-((1+battlementWidth)*2)); // // add door // - var torch = '50:' + Drone.PLAYER_TORCH_FACING[d.dir]; - d.move('fort').right((side/2)-1).door2() // double doors + var torch = '50:' + Drone.PLAYER_TORCH_FACING[drone.dir]; + drone.move('fort').right((side/2)-1).door2() // double doors .back().left().up().box(torch) // left torch .right(3).box(torch); // right torch // // add ladder up to battlements // - d.move('fort').right((side/2)-3).fwd(1).box('65:' + Drone.PLAYER_SIGN_FACING[(d.dir+2)%4], 1,h-1,1); - return d.move('fort'); + var ladder = '65:' + Drone.PLAYER_SIGN_FACING[(drone.dir+2)%4]; + drone.move('fort').right((side/2)-3).fwd(1) // move inside fort + .box(ladder, 1,height-1,1); + return drone.move('fort'); };