Reorganization of Drone from 1 monolithic module to smaller modules.
This commit is contained in:
parent
8056da0d3b
commit
b0e15bfa80
15 changed files with 1370 additions and 1278 deletions
|
@ -1052,51 +1052,29 @@ following code sends a message to any player who breaks a block in the
|
||||||
game...
|
game...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
events.on('block.BlockBreakEvent', function ( event ) {
|
function myBlockDestroyHook( event ){
|
||||||
var breaker = event.player;
|
var breaker = event.player;
|
||||||
breaker.sendMessage('You broke a block');
|
echo( breaker, 'You broke a block');
|
||||||
} );
|
}
|
||||||
|
events.blockDestroy( myBlockDestroyHook );
|
||||||
```
|
```
|
||||||
|
|
||||||
The `events.on()` function is how you *register* a function which you
|
The `events.blockDestroy()` function is just one of the many `events` functions which can be used to *register* a function to be called whenever a particular type of event occurs. In the
|
||||||
want to be called whenever a particular type of event occurs. In the
|
above code the blockDestroy function takes as a parameter a function
|
||||||
above code the first parameter `'block.BlockBreakEvent'` is the type
|
|
||||||
of event I want to listen for and the second parameter is the function
|
|
||||||
I want to be called when that event occurs. The function I want called
|
I want to be called when that event occurs. The function I want called
|
||||||
in turn takes 1 parameter. The `event` object has all the information
|
in turn takes 1 parameter. The `event` object has all the information
|
||||||
about the event which just occurred. I can tell who broke the block
|
about the event which just occurred. I can tell who broke the block
|
||||||
and send a message to the player. The important thing to note is that
|
and send a message to the player. The important thing to note is that
|
||||||
the function defined above will not be called until a player breaks a
|
the `myBlockDestroyHook` function defined above will not be called until a player breaks a
|
||||||
block. Try it - save the above code in a new file in the
|
block. Try it - save the above code in a new file in the
|
||||||
`scriptcraft/plugins` directory then type `/js refresh()` to reload
|
`scriptcraft/plugins` directory then type `/js refresh()` to reload
|
||||||
scriptcraft. Then break a block in the game and you should see the
|
scriptcraft. Then break a block in the game and you should see the
|
||||||
message 'You broke a block'.
|
message 'You broke a block'.
|
||||||
|
|
||||||
There are many types of events you can listen for in Minecraft. You can
|
There are many types of events you can listen for in Minecraft. You can
|
||||||
browse [all possible Bukkit events][bkevts] (click the 'Next
|
browse [all possible Canary events][cmevts] .
|
||||||
Package' and 'Previous Package' links to browse).
|
|
||||||
|
|
||||||
It's important to note that when browsing the Bukkit API's
|
For custom events (events which aren't in the net.canarymod.hook tree)
|
||||||
[org.bukkit.event][bkevts] package, if you see a class called
|
|
||||||
'org.bukkit.events.entity.EntityShootBowEvent', then when calling
|
|
||||||
`events.on()` you can listen to such an event using either the fully
|
|
||||||
qualified Class name...
|
|
||||||
|
|
||||||
events.on(org.bukkit.events.entity.EntityShootBowEvent, function( event ) {
|
|
||||||
...
|
|
||||||
});
|
|
||||||
|
|
||||||
or an abbreviated name in string form...
|
|
||||||
|
|
||||||
events.on('entity.EntityShootBowEvent', function( event ) {
|
|
||||||
...
|
|
||||||
});
|
|
||||||
|
|
||||||
If the `events.on()` function gets a String (text) as its first
|
|
||||||
parameter it automatically converts it to the appropriate Class by
|
|
||||||
prepending the 'org.bukkit.events' package.
|
|
||||||
|
|
||||||
For custom events (events which aren't in the org.bukkit.event tree)
|
|
||||||
just specify the fully qualified class name instead. E.g. ...
|
just specify the fully qualified class name instead. E.g. ...
|
||||||
|
|
||||||
events.on ( net.yourdomain.events.YourEvent, function( event ) {
|
events.on ( net.yourdomain.events.YourEvent, function( event ) {
|
||||||
|
@ -1108,9 +1086,9 @@ just specify the fully qualified class name instead. E.g. ...
|
||||||
If you want an event handler to only execute once, you can remove the handler like this...
|
If you want an event handler to only execute once, you can remove the handler like this...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
events.on('block.BlockBreakEvent', function( evt ) {
|
events.blockDestroy( function( evt ) {
|
||||||
var breaker = evt.player;
|
var breaker = evt.player;
|
||||||
breaker.sendMessage('You broke a block');
|
echo( breaker, 'You broke a block');
|
||||||
this.unregister();
|
this.unregister();
|
||||||
} );
|
} );
|
||||||
```
|
```
|
||||||
|
@ -1124,12 +1102,10 @@ to stop listening for events.
|
||||||
To unregister a listener *outside* of the listener function...
|
To unregister a listener *outside* of the listener function...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var myBlockBreakListener = events.on( 'block.BlockBreakEvent', function( evt ) { ... } );
|
var myBlockBreakListener = events.blockDestroy(function( evt ) { ... } );
|
||||||
...
|
...
|
||||||
myBlockBreakListener.unregister();
|
myBlockBreakListener.unregister();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Keeping Score - Lookup tables in Javascript
|
## Keeping Score - Lookup tables in Javascript
|
||||||
|
|
||||||
In the *Event-Driven Programming* section, I defined a function which
|
In the *Event-Driven Programming* section, I defined a function which
|
||||||
|
@ -1288,6 +1264,7 @@ different objects and methods available for use by ScriptCraft.
|
||||||
[api]: API-Reference.md
|
[api]: API-Reference.md
|
||||||
[twl]: http://www.barebones.com/products/textwrangler/
|
[twl]: http://www.barebones.com/products/textwrangler/
|
||||||
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
|
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
|
||||||
|
[cmevts]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/package-summary.html
|
||||||
[img_echo_date]: img/ypgpm_echo_date.png
|
[img_echo_date]: img/ypgpm_echo_date.png
|
||||||
[img_3d_shapes]: img/ypgpm_3dshapes.jpg
|
[img_3d_shapes]: img/ypgpm_3dshapes.jpg
|
||||||
[img_whd]: img/ypgpm_whd.jpg
|
[img_whd]: img/ypgpm_whd.jpg
|
||||||
|
|
49
src/docs/templates/ypgpm.md
vendored
49
src/docs/templates/ypgpm.md
vendored
|
@ -1016,51 +1016,29 @@ following code sends a message to any player who breaks a block in the
|
||||||
game...
|
game...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
events.on('block.BlockBreakEvent', function ( event ) {
|
function myBlockDestroyHook( event ){
|
||||||
var breaker = event.player;
|
var breaker = event.player;
|
||||||
breaker.sendMessage('You broke a block');
|
echo( breaker, 'You broke a block');
|
||||||
} );
|
}
|
||||||
|
events.blockDestroy( myBlockDestroyHook );
|
||||||
```
|
```
|
||||||
|
|
||||||
The `events.on()` function is how you *register* a function which you
|
The `events.blockDestroy()` function is just one of the many `events` functions which can be used to *register* a function to be called whenever a particular type of event occurs. In the
|
||||||
want to be called whenever a particular type of event occurs. In the
|
above code the blockDestroy function takes as a parameter a function
|
||||||
above code the first parameter `'block.BlockBreakEvent'` is the type
|
|
||||||
of event I want to listen for and the second parameter is the function
|
|
||||||
I want to be called when that event occurs. The function I want called
|
I want to be called when that event occurs. The function I want called
|
||||||
in turn takes 1 parameter. The `event` object has all the information
|
in turn takes 1 parameter. The `event` object has all the information
|
||||||
about the event which just occurred. I can tell who broke the block
|
about the event which just occurred. I can tell who broke the block
|
||||||
and send a message to the player. The important thing to note is that
|
and send a message to the player. The important thing to note is that
|
||||||
the function defined above will not be called until a player breaks a
|
the `myBlockDestroyHook` function defined above will not be called until a player breaks a
|
||||||
block. Try it - save the above code in a new file in the
|
block. Try it - save the above code in a new file in the
|
||||||
`scriptcraft/plugins` directory then type `/js refresh()` to reload
|
`scriptcraft/plugins` directory then type `/js refresh()` to reload
|
||||||
scriptcraft. Then break a block in the game and you should see the
|
scriptcraft. Then break a block in the game and you should see the
|
||||||
message 'You broke a block'.
|
message 'You broke a block'.
|
||||||
|
|
||||||
There are many types of events you can listen for in Minecraft. You can
|
There are many types of events you can listen for in Minecraft. You can
|
||||||
browse [all possible Bukkit events][bkevts] (click the 'Next
|
browse [all possible Canary events][cmevts] .
|
||||||
Package' and 'Previous Package' links to browse).
|
|
||||||
|
|
||||||
It's important to note that when browsing the Bukkit API's
|
For custom events (events which aren't in the net.canarymod.hook tree)
|
||||||
[org.bukkit.event][bkevts] package, if you see a class called
|
|
||||||
'org.bukkit.events.entity.EntityShootBowEvent', then when calling
|
|
||||||
`events.on()` you can listen to such an event using either the fully
|
|
||||||
qualified Class name...
|
|
||||||
|
|
||||||
events.on(org.bukkit.events.entity.EntityShootBowEvent, function( event ) {
|
|
||||||
...
|
|
||||||
});
|
|
||||||
|
|
||||||
or an abbreviated name in string form...
|
|
||||||
|
|
||||||
events.on('entity.EntityShootBowEvent', function( event ) {
|
|
||||||
...
|
|
||||||
});
|
|
||||||
|
|
||||||
If the `events.on()` function gets a String (text) as its first
|
|
||||||
parameter it automatically converts it to the appropriate Class by
|
|
||||||
prepending the 'org.bukkit.events' package.
|
|
||||||
|
|
||||||
For custom events (events which aren't in the org.bukkit.event tree)
|
|
||||||
just specify the fully qualified class name instead. E.g. ...
|
just specify the fully qualified class name instead. E.g. ...
|
||||||
|
|
||||||
events.on ( net.yourdomain.events.YourEvent, function( event ) {
|
events.on ( net.yourdomain.events.YourEvent, function( event ) {
|
||||||
|
@ -1072,9 +1050,9 @@ just specify the fully qualified class name instead. E.g. ...
|
||||||
If you want an event handler to only execute once, you can remove the handler like this...
|
If you want an event handler to only execute once, you can remove the handler like this...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
events.on('block.BlockBreakEvent', function( evt ) {
|
events.blockDestroy( function( evt ) {
|
||||||
var breaker = evt.player;
|
var breaker = evt.player;
|
||||||
breaker.sendMessage('You broke a block');
|
echo( breaker, 'You broke a block');
|
||||||
this.unregister();
|
this.unregister();
|
||||||
} );
|
} );
|
||||||
```
|
```
|
||||||
|
@ -1088,12 +1066,10 @@ to stop listening for events.
|
||||||
To unregister a listener *outside* of the listener function...
|
To unregister a listener *outside* of the listener function...
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var myBlockBreakListener = events.on( 'block.BlockBreakEvent', function( evt ) { ... } );
|
var myBlockBreakListener = events.blockDestroy(function( evt ) { ... } );
|
||||||
...
|
...
|
||||||
myBlockBreakListener.unregister();
|
myBlockBreakListener.unregister();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Keeping Score - Lookup tables in Javascript
|
## Keeping Score - Lookup tables in Javascript
|
||||||
|
|
||||||
In the *Event-Driven Programming* section, I defined a function which
|
In the *Event-Driven Programming* section, I defined a function which
|
||||||
|
@ -1252,6 +1228,7 @@ different objects and methods available for use by ScriptCraft.
|
||||||
[api]: API-Reference.md
|
[api]: API-Reference.md
|
||||||
[twl]: http://www.barebones.com/products/textwrangler/
|
[twl]: http://www.barebones.com/products/textwrangler/
|
||||||
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
|
[bkevts]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/package-summary.html
|
||||||
|
[cmevts]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/package-summary.html
|
||||||
[img_echo_date]: img/ypgpm_echo_date.png
|
[img_echo_date]: img/ypgpm_echo_date.png
|
||||||
[img_3d_shapes]: img/ypgpm_3dshapes.jpg
|
[img_3d_shapes]: img/ypgpm_3dshapes.jpg
|
||||||
[img_whd]: img/ypgpm_whd.jpg
|
[img_whd]: img/ypgpm_whd.jpg
|
||||||
|
|
268
src/main/js/plugins/drone/arc.js
Normal file
268
src/main/js/plugins/drone/arc.js
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
/*global require*/
|
||||||
|
'use strict';
|
||||||
|
/************************************************************************
|
||||||
|
### Drone.arc() method
|
||||||
|
|
||||||
|
The arc() method can be used to create 1 or more 90 degree arcs in the
|
||||||
|
horizontal or vertical planes. This method is called by cylinder() and
|
||||||
|
cylinder0() and the sphere() and sphere0() methods.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
arc() takes a single parameter - an object with the following named properties...
|
||||||
|
|
||||||
|
* radius - The radius of the arc.
|
||||||
|
* blockType - The type of block to use - this is the block Id only (no meta). See [Data Values][dv].
|
||||||
|
* meta - The metadata value. See [Data Values][dv].
|
||||||
|
* orientation (default: 'horizontal' ) - the orientation of the arc - can be 'vertical' or 'horizontal'.
|
||||||
|
* stack (default: 1 ) - the height or length of the arc (depending on the orientation - if orientation is horizontal then this parameter refers to the height, if vertical then it refers to the length ).
|
||||||
|
* strokeWidth (default: 1 ) - the width of the stroke (how many blocks) - if drawing nested arcs it's usually a good idea to set strokeWidth to at least 2 so that there are no gaps between each arc. The arc method uses a [bresenham algorithm][bres] to plot points along the circumference.
|
||||||
|
* fill - If true (or present) then the arc will be filled in.
|
||||||
|
* quadrants (default: `{topleft:true,topright:true,bottomleft:true,bottomright:true}` - An object with 4 properties indicating which of the 4 quadrants of a circle to draw. If the quadrants property is absent then all 4 quadrants are drawn.
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
To draw a 1/4 circle (top right quadrant only) with a radius of 10 and
|
||||||
|
stroke width of 2 blocks ...
|
||||||
|
|
||||||
|
arc({blockType: blocks.iron,
|
||||||
|
meta: 0,
|
||||||
|
radius: 10,
|
||||||
|
strokeWidth: 2,
|
||||||
|
quadrants: { topright: true },
|
||||||
|
orientation: 'vertical',
|
||||||
|
stack: 1,
|
||||||
|
fill: false
|
||||||
|
} );
|
||||||
|
|
||||||
|
![arc example 1](img/arcex1.png)
|
||||||
|
|
||||||
|
[bres]: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
|
||||||
|
[dv]: http://www.minecraftwiki.net/wiki/Data_values
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/*
|
||||||
|
do the bresenham thing
|
||||||
|
*/
|
||||||
|
function bresenham( x0,y0,radius, setPixel, quadrants ) {
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
var defaultQuadrants = {topleft: true, topright: true, bottomleft: true, bottomright: true};
|
||||||
|
quadrants = quadrants?quadrants:defaultQuadrants;
|
||||||
|
/*
|
||||||
|
II | I
|
||||||
|
------------
|
||||||
|
III | IV
|
||||||
|
*/
|
||||||
|
if ( quadrants.topleft || quadrants.topright )
|
||||||
|
setPixel(x0, y0 + radius ); // quadrant I/II topmost
|
||||||
|
if ( quadrants.bottomleft || quadrants.bottomright )
|
||||||
|
setPixel(x0, y0 - radius ); // quadrant III/IV bottommost
|
||||||
|
if ( quadrants.topright || quadrants.bottomright )
|
||||||
|
setPixel(x0 + radius, y0 ); // quadrant I/IV rightmost
|
||||||
|
if ( quadrants.topleft || quadrants.bottomleft )
|
||||||
|
setPixel(x0 - radius, y0 ); // quadrant II/III leftmost
|
||||||
|
|
||||||
|
while ( x < y ) {
|
||||||
|
if(f >= 0 ) {
|
||||||
|
y--;
|
||||||
|
ddF_y += 2;
|
||||||
|
f += ddF_y;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
ddF_x += 2;
|
||||||
|
f += ddF_x;
|
||||||
|
if ( quadrants.topright ) {
|
||||||
|
setPixel(x0 + x, y0 + y ); // quadrant I
|
||||||
|
setPixel(x0 + y, y0 + x ); // quadrant I
|
||||||
|
}
|
||||||
|
if ( quadrants.topleft ) {
|
||||||
|
setPixel(x0 - x, y0 + y ); // quadrant II
|
||||||
|
setPixel(x0 - y, y0 + x ); // quadrant II
|
||||||
|
}
|
||||||
|
if ( quadrants.bottomleft ) {
|
||||||
|
setPixel(x0 - x, y0 - y ); // quadrant III
|
||||||
|
setPixel(x0 - y, y0 - x ); // quadrant III
|
||||||
|
}
|
||||||
|
if ( quadrants.bottomright ) {
|
||||||
|
setPixel(x0 + x, y0 - y ); // quadrant IV
|
||||||
|
setPixel(x0 + y, y0 - x ); // quadrant IV
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getStrokeDir( x,y ) {
|
||||||
|
var absY = Math.abs(y );
|
||||||
|
var absX = Math.abs(x );
|
||||||
|
var strokeDir = 0;
|
||||||
|
if ( y > 0 && absY >= absX )
|
||||||
|
strokeDir = 0 ; //down
|
||||||
|
else if ( y < 0 && absY >= absX )
|
||||||
|
strokeDir = 1 ; // up
|
||||||
|
else if ( x > 0 && absX >= absY )
|
||||||
|
strokeDir = 2 ; // left
|
||||||
|
else if ( x < 0 && absX >= absY )
|
||||||
|
strokeDir = 3 ; // right
|
||||||
|
return strokeDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
The daddy of all arc-related API calls -
|
||||||
|
if you're drawing anything that bends it ends up here.
|
||||||
|
*/
|
||||||
|
function arcImpl( params ) {
|
||||||
|
var drone = params.drone;
|
||||||
|
var orientation = params.orientation?params.orientation:'horizontal';
|
||||||
|
var quadrants = params.quadrants?params.quadrants:{
|
||||||
|
topright:1,
|
||||||
|
topleft:2,
|
||||||
|
bottomleft:3,
|
||||||
|
bottomright:4
|
||||||
|
};
|
||||||
|
var stack = params.stack?params.stack:1;
|
||||||
|
var radius = params.radius;
|
||||||
|
var strokeWidth = params.strokeWidth?params.strokeWidth:1;
|
||||||
|
drone.chkpt('arc2' );
|
||||||
|
var x0, y0, gotoxy,setPixel;
|
||||||
|
|
||||||
|
if ( orientation == 'horizontal' ) {
|
||||||
|
gotoxy = function( x,y ) { return drone.right(x ).fwd(y );};
|
||||||
|
drone.right(radius ).fwd(radius ).chkpt('center' );
|
||||||
|
switch ( drone.dir ) {
|
||||||
|
case 0: // east
|
||||||
|
case 2: // west
|
||||||
|
x0 = drone.z;
|
||||||
|
y0 = drone.x;
|
||||||
|
break;
|
||||||
|
case 1: // south
|
||||||
|
case 3: // north
|
||||||
|
x0 = drone.x;
|
||||||
|
y0 = drone.z;
|
||||||
|
}
|
||||||
|
setPixel = function( x, y ) {
|
||||||
|
x = ( x-x0 );
|
||||||
|
y = ( y-y0 );
|
||||||
|
if ( params.fill ) {
|
||||||
|
// wph 20130114 more efficient esp. for large cylinders/spheres
|
||||||
|
if ( y < 0 ) {
|
||||||
|
drone
|
||||||
|
.fwd( y ).right( x )
|
||||||
|
.cuboidX( params.blockType, params.meta, 1, stack, Math.abs( y * 2 ) + 1 )
|
||||||
|
.back( y ).left( x );
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if ( strokeWidth == 1 ) {
|
||||||
|
gotoxy(x,y )
|
||||||
|
.cuboidX( params.blockType, params.meta,
|
||||||
|
1, // width
|
||||||
|
stack, // height
|
||||||
|
strokeWidth // depth
|
||||||
|
)
|
||||||
|
.move('center' );
|
||||||
|
} else {
|
||||||
|
var strokeDir = getStrokeDir( x, y );
|
||||||
|
var width = 1, depth = 1;
|
||||||
|
switch ( strokeDir ) {
|
||||||
|
case 0: // down
|
||||||
|
y = y-( strokeWidth - 1 );
|
||||||
|
depth = strokeWidth;
|
||||||
|
break;
|
||||||
|
case 1: // up
|
||||||
|
depth = strokeWidth;
|
||||||
|
break;
|
||||||
|
case 2: // left
|
||||||
|
width = strokeWidth;
|
||||||
|
x = x-(strokeWidth-1 );
|
||||||
|
break;
|
||||||
|
case 3: // right
|
||||||
|
width = strokeWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gotoxy( x, y )
|
||||||
|
.cuboidX( params.blockType, params.meta, width, stack, depth )
|
||||||
|
.move( 'center' );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
// vertical
|
||||||
|
gotoxy = function( x,y ) { return drone.right(x ).up(y );};
|
||||||
|
drone.right(radius ).up(radius ).chkpt('center' );
|
||||||
|
switch ( drone.dir ) {
|
||||||
|
case 0: // east
|
||||||
|
case 2: // west
|
||||||
|
x0 = drone.z;
|
||||||
|
y0 = drone.y;
|
||||||
|
break;
|
||||||
|
case 1: // south
|
||||||
|
case 3: // north
|
||||||
|
x0 = drone.x;
|
||||||
|
y0 = drone.y;
|
||||||
|
}
|
||||||
|
setPixel = function( x, y ) {
|
||||||
|
x = ( x - x0 );
|
||||||
|
y = ( y - y0 );
|
||||||
|
if ( params.fill ) {
|
||||||
|
// wph 20130114 more efficient esp. for large cylinders/spheres
|
||||||
|
if ( y < 0 ) {
|
||||||
|
drone
|
||||||
|
.up( y ).right( x )
|
||||||
|
.cuboidX( params.blockType, params.meta, 1, Math.abs( y * 2 ) + 1, stack )
|
||||||
|
.down( y ).left( x );
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if ( strokeWidth == 1 ) {
|
||||||
|
gotoxy( x, y )
|
||||||
|
.cuboidX( params.blockType, params.meta, strokeWidth, 1, stack )
|
||||||
|
.move( 'center' );
|
||||||
|
}else{
|
||||||
|
var strokeDir = getStrokeDir( x,y );
|
||||||
|
var width = 1, height = 1;
|
||||||
|
switch ( strokeDir ) {
|
||||||
|
case 0: // down
|
||||||
|
y = y - ( strokeWidth - 1 );
|
||||||
|
height = strokeWidth;
|
||||||
|
break;
|
||||||
|
case 1: // up
|
||||||
|
height = strokeWidth;
|
||||||
|
break;
|
||||||
|
case 2: // left
|
||||||
|
width = strokeWidth;
|
||||||
|
x = x - ( strokeWidth - 1 );
|
||||||
|
break;
|
||||||
|
case 3: // right
|
||||||
|
width = strokeWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gotoxy(x,y )
|
||||||
|
.cuboidX(params.blockType, params.meta, width, height, stack )
|
||||||
|
.move('center' );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
setPixel assumes a 2D plane - need to put a block along appropriate plane
|
||||||
|
*/
|
||||||
|
bresenham(x0,y0,radius,setPixel,quadrants );
|
||||||
|
|
||||||
|
params.drone.move('arc2' );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Drone.extend(function arc( params ) {
|
||||||
|
params.drone = this;
|
||||||
|
arcImpl(params );
|
||||||
|
} );
|
|
@ -1,32 +1,44 @@
|
||||||
var Drone = require('../drone').Drone;
|
'use strict';
|
||||||
var bkMaterial = org.bukkit.Material;
|
/*global require, __plugin, org*/
|
||||||
|
var Drone = require('../drone').Drone,
|
||||||
|
bkMaterial = org.bukkit.Material,
|
||||||
|
blocks = require('blocks');
|
||||||
|
|
||||||
function canHang( material ) {
|
function canHang( block ) {
|
||||||
|
|
||||||
if ( material.equals(bkMaterial.AIR) ||
|
if (__plugin.bukkit){
|
||||||
material.equals(bkMaterial.VINE) ) {
|
if ( block.type.equals(bkMaterial.AIR) ||
|
||||||
|
block.type.equals(bkMaterial.VINE) ) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (__plugin.canary){
|
||||||
|
if (block.typeId == blocks.air ||
|
||||||
|
block.typeid == blocks.vines ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
function hangtorch() {
|
function hangtorch() {
|
||||||
var torch = '50:' + Drone.PLAYER_TORCH_FACING[this.dir];
|
var torch = '50:' + Drone.PLAYER_TORCH_FACING[this.dir];
|
||||||
var moves = 0;
|
var moves = 0;
|
||||||
var block = this.world.getBlockAt(this.x, this.y, this.z);
|
var block = this.getBlock();
|
||||||
|
|
||||||
while ( !canHang(block.type) ){
|
while ( !canHang(block) ){
|
||||||
|
|
||||||
moves++;
|
moves++;
|
||||||
this.back();
|
this.back();
|
||||||
if (moves == 10){
|
if (moves == 10){
|
||||||
this.fwd(moves);
|
this
|
||||||
|
.fwd(moves);
|
||||||
console.log('nowhere to hang torch');
|
console.log('nowhere to hang torch');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
block = this.world.getBlockAt(this.x, this.y, this.z);
|
block = this.getBlock();
|
||||||
}
|
}
|
||||||
this.box(torch)
|
this
|
||||||
|
.box(torch)
|
||||||
.fwd(moves);
|
.fwd(moves);
|
||||||
}
|
}
|
||||||
Drone.extend(hangtorch);
|
Drone.extend(hangtorch);
|
||||||
|
|
143
src/main/js/plugins/drone/copypaste.js
Normal file
143
src/main/js/plugins/drone/copypaste.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require*/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/************************************************************************
|
||||||
|
### Copy & Paste using Drone
|
||||||
|
|
||||||
|
A drone can be used to copy and paste areas of the game world.
|
||||||
|
|
||||||
|
### Drone.copy() method
|
||||||
|
|
||||||
|
Copies an area so it can be pasted elsewhere. The name can be used for
|
||||||
|
pasting the copied area elsewhere...
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* name - the name to be given to the copied area (used by `paste`)
|
||||||
|
* width - the width of the area to copy
|
||||||
|
* height - the height of the area to copy
|
||||||
|
* length - the length of the area (extending away from the drone) to copy
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
drone.copy('somethingCool',10,5,10 ).right(12 ).paste('somethingCool' );
|
||||||
|
|
||||||
|
### Drone.paste() method
|
||||||
|
|
||||||
|
Pastes a copied area to the current location.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To copy a 10x5x10 area (using the drone's coordinates as the starting
|
||||||
|
point) into memory. the copied area can be referenced using the name
|
||||||
|
'somethingCool'. The drone moves 12 blocks right then pastes the copy.
|
||||||
|
|
||||||
|
drone.copy('somethingCool',10,5,10 )
|
||||||
|
.right(12 )
|
||||||
|
.paste('somethingCool' );
|
||||||
|
|
||||||
|
***/
|
||||||
|
function paste( name, immediate )
|
||||||
|
{
|
||||||
|
var ccContent = Drone.clipBoard[name];
|
||||||
|
if (ccContent == undefined){
|
||||||
|
console.warn('Nothing called ' + name + ' in clipboard!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var srcBlocks = ccContent.blocks;
|
||||||
|
var srcDir = ccContent.dir; // direction player was facing when copied.
|
||||||
|
var dirOffset = (4 + (this.dir - srcDir ) ) %4;
|
||||||
|
|
||||||
|
this.traverseWidth(srcBlocks.length,function( ww ) {
|
||||||
|
var h = srcBlocks[ww].length;
|
||||||
|
this.traverseHeight(h,function( hh ) {
|
||||||
|
var d = srcBlocks[ww][hh].length;
|
||||||
|
this.traverseDepth(d,function( dd ) {
|
||||||
|
var b = srcBlocks[ww][hh][dd],
|
||||||
|
cb = b.type,
|
||||||
|
md = b.data,
|
||||||
|
newDir,
|
||||||
|
dir,
|
||||||
|
a,
|
||||||
|
len;
|
||||||
|
//
|
||||||
|
// need to adjust blocks which face a direction
|
||||||
|
//
|
||||||
|
switch ( cb ) {
|
||||||
|
//
|
||||||
|
// doors
|
||||||
|
//
|
||||||
|
case 64: // wood
|
||||||
|
case 71: // iron
|
||||||
|
// top half of door doesn't need to change
|
||||||
|
if ( md < 8 ) {
|
||||||
|
md = (md + dirOffset ) % 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
// stairs
|
||||||
|
//
|
||||||
|
case 53: // oak
|
||||||
|
case 67: // cobblestone
|
||||||
|
case 108: // red brick
|
||||||
|
case 109: // stone brick
|
||||||
|
case 114: // nether brick
|
||||||
|
case 128: // sandstone
|
||||||
|
case 134: // spruce
|
||||||
|
case 135: // birch
|
||||||
|
case 136: // junglewood
|
||||||
|
dir = md & 0x3;
|
||||||
|
a = Drone.PLAYER_STAIRS_FACING;
|
||||||
|
len = a.length;
|
||||||
|
for ( var c=0;c < len;c++ ) {
|
||||||
|
if ( a[c] == dir ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = (c + dirOffset ) %4;
|
||||||
|
newDir = a[c];
|
||||||
|
md = (md >>2<<2 ) + newDir;
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
// signs , ladders etc
|
||||||
|
//
|
||||||
|
case 23: // dispenser
|
||||||
|
case 54: // chest
|
||||||
|
case 61: // furnace
|
||||||
|
case 62: // burning furnace
|
||||||
|
case 65: // ladder
|
||||||
|
case 68: // wall sign
|
||||||
|
a = Drone.PLAYER_SIGN_FACING;
|
||||||
|
len = a.length;
|
||||||
|
for ( var c=0;c < len;c++ ) {
|
||||||
|
if ( a[c] == md ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = (c + dirOffset ) %4;
|
||||||
|
newDir = a[c];
|
||||||
|
md = newDir;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setBlock(cb,md);
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
function copy( name, w, h, d ) {
|
||||||
|
var ccContent = [];
|
||||||
|
this.traverseWidth(w,function( ww ) {
|
||||||
|
ccContent.push([] );
|
||||||
|
this.traverseHeight(h,function( hh ) {
|
||||||
|
ccContent[ww].push([] );
|
||||||
|
this.traverseDepth(d,function( dd ) {
|
||||||
|
var b = this.getBlock();
|
||||||
|
ccContent[ww][hh][dd] = {type:b.getTypeId(), data:b.data};
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
Drone.clipBoard[name] = {dir: this.dir, blocks: ccContent};
|
||||||
|
}
|
||||||
|
Drone.clipBoard = {};
|
||||||
|
Drone.extend( copy );
|
||||||
|
Drone.extend( paste );
|
75
src/main/js/plugins/drone/cylinders.js
Normal file
75
src/main/js/plugins/drone/cylinders.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
### Drone.cylinder() method
|
||||||
|
|
||||||
|
A convenience method for building cylinders. Building begins radius blocks to the right and forward.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* block - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling. Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch`
|
||||||
|
* radius
|
||||||
|
* height
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create a cylinder of Iron 7 blocks in radius and 1 block high...
|
||||||
|
|
||||||
|
cylinder(blocks.iron, 7 , 1);
|
||||||
|
|
||||||
|
![cylinder example](img/cylinderex1.png)
|
||||||
|
|
||||||
|
### Drone.cylinder0() method
|
||||||
|
|
||||||
|
A version of cylinder that hollows out the middle.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create a hollow cylinder of Iron 7 blocks in radius and 1 block high...
|
||||||
|
|
||||||
|
cylinder0(blocks.iron, 7, 1);
|
||||||
|
|
||||||
|
![cylinder0 example](img/cylinder0ex1.png)
|
||||||
|
|
||||||
|
***/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
function cylinder0( block,radius,height,exactParams ) {
|
||||||
|
var arcParams = {
|
||||||
|
radius: radius,
|
||||||
|
fill: false,
|
||||||
|
orientation: 'horizontal',
|
||||||
|
stack: height
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( exactParams ) {
|
||||||
|
for ( var p in exactParams ) {
|
||||||
|
arcParams[p] = exactParams[p];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
var md = this._getBlockIdAndMeta(block );
|
||||||
|
arcParams.blockType = md[0];
|
||||||
|
arcParams.meta = md[1];
|
||||||
|
}
|
||||||
|
return this.arc(arcParams );
|
||||||
|
};
|
||||||
|
function cylinder( block,radius,height,exactParams ) {
|
||||||
|
var arcParams = {
|
||||||
|
radius: radius,
|
||||||
|
fill: true,
|
||||||
|
orientation: 'horizontal',
|
||||||
|
stack: height
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( exactParams ) {
|
||||||
|
arcParams.blockType = exactParams.blockType;
|
||||||
|
arcParams.meta = exactParams.meta;
|
||||||
|
}else{
|
||||||
|
var md = this._getBlockIdAndMeta(block );
|
||||||
|
arcParams.blockType = md[0];
|
||||||
|
arcParams.meta = md[1];
|
||||||
|
}
|
||||||
|
return this.arc(arcParams );
|
||||||
|
};
|
||||||
|
|
||||||
|
Drone.extend(cylinder0 );
|
||||||
|
Drone.extend(cylinder );
|
96
src/main/js/plugins/drone/doors.js
Normal file
96
src/main/js/plugins/drone/doors.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*************************************************************************
|
||||||
|
### Drone.door() method
|
||||||
|
|
||||||
|
create a door - if a parameter is supplied an Iron door is created otherwise a wooden door is created.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* doorType (optional - default wood) - If a parameter is provided then the door is Iron.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create a wooden door at the crosshairs/drone's location...
|
||||||
|
|
||||||
|
var drone = new Drone();
|
||||||
|
drone.door();
|
||||||
|
|
||||||
|
To create an iron door...
|
||||||
|
|
||||||
|
drone.door( blocks.door_iron );
|
||||||
|
|
||||||
|
![iron door](img/doorex1.png)
|
||||||
|
|
||||||
|
### Drone.door_iron() method
|
||||||
|
|
||||||
|
create an Iron door.
|
||||||
|
|
||||||
|
### Drone.door2() method
|
||||||
|
|
||||||
|
Create double doors (left and right side)
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* doorType (optional - default wood) - If a parameter is provided then the door is Iron.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create double-doors at the cross-hairs/drone's location...
|
||||||
|
|
||||||
|
drone.door2();
|
||||||
|
|
||||||
|
![double doors](img/door2ex1.png)
|
||||||
|
|
||||||
|
### Drone.door2_iron() method
|
||||||
|
|
||||||
|
Create double iron doors
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/*global require*/
|
||||||
|
function door( doorMaterial, hinge) {
|
||||||
|
if ( typeof doorMaterial == 'undefined' ) {
|
||||||
|
doorMaterial = 64; // wood
|
||||||
|
}
|
||||||
|
if (typeof hinge == 'undefined') {
|
||||||
|
hinge = 'left';
|
||||||
|
}
|
||||||
|
this.then(function(){
|
||||||
|
this.setBlock(doorMaterial, this.dir);
|
||||||
|
this.setBlock(doorMaterial, hinge=='left' ? 8 : 9, 0,1,0);
|
||||||
|
if ( this.bountiful ){
|
||||||
|
// 1.8
|
||||||
|
var prop = require('blockhelper').property;
|
||||||
|
var lower = this.getBlock();
|
||||||
|
var upper = this.getBlock();
|
||||||
|
prop(upper)
|
||||||
|
.set('half','upper')
|
||||||
|
.set('hinge',hinge);
|
||||||
|
prop(lower)
|
||||||
|
.set('facing',this.dir)
|
||||||
|
.set('half','lower');
|
||||||
|
|
||||||
|
upper.update();
|
||||||
|
lower.update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Drone.extend( door );
|
||||||
|
|
||||||
|
Drone.extend( function door_iron( ) {
|
||||||
|
this.door(71);
|
||||||
|
} );
|
||||||
|
|
||||||
|
Drone.extend( function door2( doorMaterial ) {
|
||||||
|
if ( typeof doorMaterial == 'undefined' ) {
|
||||||
|
doorMaterial = 64;
|
||||||
|
}
|
||||||
|
this
|
||||||
|
.door( doorMaterial, 'left')
|
||||||
|
.right()
|
||||||
|
.door( doorMaterial, 'right')
|
||||||
|
.left();
|
||||||
|
} );
|
||||||
|
Drone.extend( function door2_iron( ) {
|
||||||
|
this.door2( 71 );
|
||||||
|
} );
|
File diff suppressed because it is too large
Load diff
46
src/main/js/plugins/drone/garden.js
Normal file
46
src/main/js/plugins/drone/garden.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/************************************************************************
|
||||||
|
### Drone.garden() method
|
||||||
|
|
||||||
|
places random flowers and long grass (similar to the effect of placing bonemeal on grass)
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* width - the width of the garden
|
||||||
|
* length - how far from the drone the garden extends
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create a garden 10 blocks wide by 5 blocks long...
|
||||||
|
|
||||||
|
garden(10,5);
|
||||||
|
|
||||||
|
![garden example](img/gardenex1.png)
|
||||||
|
|
||||||
|
***/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
var blocks = require('blocks');
|
||||||
|
|
||||||
|
function garden( width, depth ) {
|
||||||
|
if ( typeof width == 'undefined' ) {
|
||||||
|
width = 10;
|
||||||
|
}
|
||||||
|
if ( typeof depth == 'undefined' ) {
|
||||||
|
depth = width;
|
||||||
|
}
|
||||||
|
// make sure grass is present first
|
||||||
|
this
|
||||||
|
.box( blocks.grass, width, 1, depth )
|
||||||
|
.up();
|
||||||
|
|
||||||
|
// make flowers more common than long grass
|
||||||
|
var dist = { };
|
||||||
|
dist[blocks.rose] = 3;
|
||||||
|
dist[blocks.dandelion] = 3;
|
||||||
|
dist[blocks.grass_tall] = 2;
|
||||||
|
dist[blocks.air] = 1;
|
||||||
|
|
||||||
|
this
|
||||||
|
.rand( dist, width, 1, depth, false /* don't overwrite */ )
|
||||||
|
.down();
|
||||||
|
}
|
||||||
|
Drone.extend(garden);
|
185
src/main/js/plugins/drone/movement.js
Normal file
185
src/main/js/plugins/drone/movement.js
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require,__plugin*/
|
||||||
|
var Drone = require('./drone').Drone,
|
||||||
|
bkLocation = org.bukkit.Location;
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
### Drone Movement
|
||||||
|
|
||||||
|
Drones can move freely in minecraft's 3-D world. You control the
|
||||||
|
Drone's movement using any of the following methods..
|
||||||
|
|
||||||
|
* up()
|
||||||
|
* down()
|
||||||
|
* left()
|
||||||
|
* right()
|
||||||
|
* fwd()
|
||||||
|
* back()
|
||||||
|
* turn()
|
||||||
|
|
||||||
|
... Each of these methods takes a single optional parameter
|
||||||
|
`numBlocks` - the number of blocks to move in the given direction. If
|
||||||
|
no parameter is given, the default is 1.
|
||||||
|
|
||||||
|
To change direction use the `turn()` method which also takes a single
|
||||||
|
optional parameter (numTurns) - the number of 90 degree turns to
|
||||||
|
make. Turns are always clock-wise. If the drone is facing north, then
|
||||||
|
drone.turn() will make the turn face east. If the drone is facing east
|
||||||
|
then drone.turn(2) will make the drone turn twice so that it is facing
|
||||||
|
west.
|
||||||
|
|
||||||
|
### Drone Positional Info
|
||||||
|
|
||||||
|
* getLocation() - Returns a native Java Location object for the drone
|
||||||
|
|
||||||
|
### Drone Markers
|
||||||
|
|
||||||
|
Markers are useful when your Drone has to do a lot of work. You can
|
||||||
|
set a check-point and return to the check-point using the move()
|
||||||
|
method. If your drone is about to undertake a lot of work -
|
||||||
|
e.g. building a road, skyscraper or forest you should set a
|
||||||
|
check-point before doing so if you want your drone to return to its
|
||||||
|
current location.
|
||||||
|
|
||||||
|
A 'start' checkpoint is automatically created when the Drone is first created.
|
||||||
|
|
||||||
|
Markers are created and returned to using the followng two methods...
|
||||||
|
|
||||||
|
* chkpt - Saves the drone's current location so it can be returned to later.
|
||||||
|
* move - moves the drone to a saved location. Alternatively you can provide a Java Location object or x,y,z and direction parameters.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* name - the name of the checkpoint to save or return to.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
drone.chkpt('town-square');
|
||||||
|
//
|
||||||
|
// the drone can now go off on a long excursion
|
||||||
|
//
|
||||||
|
for ( i = 0; i< 100; i++) {
|
||||||
|
drone.fwd(12).box(6);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// return to the point before the excursion
|
||||||
|
//
|
||||||
|
drone.move('town-square');
|
||||||
|
|
||||||
|
***/
|
||||||
|
var _movements = [{},{},{},{}];
|
||||||
|
// east
|
||||||
|
_movements[0].right = function( drone,n ) { drone.z +=n; return drone;};
|
||||||
|
_movements[0].left = function( drone,n ) { drone.z -=n; return drone;};
|
||||||
|
_movements[0].fwd = function( drone,n ) { drone.x +=n; return drone;};
|
||||||
|
_movements[0].back = function( drone,n ) { drone.x -= n; return drone;};
|
||||||
|
// south
|
||||||
|
_movements[1].right = _movements[0].back;
|
||||||
|
_movements[1].left = _movements[0].fwd;
|
||||||
|
_movements[1].fwd = _movements[0].right;
|
||||||
|
_movements[1].back = _movements[0].left;
|
||||||
|
// west
|
||||||
|
_movements[2].right = _movements[0].left;
|
||||||
|
_movements[2].left = _movements[0].right;
|
||||||
|
_movements[2].fwd = _movements[0].back;
|
||||||
|
_movements[2].back = _movements[0].fwd;
|
||||||
|
// north
|
||||||
|
_movements[3].right = _movements[0].fwd;
|
||||||
|
_movements[3].left = _movements[0].back;
|
||||||
|
_movements[3].fwd = _movements[0].left;
|
||||||
|
_movements[3].back = _movements[0].right;
|
||||||
|
|
||||||
|
Drone.prototype._checkpoints = {};
|
||||||
|
Drone.extend(function chkpt( name ) {
|
||||||
|
this._checkpoints[ name ] = { x:this.x, y:this.y, z:this.z, dir:this.dir };
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend(function move( ) {
|
||||||
|
if ( arguments[0].x && arguments[0].y && arguments[0].z) {
|
||||||
|
this.x = arguments[0].x;
|
||||||
|
this.y = arguments[0].y;
|
||||||
|
this.z = arguments[0].z;
|
||||||
|
this.dir = Drone.getDirFromRotation(arguments[0] );
|
||||||
|
this.world = arguments[0].world;
|
||||||
|
} else if ( typeof arguments[0] === 'string' ) {
|
||||||
|
var coords = this._checkpoints[arguments[0]];
|
||||||
|
if ( coords ) {
|
||||||
|
this.x = coords.x;
|
||||||
|
this.y = coords.y;
|
||||||
|
this.z = coords.z;
|
||||||
|
this.dir = coords.dir%4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// expect x,y,z,dir
|
||||||
|
switch( arguments.length ) {
|
||||||
|
case 4:
|
||||||
|
this.dir = arguments[3];
|
||||||
|
case 3:
|
||||||
|
this.z = arguments[2];
|
||||||
|
case 2:
|
||||||
|
this.y = arguments[1];
|
||||||
|
case 1:
|
||||||
|
this.x = arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function turn( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
this.dir += n;
|
||||||
|
this.dir %=4;
|
||||||
|
} );
|
||||||
|
|
||||||
|
Drone.extend( function right( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
_movements[ this.dir ].right( this, n );
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function left( n ) {
|
||||||
|
if ( typeof n == 'undefined') {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
_movements[ this.dir ].left( this, n );
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function fwd( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
_movements[ this.dir ].fwd( this, n );
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function back( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
_movements[ this.dir ].back( this, n );
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function up( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
this.y+= n;
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.extend( function down( n ) {
|
||||||
|
if ( typeof n == 'undefined' ) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
this.y-= n;
|
||||||
|
});
|
||||||
|
|
||||||
|
Drone.prototype.getLocation = function( ) {
|
||||||
|
if (__plugin.canary) {
|
||||||
|
var cmLocation = Packages.net.canarymod.api.world.position.Location;
|
||||||
|
return new cmLocation( this.world, this.x, this.y, this.z, 0, 0);
|
||||||
|
}
|
||||||
|
if (__plugin.bukkit) {
|
||||||
|
return new bkLocation( this.world, this.x, this.y, this.z );
|
||||||
|
}
|
||||||
|
};
|
97
src/main/js/plugins/drone/prism.js
Normal file
97
src/main/js/plugins/drone/prism.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require*/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/************************************************************************
|
||||||
|
### Drone.prism() method
|
||||||
|
|
||||||
|
Creates a prism. This is useful for roofs on houses.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* block - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling.
|
||||||
|
Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch`
|
||||||
|
* width - the width of the prism
|
||||||
|
* length - the length of the prism (will be 2 time its height)
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
prism(blocks.oak,3,12);
|
||||||
|
|
||||||
|
![prism example](img/prismex1.png)
|
||||||
|
|
||||||
|
### Drone.prism0() method
|
||||||
|
|
||||||
|
A variation on `prism` which hollows out the inside of the prism. It
|
||||||
|
uses the same parameters as `prism`.
|
||||||
|
|
||||||
|
***/
|
||||||
|
var STAIRBLOCKS = {
|
||||||
|
53: '5:0' // oak wood
|
||||||
|
,67: 4 // cobblestone
|
||||||
|
,108: 45 // brick
|
||||||
|
,109: 98 // stone brick
|
||||||
|
,114: 112 // nether brick
|
||||||
|
,128: 24 // sandstone
|
||||||
|
,134: '5:1' // spruce wood
|
||||||
|
,135: '5:2' // birch wood
|
||||||
|
,136: '5:3' // jungle wood
|
||||||
|
,156: 155 // quartz
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// prism private implementation
|
||||||
|
//
|
||||||
|
function prism( block, w, d ) {
|
||||||
|
var stairEquiv = STAIRBLOCKS[block];
|
||||||
|
if ( stairEquiv ) {
|
||||||
|
this
|
||||||
|
.fwd()
|
||||||
|
.prism( stairEquiv,w,d-2 )
|
||||||
|
.back()
|
||||||
|
.stairs(block, w, d / 2)
|
||||||
|
.fwd(d - 1)
|
||||||
|
.right(w - 1)
|
||||||
|
.turn(2)
|
||||||
|
.stairs(block, w, d / 2)
|
||||||
|
.turn(2)
|
||||||
|
.left(w - 1)
|
||||||
|
.back(d - 1);
|
||||||
|
}else{
|
||||||
|
var c = 0;
|
||||||
|
var d2 = d;
|
||||||
|
while ( d2 >= 1 ) {
|
||||||
|
this.cuboid(block,w,1,d2 );
|
||||||
|
d2 -= 2;
|
||||||
|
this.fwd( ).up( );
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
this.down(c ).back(c );
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// prism0 private implementation
|
||||||
|
//
|
||||||
|
function prism0( block,w,d ) {
|
||||||
|
this
|
||||||
|
.stairs(block,w,d/2)
|
||||||
|
.fwd(d-1)
|
||||||
|
.right(w-1)
|
||||||
|
.turn(2)
|
||||||
|
.stairs(block,w,d/2)
|
||||||
|
.turn(2)
|
||||||
|
.left(w-1)
|
||||||
|
.back(d-1);
|
||||||
|
|
||||||
|
var se = STAIRBLOCKS[block];
|
||||||
|
if (se) {
|
||||||
|
this
|
||||||
|
.fwd()
|
||||||
|
.prism(se,1,d-2)
|
||||||
|
.right(w-1)
|
||||||
|
.prism(se,1,d-2)
|
||||||
|
.left(w-1)
|
||||||
|
.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Drone.extend(prism0);
|
||||||
|
Drone.extend(prism);
|
66
src/main/js/plugins/drone/rand.js
Normal file
66
src/main/js/plugins/drone/rand.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require*/
|
||||||
|
/************************************************************************
|
||||||
|
### Drone.rand() method
|
||||||
|
|
||||||
|
rand takes either an array (if each blockid has the same chance of occurring) or an object where each property is a blockid and the value is it's weight (an integer)
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
place random blocks stone, mossy stone and cracked stone (each block has the same chance of being picked)
|
||||||
|
|
||||||
|
rand( [blocks.brick.stone, blocks.brick.mossy, blocks.brick.cracked ],w,d,h)
|
||||||
|
|
||||||
|
to place random blocks stone has a 50% chance of being picked,
|
||||||
|
|
||||||
|
var distribution = {};
|
||||||
|
distribution[ blocks.brick.stone ] = 5;
|
||||||
|
distribution[ blocks.brick.mossy ] = 3;
|
||||||
|
distribution[ blocks.brick.cracked ] = 2;
|
||||||
|
|
||||||
|
rand( distribution, width, height, depth)
|
||||||
|
|
||||||
|
regular stone has a 50% chance, mossy stone has a 30% chance and cracked stone has just a 20% chance of being picked.
|
||||||
|
|
||||||
|
***/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
//
|
||||||
|
// standard fisher-yates shuffle algorithm
|
||||||
|
//
|
||||||
|
function fisherYates( myArray ) {
|
||||||
|
var i = myArray.length;
|
||||||
|
if ( i == 0 ) return false;
|
||||||
|
while ( --i ) {
|
||||||
|
var j = Math.floor( Math.random( ) * ( i + 1 ) );
|
||||||
|
var tempi = myArray[i];
|
||||||
|
var tempj = myArray[j];
|
||||||
|
myArray[i] = tempj;
|
||||||
|
myArray[j] = tempi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _rand( blockDistribution ) {
|
||||||
|
if ( !(blockDistribution.constructor == Array ) ) {
|
||||||
|
var a = [];
|
||||||
|
for ( var p in blockDistribution ) {
|
||||||
|
var n = blockDistribution[p];
|
||||||
|
for ( var i = 0;i < n;i++ ) {
|
||||||
|
a.push(p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blockDistribution = a;
|
||||||
|
}
|
||||||
|
while ( blockDistribution.length < 1000 ) {
|
||||||
|
// make array bigger so that it's more random
|
||||||
|
blockDistribution = blockDistribution.concat(blockDistribution );
|
||||||
|
}
|
||||||
|
fisherYates(blockDistribution );
|
||||||
|
return blockDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
Drone.extend( function rand( dist, width, height, depth, overwrite ) {
|
||||||
|
if ( typeof overwrite == 'undefined' ) {
|
||||||
|
overwrite = true;
|
||||||
|
}
|
||||||
|
var randomized = _rand( dist );
|
||||||
|
this.boxa( randomized, width, height, depth, overwrite);
|
||||||
|
} );
|
102
src/main/js/plugins/drone/sign.js
Normal file
102
src/main/js/plugins/drone/sign.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require, echo,__plugin*/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/************************************************************************
|
||||||
|
### Drone.sign() method
|
||||||
|
|
||||||
|
Signs must use block 63 (stand-alone signs) or 68 (signs on walls)
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* message - can be a string or an array of strings.
|
||||||
|
* block - can be 63 or 68
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create a free-standing sign...
|
||||||
|
|
||||||
|
drone.sign(["Hello","World"],63);
|
||||||
|
|
||||||
|
![ground sign](img/signex1.png)
|
||||||
|
|
||||||
|
... to create a wall mounted sign...
|
||||||
|
|
||||||
|
drone.sign(["Welcome","to","Scriptopia"], 68 );
|
||||||
|
|
||||||
|
![wall sign](img/signex2.png)
|
||||||
|
|
||||||
|
***/
|
||||||
|
function putSign( drone, texts, blockId, meta ) {
|
||||||
|
var i,
|
||||||
|
block,
|
||||||
|
state,
|
||||||
|
getState,
|
||||||
|
isSign,
|
||||||
|
setLine;
|
||||||
|
|
||||||
|
if ( blockId != 63 && blockId != 68 ) {
|
||||||
|
throw new Error( 'Invalid Parameter: blockId must be 63 or 68' );
|
||||||
|
}
|
||||||
|
drone.setBlock( blockId, meta);
|
||||||
|
block = drone.getBlock();
|
||||||
|
if (__plugin.canary){
|
||||||
|
isSign = function(block){
|
||||||
|
var sign = block.getTileEntity();
|
||||||
|
return sign.setTextOnLine;
|
||||||
|
};
|
||||||
|
setLine = function( block, i, text) {
|
||||||
|
var sign = block.getTileEntity();
|
||||||
|
sign.setTextOnLine( text, i );
|
||||||
|
sign.update();
|
||||||
|
};
|
||||||
|
if ( drone.bountiful ) {
|
||||||
|
// 1.8
|
||||||
|
var prop = require('blockhelper').property;
|
||||||
|
prop(block).set('facing',(drone.dir+2)%4);
|
||||||
|
block.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (__plugin.bukkit){
|
||||||
|
isSign = function(block){ return block.state && block.state.setLine; };
|
||||||
|
setLine = function( block, i, text) {
|
||||||
|
var sign = block.state;
|
||||||
|
sign.setLine( i, text );
|
||||||
|
sign.update(true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if ( isSign(block) ) {
|
||||||
|
for ( i = 0; i < texts.length; i++ ) {
|
||||||
|
setLine(block, i % 4, texts[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function sign( message, block ) {
|
||||||
|
if ( message.constructor != Array ) {
|
||||||
|
message = [message];
|
||||||
|
}
|
||||||
|
var bm = this._getBlockIdAndMeta( block );
|
||||||
|
block = bm[0];
|
||||||
|
var meta = bm[1];
|
||||||
|
if ( block != 63 && block != 68 ) {
|
||||||
|
var usage = 'Usage: sign("message", "63:1") or sign("message","68:1")';
|
||||||
|
if ( this.player ) {
|
||||||
|
echo( this.player, usage);
|
||||||
|
}
|
||||||
|
console.error(usage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( block == 68 ) {
|
||||||
|
meta = Drone.PLAYER_SIGN_FACING[ this.dir % 4 ];
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
if ( block == 63 ) {
|
||||||
|
meta = ( 12 + ( ( this.dir + 2 ) * 4 ) ) % 16;
|
||||||
|
}
|
||||||
|
this.then(function(){
|
||||||
|
putSign( this, message, block, meta);
|
||||||
|
if ( block == 68 ) {
|
||||||
|
this.fwd();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Drone.extend(sign);
|
58
src/main/js/plugins/drone/stairs.js
Normal file
58
src/main/js/plugins/drone/stairs.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**************************************************************************
|
||||||
|
### Drone.stairs() function
|
||||||
|
|
||||||
|
The stairs() function will build a flight of stairs
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
* blockType - should be one of the following:
|
||||||
|
|
||||||
|
* blocks.stairs.oak
|
||||||
|
* blocks.stairs.cobblestone
|
||||||
|
* blocks.stairs.brick
|
||||||
|
* blocks.stairs.stone
|
||||||
|
* blocks.stairs.nether
|
||||||
|
* blocks.stairs.sandstone
|
||||||
|
* blocks.stairs.spruce
|
||||||
|
* blocks.stairs.birch
|
||||||
|
* blocks.stairs.jungle
|
||||||
|
* blocks.stairs.quartz
|
||||||
|
|
||||||
|
* width - The width of the staircase - default is 1
|
||||||
|
* height - The height of the staircase - default is 1
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To build an oak staircase 3 blocks wide and 5 blocks tall:
|
||||||
|
|
||||||
|
/js stairs(blocks.stairs.oak, 3, 5)
|
||||||
|
|
||||||
|
Staircases do not have any blocks beneath them.
|
||||||
|
|
||||||
|
***/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
/*global require*/
|
||||||
|
function stairs(blockType, width, height){
|
||||||
|
if (typeof width === 'undefined')
|
||||||
|
width = 1;
|
||||||
|
if (typeof height === 'undefined')
|
||||||
|
height = 1;
|
||||||
|
this.chkpt('_stairs');
|
||||||
|
while (height > 0) {
|
||||||
|
this.traverseWidth(width, function(){
|
||||||
|
this.setBlock(blockType, Drone.PLAYER_STAIRS_FACING[this.dir]);
|
||||||
|
if ( this.bountiful ){
|
||||||
|
// 1.8
|
||||||
|
var prop = require('blockhelper').property;
|
||||||
|
var block = this.getBlock();
|
||||||
|
prop(block).set('facing',that.dir);
|
||||||
|
block.update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.fwd().up();
|
||||||
|
height -= 1;
|
||||||
|
}
|
||||||
|
this.move('_stairs');
|
||||||
|
}
|
||||||
|
Drone.extend(stairs);
|
58
src/main/js/plugins/drone/trees.js
Normal file
58
src/main/js/plugins/drone/trees.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
'use strict';
|
||||||
|
/*global require,__plugin*/
|
||||||
|
/************************************************************************
|
||||||
|
### Drone Trees methods
|
||||||
|
|
||||||
|
* oak()
|
||||||
|
* spruce()
|
||||||
|
* birch()
|
||||||
|
* jungle()
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
To create 4 trees in a row, point the cross-hairs at the ground then type `/js ` and ...
|
||||||
|
|
||||||
|
up( ).oak( ).right(8 ).spruce( ).right(8 ).birch( ).right(8 ).jungle( );
|
||||||
|
|
||||||
|
Trees won't always generate unless the conditions are right. You
|
||||||
|
should use the tree methods when the drone is directly above the
|
||||||
|
ground. Trees will usually grow if the drone's current location is
|
||||||
|
occupied by Air and is directly above an area of grass (That is why
|
||||||
|
the `up()` method is called first).
|
||||||
|
|
||||||
|
![tree example](img/treeex1.png)
|
||||||
|
|
||||||
|
None of the tree methods require parameters. Tree methods will only be
|
||||||
|
successful if the tree is placed on grass in a setting where trees can
|
||||||
|
grow.
|
||||||
|
|
||||||
|
***/
|
||||||
|
var Drone = require('./drone').Drone;
|
||||||
|
var bkTreeType = org.bukkit.TreeType;
|
||||||
|
var _trees = {
|
||||||
|
oak: bkTreeType.BIG_TREE ,
|
||||||
|
birch: bkTreeType.BIRCH ,
|
||||||
|
jungle: bkTreeType.JUNGLE,
|
||||||
|
spruce: bkTreeType.REDWOOD
|
||||||
|
};
|
||||||
|
function bukkitTreeFactory( k, v ) {
|
||||||
|
return function( ) {
|
||||||
|
var block = this.getBlock();
|
||||||
|
if ( block.typeId == 2 ) {
|
||||||
|
this.up( );
|
||||||
|
}
|
||||||
|
var treeLoc = this.getLocation();
|
||||||
|
var successful = treeLoc.world.generateTree(treeLoc,v );
|
||||||
|
if ( block.typeId == 2 ) {
|
||||||
|
this.down( );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function canaryTreeFactory( k, v ){
|
||||||
|
return function(){
|
||||||
|
console.log(k + ' not yet implemented.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for ( var p in _trees ) {
|
||||||
|
Drone.extend(p, (__plugin.canary? canaryTreeFactory : bukkitTreeFactory) ( p, _trees[p] ) );
|
||||||
|
}
|
Reference in a new issue