From 8d8ea69dda8bc875f78d82117cfe48fc5c28d8f9 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Sat, 3 Jan 2015 20:57:30 +0000 Subject: [PATCH] moving core drone and extensions into modules folder so 3rd-party extensions/contributions can use require('drone') instead of the existing unwieldy require('../drone').Drone --- docs/API-Reference.md | 3551 +++++++++-------- src/docs/js/generateApiDocs.js | 7 +- src/main/js/{plugins => modules}/drone/arc.js | 13 +- src/main/js/modules/drone/bed.js | 55 + .../{plugins => modules}/drone/blocktype.js | 9 +- .../{plugins => modules}/drone/copypaste.js | 27 +- .../{plugins => modules}/drone/cylinders.js | 13 +- .../js/{plugins => modules}/drone/doors.js | 41 +- src/main/js/modules/drone/firework.js | 21 + .../js/{plugins => modules}/drone/garden.js | 7 +- src/main/js/modules/drone/index.js | 909 +++++ .../js/{plugins => modules}/drone/ladder.js | 7 +- .../js/{plugins => modules}/drone/movement.js | 78 +- .../js/{plugins => modules}/drone/prism.js | 9 +- .../js/{plugins => modules}/drone/rand.js | 11 +- .../js/{plugins => modules}/drone/sign.js | 15 +- .../js/{plugins => modules}/drone/sphere.js | 40 +- .../js/{plugins => modules}/drone/stairs.js | 11 +- .../js/{plugins => modules}/drone/test.js | 15 +- .../js/{plugins => modules}/drone/trees.js | 9 +- src/main/js/plugins/drone/bed.js | 55 - src/main/js/plugins/drone/contrib/castle.js | 2 +- .../js/plugins/drone/contrib/chessboard.js | 2 +- src/main/js/plugins/drone/contrib/cottage.js | 2 +- .../js/plugins/drone/contrib/dancefloor.js | 2 +- src/main/js/plugins/drone/contrib/fort.js | 2 +- .../js/plugins/drone/contrib/hangtorch.js | 4 +- .../js/plugins/drone/contrib/lcd-clock.js | 5 +- src/main/js/plugins/drone/contrib/logo.js | 121 +- src/main/js/plugins/drone/contrib/mazegen.js | 2 +- src/main/js/plugins/drone/contrib/rainbow.js | 8 +- .../js/plugins/drone/contrib/redstonewire.js | 6 +- .../js/plugins/drone/contrib/spiral_stairs.js | 6 +- src/main/js/plugins/drone/contrib/temple.js | 4 +- src/main/js/plugins/drone/drone-firework.js | 6 - src/main/js/plugins/drone/drone.js | 882 +--- 36 files changed, 3050 insertions(+), 2907 deletions(-) rename src/main/js/{plugins => modules}/drone/arc.js (98%) create mode 100644 src/main/js/modules/drone/bed.js rename src/main/js/{plugins => modules}/drone/blocktype.js (98%) rename src/main/js/{plugins => modules}/drone/copypaste.js (90%) rename src/main/js/{plugins => modules}/drone/cylinders.js (89%) rename src/main/js/{plugins => modules}/drone/doors.js (76%) create mode 100644 src/main/js/modules/drone/firework.js rename src/main/js/{plugins => modules}/drone/garden.js (90%) create mode 100644 src/main/js/modules/drone/index.js rename src/main/js/{plugins => modules}/drone/ladder.js (90%) rename src/main/js/{plugins => modules}/drone/movement.js (86%) rename src/main/js/{plugins => modules}/drone/prism.js (94%) rename src/main/js/{plugins => modules}/drone/rand.js (92%) rename src/main/js/{plugins => modules}/drone/sign.js (92%) rename src/main/js/{plugins => modules}/drone/sphere.js (92%) rename src/main/js/{plugins => modules}/drone/stairs.js (87%) rename src/main/js/{plugins => modules}/drone/test.js (60%) rename src/main/js/{plugins => modules}/drone/trees.js (95%) delete mode 100644 src/main/js/plugins/drone/bed.js delete mode 100644 src/main/js/plugins/drone/drone-firework.js diff --git a/docs/API-Reference.md b/docs/API-Reference.md index be631fe..8eb7d2b 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -44,21 +44,135 @@ Walter Higgins * [module name resolution](#module-name-resolution) * [events Module](#events-module) * [events.on() static method](#eventson-static-method) - * [console global variable](#console-global-variable) - * [Example](#example) - * [Using string substitutions](#using-string-substitutions) - * [Events Helper Module (bukkit version)](#events-helper-module-bukkit-version) + * [Events Helper Module (canary version)](#events-helper-module-canary-version) * [Usage](#usage) - * [events.weatherChange()](#eventsweatherchange) - * [events.lightningStrike()](#eventslightningstrike) - * [events.thunderChange()](#eventsthunderchange) - * [events.vehicleMove()](#eventsvehiclemove) + * [events.minecartActivate()](#eventsminecartactivate) + * [events.villagerTradeUnlock()](#eventsvillagertradeunlock) + * [events.mobTarget()](#eventsmobtarget) + * [events.chickenLayEgg()](#eventschickenlayegg) + * [events.potionEffectFinish()](#eventspotioneffectfinish) + * [events.entityMove()](#eventsentitymove) + * [events.hangingEntityDestroy()](#eventshangingentitydestroy) + * [events.vehicleCollision()](#eventsvehiclecollision) + * [events.potionEffectApplied()](#eventspotioneffectapplied) * [events.vehicleDestroy()](#eventsvehicledestroy) + * [events.vehicleEnter()](#eventsvehicleenter) + * [events.damage()](#eventsdamage) + * [events.entityMount()](#eventsentitymount) + * [events.slimeSplit()](#eventsslimesplit) + * [events.endermanDropBlock()](#eventsendermandropblock) + * [events.itemTouchGround()](#eventsitemtouchground) + * [events.entitySpawn()](#eventsentityspawn) + * [events.endermanPickupBlock()](#eventsendermanpickupblock) + * [events.vehicleDamage()](#eventsvehicledamage) + * [events.entityLightningStruck()](#eventsentitylightningstruck) + * [events.entityDespawn()](#eventsentitydespawn) + * [events.vehicleMove()](#eventsvehiclemove) + * [events.projectileHit()](#eventsprojectilehit) + * [events.entityDeath()](#eventsentitydeath) + * [events.entityTame()](#eventsentitytame) * [events.vehicleExit()](#eventsvehicleexit) + * [events.dimensionSwitch()](#eventsdimensionswitch) + * [events.foodLevel()](#eventsfoodlevel) + * [events.bookEdit()](#eventsbookedit) + * [events.playerListEntry()](#eventsplayerlistentry) + * [events.eat()](#eventseat) + * [events.playerIdle()](#eventsplayeridle) + * [events.enchant()](#eventsenchant) + * [events.playerArmSwing()](#eventsplayerarmswing) + * [events.teleport()](#eventsteleport) + * [events.anvilUse()](#eventsanviluse) + * [events.portalUse()](#eventsportaluse) + * [events.foodSaturation()](#eventsfoodsaturation) + * [events.connection()](#eventsconnection) + * [events.playerRespawned()](#eventsplayerrespawned) + * [events.armorBroken()](#eventsarmorbroken) + * [events.levelUp()](#eventslevelup) + * [events.blockRightClick()](#eventsblockrightclick) + * [events.itemDrop()](#eventsitemdrop) + * [events.playerRespawning()](#eventsplayerrespawning) + * [events.craft()](#eventscraft) + * [events.experience()](#eventsexperience) + * [events.signChange()](#eventssignchange) + * [events.healthChange()](#eventshealthchange) + * [events.disconnection()](#eventsdisconnection) + * [events.gameModeChange()](#eventsgamemodechange) + * [events.preConnection()](#eventspreconnection) + * [events.villagerTrade()](#eventsvillagertrade) + * [events.returnFromIdle()](#eventsreturnfromidle) + * [events.slotClick()](#eventsslotclick) + * [events.entityRightClick()](#eventsentityrightclick) + * [events.foodExhaustion()](#eventsfoodexhaustion) + * [events.chat()](#eventschat) + * [events.itemPickup()](#eventsitempickup) + * [events.bedExit()](#eventsbedexit) + * [events.blockPlace()](#eventsblockplace) + * [events.toolBroken()](#eventstoolbroken) + * [events.kick()](#eventskick) + * [events.playerDeath()](#eventsplayerdeath) + * [events.blockLeftClick()](#eventsblockleftclick) + * [events.blockDestroy()](#eventsblockdestroy) + * [events.bedEnter()](#eventsbedenter) + * [events.signShow()](#eventssignshow) + * [events.inventory()](#eventsinventory) + * [events.playerMove()](#eventsplayermove) + * [events.itemUse()](#eventsitemuse) + * [events.ban()](#eventsban) + * [events.statGained()](#eventsstatgained) + * [events.smeltBegin()](#eventssmeltbegin) + * [events.treeGrow()](#eventstreegrow) + * [events.chunkCreated()](#eventschunkcreated) + * [events.liquidDestroy()](#eventsliquiddestroy) + * [events.chunkLoaded()](#eventschunkloaded) + * [events.pistonRetract()](#eventspistonretract) + * [events.smelt()](#eventssmelt) + * [events.blockUpdate()](#eventsblockupdate) + * [events.portalDestroy()](#eventsportaldestroy) + * [events.ignition()](#eventsignition) + * [events.redstoneChange()](#eventsredstonechange) + * [events.weatherChange()](#eventsweatherchange) + * [events.chunkCreation()](#eventschunkcreation) + * [events.hopperTransfer()](#eventshoppertransfer) + * [events.chunkUnload()](#eventschunkunload) + * [events.blockGrow()](#eventsblockgrow) + * [events.dispense()](#eventsdispense) + * [events.blockDropXp()](#eventsblockdropxp) + * [events.fireworkExplode()](#eventsfireworkexplode) + * [events.leafDecay()](#eventsleafdecay) + * [events.pistonExtend()](#eventspistonextend) + * [events.noteBlockPlay()](#eventsnoteblockplay) + * [events.lightningStrike()](#eventslightningstrike) + * [events.decorate()](#eventsdecorate) + * [events.explosion()](#eventsexplosion) + * [events.tNTActivate()](#eventstntactivate) + * [events.timeChange()](#eventstimechange) + * [events.flow()](#eventsflow) + * [events.portalCreate()](#eventsportalcreate) + * [events.blockPhysics()](#eventsblockphysics) + * [events.playerCommand()](#eventsplayercommand) + * [events.consoleCommand()](#eventsconsolecommand) + * [events.commandBlockCommand()](#eventscommandblockcommand) + * [events.loadWorld()](#eventsloadworld) + * [events.permissionCheck()](#eventspermissioncheck) + * [events.serverGuiStart()](#eventsserverguistart) + * [events.unloadWorld()](#eventsunloadworld) + * [events.pluginDisable()](#eventsplugindisable) + * [events.pluginEnable()](#eventspluginenable) + * [events.serverTick()](#eventsservertick) + * [events.serverListPing()](#eventsserverlistping) + * [events.serverShutdown()](#eventsservershutdown) + * [Events Helper Module (bukkit version)](#events-helper-module-bukkit-version) + * [Usage](#usage-1) + * [events.weatherChange()](#eventsweatherchange-1) + * [events.lightningStrike()](#eventslightningstrike-1) + * [events.thunderChange()](#eventsthunderchange) + * [events.vehicleMove()](#eventsvehiclemove-1) + * [events.vehicleDestroy()](#eventsvehicledestroy-1) + * [events.vehicleExit()](#eventsvehicleexit-1) * [events.vehicleEntityCollision()](#eventsvehicleentitycollision) * [events.vehicleBlockCollision()](#eventsvehicleblockcollision) - * [events.vehicleEnter()](#eventsvehicleenter) - * [events.vehicleDamage()](#eventsvehicledamage) + * [events.vehicleEnter()](#eventsvehicleenter-1) + * [events.vehicleDamage()](#eventsvehicledamage-1) * [events.vehicleUpdate()](#eventsvehicleupdate) * [events.vehicleCreate()](#eventsvehiclecreate) * [events.paintingBreak()](#eventspaintingbreak) @@ -81,7 +195,7 @@ Walter Higgins * [events.asyncPlayerChat()](#eventsasyncplayerchat) * [events.playerDropItem()](#eventsplayerdropitem) * [events.playerRegisterChannel()](#eventsplayerregisterchannel) - * [events.playerMove()](#eventsplayermove) + * [events.playerMove()](#eventsplayermove-1) * [events.playerItemBreak()](#eventsplayeritembreak) * [events.playerBucketEmpty()](#eventsplayerbucketempty) * [events.playerStatisticIncrement()](#eventsplayerstatisticincrement) @@ -120,34 +234,34 @@ Walter Higgins * [events.inventoryClick()](#eventsinventoryclick) * [events.inventoryClose()](#eventsinventoryclose) * [events.inventoryCreative()](#eventsinventorycreative) - * [events.inventory()](#eventsinventory) + * [events.inventory()](#eventsinventory-1) * [events.prepareItemCraft()](#eventsprepareitemcraft) * [events.furnaceExtract()](#eventsfurnaceextract) * [events.brew()](#eventsbrew) * [events.serverCommand()](#eventsservercommand) - * [events.serverListPing()](#eventsserverlistping) + * [events.serverListPing()](#eventsserverlistping-1) * [events.serviceRegister()](#eventsserviceregister) - * [events.pluginDisable()](#eventsplugindisable) + * [events.pluginDisable()](#eventsplugindisable-1) * [events.remoteServerCommand()](#eventsremoteservercommand) * [events.mapInitialize()](#eventsmapinitialize) * [events.serviceUnregister()](#eventsserviceunregister) - * [events.pluginEnable()](#eventspluginenable) - * [events.playerDeath()](#eventsplayerdeath) + * [events.pluginEnable()](#eventspluginenable-1) + * [events.playerDeath()](#eventsplayerdeath-1) * [events.entityCreatePortal()](#eventsentitycreateportal) * [events.entityCombust()](#eventsentitycombust) * [events.sheepDyeWool()](#eventssheepdyewool) * [events.expBottle()](#eventsexpbottle) - * [events.entityTame()](#eventsentitytame) + * [events.entityTame()](#eventsentitytame-1) * [events.projectileLaunch()](#eventsprojectilelaunch) * [events.entityDamage()](#eventsentitydamage) * [events.itemSpawn()](#eventsitemspawn) - * [events.projectileHit()](#eventsprojectilehit) + * [events.projectileHit()](#eventsprojectilehit-1) * [events.foodLevelChange()](#eventsfoodlevelchange) * [events.itemDespawn()](#eventsitemdespawn) * [events.entityPortalEnter()](#eventsentityportalenter) * [events.entityPortal()](#eventsentityportal) * [events.entityTarget()](#eventsentitytarget) - * [events.entityDeath()](#eventsentitydeath) + * [events.entityDeath()](#eventsentitydeath-1) * [events.sheepRegrowWool()](#eventssheepregrowwool) * [events.entityShootBow()](#eventsentityshootbow) * [events.creeperPower()](#eventscreeperpower) @@ -165,7 +279,7 @@ Walter Higgins * [events.entityTargetLivingEntity()](#eventsentitytargetlivingentity) * [events.entityTeleport()](#eventsentityteleport) * [events.playerLeashEntity()](#eventsplayerleashentity) - * [events.slimeSplit()](#eventsslimesplit) + * [events.slimeSplit()](#eventsslimesplit-1) * [events.pigZap()](#eventspigzap) * [events.potionSplash()](#eventspotionsplash) * [events.entityChangeBlock()](#eventsentitychangeblock) @@ -176,8 +290,8 @@ Walter Higgins * [events.blockMultiPlace()](#eventsblockmultiplace) * [events.notePlay()](#eventsnoteplay) * [events.blockFade()](#eventsblockfade) - * [events.blockPlace()](#eventsblockplace) - * [events.blockPhysics()](#eventsblockphysics) + * [events.blockPlace()](#eventsblockplace-1) + * [events.blockPhysics()](#eventsblockphysics-1) * [events.blockIgnite()](#eventsblockignite) * [events.blockBreak()](#eventsblockbreak) * [events.blockBurn()](#eventsblockburn) @@ -185,10 +299,10 @@ Walter Higgins * [events.blockRedstone()](#eventsblockredstone) * [events.blockPistonRetract()](#eventsblockpistonretract) * [events.blockDispense()](#eventsblockdispense) - * [events.signChange()](#eventssignchange) + * [events.signChange()](#eventssignchange-1) * [events.blockPistonExtend()](#eventsblockpistonextend) * [events.blockCanBuild()](#eventsblockcanbuild) - * [events.blockGrow()](#eventsblockgrow) + * [events.blockGrow()](#eventsblockgrow-1) * [events.leavesDecay()](#eventsleavesdecay) * [events.blockExp()](#eventsblockexp) * [events.blockForm()](#eventsblockform) @@ -202,127 +316,57 @@ Walter Higgins * [events.worldInit()](#eventsworldinit) * [events.worldUnload()](#eventsworldunload) * [events.worldSave()](#eventsworldsave) - * [events.chunkUnload()](#eventschunkunload) - * [events.chunkPopulate()](#eventschunkpopulate) - * [events.portalCreate()](#eventsportalcreate) - * [events.chunkLoad()](#eventschunkload) - * [Events Helper Module (canary version)](#events-helper-module-canary-version) - * [Usage](#usage-1) - * [events.minecartActivate()](#eventsminecartactivate) - * [events.villagerTradeUnlock()](#eventsvillagertradeunlock) - * [events.mobTarget()](#eventsmobtarget) - * [events.chickenLayEgg()](#eventschickenlayegg) - * [events.potionEffectFinish()](#eventspotioneffectfinish) - * [events.entityMove()](#eventsentitymove) - * [events.hangingEntityDestroy()](#eventshangingentitydestroy) - * [events.vehicleCollision()](#eventsvehiclecollision) - * [events.potionEffectApplied()](#eventspotioneffectapplied) - * [events.vehicleDestroy()](#eventsvehicledestroy-1) - * [events.vehicleEnter()](#eventsvehicleenter-1) - * [events.damage()](#eventsdamage) - * [events.entityMount()](#eventsentitymount) - * [events.slimeSplit()](#eventsslimesplit-1) - * [events.endermanDropBlock()](#eventsendermandropblock) - * [events.itemTouchGround()](#eventsitemtouchground) - * [events.entitySpawn()](#eventsentityspawn) - * [events.endermanPickupBlock()](#eventsendermanpickupblock) - * [events.vehicleDamage()](#eventsvehicledamage-1) - * [events.entityLightningStruck()](#eventsentitylightningstruck) - * [events.entityDespawn()](#eventsentitydespawn) - * [events.vehicleMove()](#eventsvehiclemove-1) - * [events.projectileHit()](#eventsprojectilehit-1) - * [events.entityDeath()](#eventsentitydeath-1) - * [events.entityTame()](#eventsentitytame-1) - * [events.vehicleExit()](#eventsvehicleexit-1) - * [events.dimensionSwitch()](#eventsdimensionswitch) - * [events.foodLevel()](#eventsfoodlevel) - * [events.bookEdit()](#eventsbookedit) - * [events.playerListEntry()](#eventsplayerlistentry) - * [events.eat()](#eventseat) - * [events.playerIdle()](#eventsplayeridle) - * [events.enchant()](#eventsenchant) - * [events.playerArmSwing()](#eventsplayerarmswing) - * [events.teleport()](#eventsteleport) - * [events.anvilUse()](#eventsanviluse) - * [events.portalUse()](#eventsportaluse) - * [events.foodSaturation()](#eventsfoodsaturation) - * [events.connection()](#eventsconnection) - * [events.playerRespawned()](#eventsplayerrespawned) - * [events.armorBroken()](#eventsarmorbroken) - * [events.levelUp()](#eventslevelup) - * [events.blockRightClick()](#eventsblockrightclick) - * [events.itemDrop()](#eventsitemdrop) - * [events.playerRespawning()](#eventsplayerrespawning) - * [events.craft()](#eventscraft) - * [events.experience()](#eventsexperience) - * [events.signChange()](#eventssignchange-1) - * [events.healthChange()](#eventshealthchange) - * [events.disconnection()](#eventsdisconnection) - * [events.gameModeChange()](#eventsgamemodechange) - * [events.preConnection()](#eventspreconnection) - * [events.villagerTrade()](#eventsvillagertrade) - * [events.returnFromIdle()](#eventsreturnfromidle) - * [events.slotClick()](#eventsslotclick) - * [events.entityRightClick()](#eventsentityrightclick) - * [events.foodExhaustion()](#eventsfoodexhaustion) - * [events.chat()](#eventschat) - * [events.itemPickup()](#eventsitempickup) - * [events.bedExit()](#eventsbedexit) - * [events.blockPlace()](#eventsblockplace-1) - * [events.toolBroken()](#eventstoolbroken) - * [events.kick()](#eventskick) - * [events.playerDeath()](#eventsplayerdeath-1) - * [events.blockLeftClick()](#eventsblockleftclick) - * [events.blockDestroy()](#eventsblockdestroy) - * [events.bedEnter()](#eventsbedenter) - * [events.signShow()](#eventssignshow) - * [events.inventory()](#eventsinventory-1) - * [events.playerMove()](#eventsplayermove-1) - * [events.itemUse()](#eventsitemuse) - * [events.ban()](#eventsban) - * [events.statGained()](#eventsstatgained) - * [events.smeltBegin()](#eventssmeltbegin) - * [events.treeGrow()](#eventstreegrow) - * [events.chunkCreated()](#eventschunkcreated) - * [events.liquidDestroy()](#eventsliquiddestroy) - * [events.chunkLoaded()](#eventschunkloaded) - * [events.pistonRetract()](#eventspistonretract) - * [events.smelt()](#eventssmelt) - * [events.blockUpdate()](#eventsblockupdate) - * [events.portalDestroy()](#eventsportaldestroy) - * [events.ignition()](#eventsignition) - * [events.redstoneChange()](#eventsredstonechange) - * [events.weatherChange()](#eventsweatherchange-1) - * [events.chunkCreation()](#eventschunkcreation) - * [events.hopperTransfer()](#eventshoppertransfer) * [events.chunkUnload()](#eventschunkunload-1) - * [events.blockGrow()](#eventsblockgrow-1) - * [events.dispense()](#eventsdispense) - * [events.blockDropXp()](#eventsblockdropxp) - * [events.fireworkExplode()](#eventsfireworkexplode) - * [events.leafDecay()](#eventsleafdecay) - * [events.pistonExtend()](#eventspistonextend) - * [events.noteBlockPlay()](#eventsnoteblockplay) - * [events.lightningStrike()](#eventslightningstrike-1) - * [events.decorate()](#eventsdecorate) - * [events.explosion()](#eventsexplosion) - * [events.tNTActivate()](#eventstntactivate) - * [events.timeChange()](#eventstimechange) - * [events.flow()](#eventsflow) + * [events.chunkPopulate()](#eventschunkpopulate) * [events.portalCreate()](#eventsportalcreate-1) - * [events.blockPhysics()](#eventsblockphysics-1) - * [events.playerCommand()](#eventsplayercommand) - * [events.consoleCommand()](#eventsconsolecommand) - * [events.commandBlockCommand()](#eventscommandblockcommand) - * [events.loadWorld()](#eventsloadworld) - * [events.permissionCheck()](#eventspermissioncheck) - * [events.serverGuiStart()](#eventsserverguistart) - * [events.unloadWorld()](#eventsunloadworld) - * [events.pluginDisable()](#eventsplugindisable-1) - * [events.pluginEnable()](#eventspluginenable-1) - * [events.serverTick()](#eventsservertick) - * [events.serverListPing()](#eventsserverlistping-1) - * [events.serverShutdown()](#eventsservershutdown) + * [events.chunkLoad()](#eventschunkload) + * [console global variable](#console-global-variable) + * [Example](#example) + * [Using string substitutions](#using-string-substitutions) + * [Drone Plugin](#drone-plugin) + * [Constructing a Drone Object](#constructing-a-drone-object) + * [Drone.box() method](#dronebox-method) + * [Drone.box0() method](#dronebox0-method) + * [Drone.boxa() method](#droneboxa-method) + * [Chaining](#chaining) + * [Drone Properties](#drone-properties) + * [Extending Drone](#extending-drone) + * [Drone.extend() static method](#droneextend-static-method) + * [Drone Constants](#drone-constants) + * [Drone.times() Method](#dronetimes-method) + * [Drone.arc() method](#dronearc-method) + * [Drone.bed() method](#dronebed-method) + * [Drone.blocktype() method](#droneblocktype-method) + * [Copy & Paste using Drone](#copy--paste-using-drone) + * [Drone.copy() method](#dronecopy-method) + * [Drone.paste() method](#dronepaste-method) + * [Drone.cylinder() method](#dronecylinder-method) + * [Drone.cylinder0() method](#dronecylinder0-method) + * [Drone.door() method](#dronedoor-method) + * [Drone.door_iron() method](#dronedoor_iron-method) + * [Drone.door2() method](#dronedoor2-method) + * [Drone.door2_iron() method](#dronedoor2_iron-method) + * [Drone.firework() method](#dronefirework-method) + * [Drone.garden() method](#dronegarden-method) + * [Drone.ladder() method](#droneladder-method) + * [Drone Movement](#drone-movement) + * [Drone Positional Info](#drone-positional-info) + * [Drone Markers](#drone-markers) + * [Drone.prism() method](#droneprism-method) + * [Drone.prism0() method](#droneprism0-method) + * [Drone.rand() method](#dronerand-method) + * [Drone.wallsign() method](#dronewallsign-method) + * [Drone.signpost() method](#dronesignpost-method) + * [Drone.sign() method](#dronesign-method) + * [Drone.sphere() method](#dronesphere-method) + * [Drone.sphere0() method](#dronesphere0-method) + * [Drone.hemisphere() method](#dronehemisphere-method) + * [Drone.hemisphere0() method](#dronehemisphere0-method) + * [Drone.stairs() function](#dronestairs-function) + * [Drone Trees methods](#drone-trees-methods) + * [Drone.rainbow() method](#dronerainbow-method) + * [Drone.spiral_stairs() method](#dronespiral_stairs-method) + * [Drone.stairs() function](#dronestairs-function-1) * [Blocks Module](#blocks-module) * [Examples](#examples) * [Fireworks Module](#fireworks-module) @@ -359,48 +403,6 @@ Walter Higgins * [utils.players() function](#utilsplayers-function) * [utils.playerNames() function](#utilsplayernames-function) * [utils.stat() function](#utilsstat-function) - * [Drone Plugin](#drone-plugin) - * [Constructing a Drone Object](#constructing-a-drone-object) - * [Drone.box() method](#dronebox-method) - * [Drone.box0() method](#dronebox0-method) - * [Drone.boxa() method](#droneboxa-method) - * [Chaining](#chaining) - * [Drone Properties](#drone-properties) - * [Extending Drone](#extending-drone) - * [Drone.extend() static method](#droneextend-static-method) - * [Drone Constants](#drone-constants) - * [Drone.times() Method](#dronetimes-method) - * [Drone.arc() method](#dronearc-method) - * [Drone.bed() method](#dronebed-method) - * [Drone.blocktype() method](#droneblocktype-method) - * [Copy & Paste using Drone](#copy--paste-using-drone) - * [Drone.copy() method](#dronecopy-method) - * [Drone.paste() method](#dronepaste-method) - * [Drone.cylinder() method](#dronecylinder-method) - * [Drone.cylinder0() method](#dronecylinder0-method) - * [Drone.door() method](#dronedoor-method) - * [Drone.door_iron() method](#dronedoor_iron-method) - * [Drone.door2() method](#dronedoor2-method) - * [Drone.door2_iron() method](#dronedoor2_iron-method) - * [Drone.garden() method](#dronegarden-method) - * [Drone.ladder() method](#droneladder-method) - * [Drone Movement](#drone-movement) - * [Drone Positional Info](#drone-positional-info) - * [Drone Markers](#drone-markers) - * [Drone.prism() method](#droneprism-method) - * [Drone.prism0() method](#droneprism0-method) - * [Drone.rainbow() method](#dronerainbow-method) - * [Drone.rand() method](#dronerand-method) - * [Drone.wallsign() method](#dronewallsign-method) - * [Drone.signpost() method](#dronesignpost-method) - * [Drone.sign() method](#dronesign-method) - * [Drone.sphere() method](#dronesphere-method) - * [Drone.sphere0() method](#dronesphere0-method) - * [Drone.hemisphere() method](#dronehemisphere-method) - * [Drone.hemisphere0() method](#dronehemisphere0-method) - * [Drone.spiral_stairs() method](#dronespiral_stairs-method) - * [Drone.stairs() function](#dronestairs-function) - * [Drone Trees methods](#drone-trees-methods) * [Example Plugin #1 - A simple extension to Minecraft.](#example-plugin-1---a-simple-extension-to-minecraft) * [Usage:](#usage-3) * [Example Plugin #2 - Making extensions available for all players.](#example-plugin-2---making-extensions-available-for-all-players) @@ -970,40 +972,940 @@ myBlockBreakListener.unregister(); [buk2]: http://wiki.bukkit.org/Event_API_Reference [buk]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/event/Event.html -## console global variable +## Events Helper Module (canary version) +The Events helper module provides a suite of functions - one for each possible event. +For example, the events.blockDestroy() function is just a wrapper function which calls events.on(net.canarymod.hook.player.BlockDestroyHook, callback, priority) +This module is a convenience wrapper for easily adding new event handling functions in Javascript. +At the in-game or server-console prompt, players/admins can type `events.` and use TAB completion +to choose from any of the approx. 160 different event types to listen to. -ScriptCraft provides a `console` global variable with the followng methods... +### Usage - * log() - * info() - * warn() - * error() + events.blockDestroy( function( event ) { + echo( event.player, 'You broke a block!'); + }); -The ScriptCraft console methods work like the [Web API implementation][webcons]. +The crucial difference is that the events module now has functions for each of the built-in events. The functions are accessible via TAB-completion so will help beginning programmers to explore the events at the server console window. -### Example +### events.minecartActivate() - console.log('Hello %s', 'world'); +#### Parameters -Basic variable substitution is supported (ScriptCraft's implementation -of console uses the Bukkit Plugin [Logger][lgr] or Canary Plugin [Logman][cmlgr] under the hood and -uses [java.lang.String.format()][strfmt] for variable -substitution. All output will be sent to the server console (not -in-game). + * callback - A function which is called whenever the [entity.MinecartActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MinecartActivateHook.html) is fired -### Using string substitutions + * priority - optional - see events.on() for more information. -ScriptCraft uses Java's [String.format()][strfmt] so any string substitution identifiers supported by -`java.lang.String.format()` are supported (e.g. %s , %d etc). +### events.villagerTradeUnlock() - for (var i=0; i<5; i++) { - console.log("Hello, %s. You've called me %d times.", "Bob", i+1); - } +#### Parameters -[lgr]: http://jd.bukkit.org/beta/apidocs/org/bukkit/plugin/PluginLogger.html -[cmlgr]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/logger/Logman.html -[strfmt]: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...) -[webcons]: https://developer.mozilla.org/en-US/docs/Web/API/console + * callback - A function which is called whenever the [entity.VillagerTradeUnlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VillagerTradeUnlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.mobTarget() + +#### Parameters + + * callback - A function which is called whenever the [entity.MobTargetHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MobTargetHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chickenLayEgg() + +#### Parameters + + * callback - A function which is called whenever the [entity.ChickenLayEggHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ChickenLayEggHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.potionEffectFinish() + +#### Parameters + + * callback - A function which is called whenever the [entity.PotionEffectFinishHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectFinishHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityMove() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.hangingEntityDestroy() + +#### Parameters + + * callback - A function which is called whenever the [entity.HangingEntityDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/HangingEntityDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleCollision() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleCollisionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleCollisionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.potionEffectApplied() + +#### Parameters + + * callback - A function which is called whenever the [entity.PotionEffectAppliedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectAppliedHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleDestroy() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleEnter() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleEnterHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.damage() + +#### Parameters + + * callback - A function which is called whenever the [entity.DamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DamageHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityMount() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityMountHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMountHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.slimeSplit() + +#### Parameters + + * callback - A function which is called whenever the [entity.SlimeSplitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/SlimeSplitHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.endermanDropBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EndermanDropBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanDropBlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.itemTouchGround() + +#### Parameters + + * callback - A function which is called whenever the [entity.ItemTouchGroundHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ItemTouchGroundHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entitySpawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntitySpawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntitySpawnHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.endermanPickupBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EndermanPickupBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanPickupBlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleDamage() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleDamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDamageHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityLightningStruck() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityLightningStruckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityLightningStruckHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityDespawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDespawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDespawnHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleMove() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.projectileHit() + +#### Parameters + + * callback - A function which is called whenever the [entity.ProjectileHitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ProjectileHitHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityDeath() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDeathHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityTame() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTameHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityTameHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.vehicleExit() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleExitHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.dimensionSwitch() + +#### Parameters + + * callback - A function which is called whenever the [entity.DimensionSwitchHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DimensionSwitchHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.foodLevel() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodLevelHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodLevelHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.bookEdit() + +#### Parameters + + * callback - A function which is called whenever the [player.BookEditHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BookEditHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerListEntry() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerListEntryHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerListEntryHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.eat() + +#### Parameters + + * callback - A function which is called whenever the [player.EatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EatHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerIdle() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerIdleHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.enchant() + +#### Parameters + + * callback - A function which is called whenever the [player.EnchantHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EnchantHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerArmSwing() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerArmSwingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerArmSwingHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.teleport() + +#### Parameters + + * callback - A function which is called whenever the [player.TeleportHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/TeleportHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.anvilUse() + +#### Parameters + + * callback - A function which is called whenever the [player.AnvilUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/AnvilUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.portalUse() + +#### Parameters + + * callback - A function which is called whenever the [player.PortalUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PortalUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.foodSaturation() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodSaturationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodSaturationHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.connection() + +#### Parameters + + * callback - A function which is called whenever the [player.ConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ConnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerRespawned() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRespawnedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawnedHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.armorBroken() + +#### Parameters + + * callback - A function which is called whenever the [player.ArmorBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ArmorBrokenHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.levelUp() + +#### Parameters + + * callback - A function which is called whenever the [player.LevelUpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/LevelUpHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockRightClick() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockRightClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.itemDrop() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemDropHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemDropHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerRespawning() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRespawningHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawningHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.craft() + +#### Parameters + + * callback - A function which is called whenever the [player.CraftHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/CraftHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.experience() + +#### Parameters + + * callback - A function which is called whenever the [player.ExperienceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ExperienceHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.signChange() + +#### Parameters + + * callback - A function which is called whenever the [player.SignChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.healthChange() + +#### Parameters + + * callback - A function which is called whenever the [player.HealthChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/HealthChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.disconnection() + +#### Parameters + + * callback - A function which is called whenever the [player.DisconnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/DisconnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.gameModeChange() + +#### Parameters + + * callback - A function which is called whenever the [player.GameModeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/GameModeChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.preConnection() + +#### Parameters + + * callback - A function which is called whenever the [player.PreConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PreConnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.villagerTrade() + +#### Parameters + + * callback - A function which is called whenever the [player.VillagerTradeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/VillagerTradeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.returnFromIdle() + +#### Parameters + + * callback - A function which is called whenever the [player.ReturnFromIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ReturnFromIdleHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.slotClick() + +#### Parameters + + * callback - A function which is called whenever the [player.SlotClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SlotClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.entityRightClick() + +#### Parameters + + * callback - A function which is called whenever the [player.EntityRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EntityRightClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.foodExhaustion() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodExhaustionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodExhaustionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chat() + +#### Parameters + + * callback - A function which is called whenever the [player.ChatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ChatHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.itemPickup() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemPickupHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemPickupHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.bedExit() + +#### Parameters + + * callback - A function which is called whenever the [player.BedExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedExitHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockPlace() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockPlaceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockPlaceHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.toolBroken() + +#### Parameters + + * callback - A function which is called whenever the [player.ToolBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ToolBrokenHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.kick() + +#### Parameters + + * callback - A function which is called whenever the [player.KickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/KickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerDeath() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerDeathHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockLeftClick() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockLeftClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockLeftClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockDestroy() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.bedEnter() + +#### Parameters + + * callback - A function which is called whenever the [player.BedEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedEnterHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.signShow() + +#### Parameters + + * callback - A function which is called whenever the [player.SignShowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignShowHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.inventory() + +#### Parameters + + * callback - A function which is called whenever the [player.InventoryHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/InventoryHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerMove() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.itemUse() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.ban() + +#### Parameters + + * callback - A function which is called whenever the [player.BanHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BanHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.statGained() + +#### Parameters + + * callback - A function which is called whenever the [player.StatGainedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/StatGainedHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.smeltBegin() + +#### Parameters + + * callback - A function which is called whenever the [world.SmeltBeginHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltBeginHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.treeGrow() + +#### Parameters + + * callback - A function which is called whenever the [world.TreeGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TreeGrowHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chunkCreated() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkCreatedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreatedHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.liquidDestroy() + +#### Parameters + + * callback - A function which is called whenever the [world.LiquidDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LiquidDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chunkLoaded() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkLoadedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkLoadedHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.pistonRetract() + +#### Parameters + + * callback - A function which is called whenever the [world.PistonRetractHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonRetractHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.smelt() + +#### Parameters + + * callback - A function which is called whenever the [world.SmeltHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockUpdate() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockUpdateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockUpdateHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.portalDestroy() + +#### Parameters + + * callback - A function which is called whenever the [world.PortalDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.ignition() + +#### Parameters + + * callback - A function which is called whenever the [world.IgnitionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/IgnitionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.redstoneChange() + +#### Parameters + + * callback - A function which is called whenever the [world.RedstoneChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/RedstoneChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.weatherChange() + +#### Parameters + + * callback - A function which is called whenever the [world.WeatherChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/WeatherChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chunkCreation() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkCreationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreationHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.hopperTransfer() + +#### Parameters + + * callback - A function which is called whenever the [world.HopperTransferHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/HopperTransferHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.chunkUnload() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkUnloadHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkUnloadHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockGrow() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockGrowHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.dispense() + +#### Parameters + + * callback - A function which is called whenever the [world.DispenseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DispenseHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockDropXp() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockDropXpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockDropXpHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.fireworkExplode() + +#### Parameters + + * callback - A function which is called whenever the [world.FireworkExplodeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FireworkExplodeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.leafDecay() + +#### Parameters + + * callback - A function which is called whenever the [world.LeafDecayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LeafDecayHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.pistonExtend() + +#### Parameters + + * callback - A function which is called whenever the [world.PistonExtendHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonExtendHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.noteBlockPlay() + +#### Parameters + + * callback - A function which is called whenever the [world.NoteBlockPlayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/NoteBlockPlayHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.lightningStrike() + +#### Parameters + + * callback - A function which is called whenever the [world.LightningStrikeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LightningStrikeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.decorate() + +#### Parameters + + * callback - A function which is called whenever the [world.DecorateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DecorateHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.explosion() + +#### Parameters + + * callback - A function which is called whenever the [world.ExplosionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ExplosionHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.tNTActivate() + +#### Parameters + + * callback - A function which is called whenever the [world.TNTActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TNTActivateHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.timeChange() + +#### Parameters + + * callback - A function which is called whenever the [world.TimeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TimeChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.flow() + +#### Parameters + + * callback - A function which is called whenever the [world.FlowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FlowHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.portalCreate() + +#### Parameters + + * callback - A function which is called whenever the [world.PortalCreateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalCreateHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.blockPhysics() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockPhysicsHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockPhysicsHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.playerCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.PlayerCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/PlayerCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.consoleCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.ConsoleCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/ConsoleCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.commandBlockCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.CommandBlockCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/CommandBlockCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.loadWorld() + +#### Parameters + + * callback - A function which is called whenever the [system.LoadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/LoadWorldHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.permissionCheck() + +#### Parameters + + * callback - A function which is called whenever the [system.PermissionCheckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PermissionCheckHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.serverGuiStart() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerGuiStartHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerGuiStartHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.unloadWorld() + +#### Parameters + + * callback - A function which is called whenever the [system.UnloadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/UnloadWorldHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.pluginDisable() + +#### Parameters + + * callback - A function which is called whenever the [system.PluginDisableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginDisableHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.pluginEnable() + +#### Parameters + + * callback - A function which is called whenever the [system.PluginEnableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginEnableHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.serverTick() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerTickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerTickHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.serverListPing() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerListPingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerListPingHook.html) is fired + + * priority - optional - see events.on() for more information. + +### events.serverShutdown() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerShutdownHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerShutdownHook.html) is fired + + * priority - optional - see events.on() for more information. ## Events Helper Module (bukkit version) The Events helper module provides a suite of functions - one for each possible event. @@ -2276,940 +3178,969 @@ The crucial difference is that the events module now has functions for each of t * priority - optional - see events.on() for more information. -## Events Helper Module (canary version) -The Events helper module provides a suite of functions - one for each possible event. -For example, the events.blockDestroy() function is just a wrapper function which calls events.on(net.canarymod.hook.player.BlockDestroyHook, callback, priority) -This module is a convenience wrapper for easily adding new event handling functions in Javascript. -At the in-game or server-console prompt, players/admins can type `events.` and use TAB completion -to choose from any of the approx. 160 different event types to listen to. +## console global variable -### Usage +ScriptCraft provides a `console` global variable with the followng methods... - events.blockDestroy( function( event ) { - echo( event.player, 'You broke a block!'); + * log() + * info() + * warn() + * error() + +The ScriptCraft console methods work like the [Web API implementation][webcons]. + +### Example + + console.log('Hello %s', 'world'); + +Basic variable substitution is supported (ScriptCraft's implementation +of console uses the Bukkit Plugin [Logger][lgr] or Canary Plugin [Logman][cmlgr] under the hood and +uses [java.lang.String.format()][strfmt] for variable +substitution. All output will be sent to the server console (not +in-game). + +### Using string substitutions + +ScriptCraft uses Java's [String.format()][strfmt] so any string substitution identifiers supported by +`java.lang.String.format()` are supported (e.g. %s , %d etc). + + for (var i=0; i<5; i++) { + console.log("Hello, %s. You've called me %d times.", "Bob", i+1); + } + +[lgr]: http://jd.bukkit.org/beta/apidocs/org/bukkit/plugin/PluginLogger.html +[cmlgr]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/logger/Logman.html +[strfmt]: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...) +[webcons]: https://developer.mozilla.org/en-US/docs/Web/API/console + +## Drone Plugin + +The Drone is a convenience class for building. It can be used for... + + 1. Building + 2. Copying and Pasting + +It uses a fluent interface which means all of the Drone's methods return `this` and can be chained together like so... + + var theDrone = new Drone(self); + theDrone.up().left().box(blocks.oak).down().fwd(3).cylinder0(blocks.lava,8); + +### Constructing a Drone Object + +Drones can be created in any of the following ways... + + 1. Calling any one of the methods listed below will return a Drone object. For example... + + var d = box( blocks.oak ) + + ... creates a 1x1x1 wooden block at the cross-hairs or player's location and returns a Drone object. This might look odd (if you're familiar with Java's Object-dot-method syntax) but all of the Drone class's methods are also global functions that return new Drone objects. This is short-hand for creating drones and is useful for playing around with Drones at the in-game command prompt. It's shorter than typing ... + + var d = new Drone(self).box( blocks.oak ) + + ... All of the Drone's methods return `this` so you can chain operations together like this... + + var d = box( blocks.oak ) + .up() + .box( blocks.oak ,3,1,3) + .down() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ); + + 2. Using the following form... + + d = new Drone(self) + + ...will create a new Drone taking the current player as the parameter. If the player's cross-hairs are pointing at a block at the time then, that block's location becomes the drone's 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() with either a player or location given as a parameter, then building begins at the location the player was looking at or at the location. You can get around this by pointing at a 'corner stone' just above ground level or alternatively use the following statement... + + d = new Drone(self).up(); + + ... which will move the drone up one block as soon as it's created. + + ![corner stone](img/cornerstone1.png) + + 3. Or by using the following form... + + d = new Drone(x,y,z,direction,world); + + This will create a new Drone at the location you specified using x, y, z In minecraft, the X axis runs west to east and the Z axis runs north to south. The direction parameter says what direction you want the drone to face: 0 = east, 1 = south, 2 = west, 3 = north. If the direction parameter is omitted, the player's direction is used instead. Both the `direction` and `world` parameters are optional. + + 4. Create a new Drone based on a Location object... + + d = new Drone(location); + + This is useful when you want to create a drone at a given `org.bukkit.Location` . The `Location` class is used throughout the bukkit API. For example, if you want to create a drone when a block is broken at the block's location you would do so like this... + + events.blockBreak( function( event ) { + var location = event.block.location; + var drone = new Drone(location); + // do more stuff with the drone here... + }); + +#### Parameters + + * Player : If a player reference is given as the sole parameter then the block the player was looking at will be used as the starting point for the drone. If the player was not looking at a block then the player's location will be used as the starting point. If a `Player` object is provided as a paramter then it should be the only parameter. + * location : *NB* If a `Location` object is provided as a parameter, then it should be the only parameter. + * x : The x coordinate of the Drone (x,y,z,direction and world are not needed if either a player or location parameter is provided) + * y : The y coordinate of the Drone + * z : The z coordinate of the Drone + * direction : The direction in which the Drone is facing. Possible values are 0 (east), 1 (south), 2 (west) or 3 (north) + * world : The world in which the drone is created. + +### Drone.box() method + +the box() method is a convenience method for building things. (For the more performance-oriented method - see cuboid) + +#### parameters + + * b - 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` + * w (optional - default 1) - the width of the structure + * h (optional - default 1) - the height of the structure + * d (optional - default 1) - the depth of the structure - NB this is not how deep underground the structure lies - this is how far away (depth of field) from the drone the structure will extend. + +#### Example + +To create a black structure 4 blocks wide, 9 blocks tall and 1 block long... + + box(blocks.wool.black, 4, 9, 1); + +... or the following code does the same but creates a variable that can be used for further methods... + + var drone = new Drone(self); + drone.box(blocks.wool.black, 4, 9, 1); + +![box example 1](img/boxex1.png) + +### Drone.box0() method + +Another convenience method - this one creates 4 walls with no floor or ceiling. + +#### 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 (optional - default 1) - the width of the structure + * height (optional - default 1) - the height of the structure + * length (optional - default 1) - the length of the structure - how far + away (depth of field) from the drone the structure will extend. + +#### Example + +To create a stone building with the insided hollowed out 7 wide by 3 tall by 6 long... + + box0( blocks.stone, 7, 3, 6); + +![example box0](img/box0ex1.png) + +### Drone.boxa() method + +Construct a cuboid using an array of blocks. As the drone moves first along the width axis, then the height (y axis) then the length, each block is picked from the array and placed. + +#### Parameters + + * blocks - An array of blocks - each block in the array will be placed in turn. + * width + * height + * length + +#### Example + +Construct a rainbow-colored road 100 blocks long... + + var rainbowColors = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, + blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple]; + + boxa(rainbowColors,7,1,30); + +![boxa example](img/boxaex1.png) + +### Chaining + +All of the Drone methods return a Drone object, which means methods can be 'chained' together so instead of writing this... + + drone = new Drone( self ); + drone.fwd( 3 ); + drone.left( 2 ); + drone.box( blocks.grass ); // create a grass block + drone.up(); + drone.box( blocks.grass ); // create another grass block + drone.down(); + +...you could simply write ... + + var drone = new Drone(self).fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down(); + +... since each Drone method is also a global function that constructs a drone if none is supplied, you can shorten even further to just... + + fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down() + +The Drone object uses a [Fluent Interface][fl] to make ScriptCraft scripts more concise and easier to write and read. Minecraft's in-game command prompt is limited to about 80 characters so chaining drone commands together means more can be done before hitting the command prompt limit. For complex building you should save your commands in a new script file and load it using /js load() + +[fl]: http://en.wikipedia.org/wiki/Fluent_interface + +### Drone Properties + + * x - The Drone's position along the west-east axis (x increases as you move east) + * y - The Drone's position along the vertical axis (y increses as you move up) + * z - The Drone's position along the north-south axis (z increases as you move south) + * dir - The Drone's direction 0 is east, 1 is south , 2 is west and 3 is north. + +### Extending Drone + +The Drone object can be easily extended - new buidling recipes/blueprints can be added and can become part of a Drone's chain using the *static* method `Drone.extend`. + +### Drone.extend() static method + +Use this method to add new methods (which also become chainable global functions) to the Drone object. + +#### Parameters + + * name - The name of the new method e.g. 'pyramid'. + * function - The method body. + +Alternatively if you provide just a function as a parameter, then the function name will be used as the new method name. For example the following two approaches are both valid. + +#### Example 1 Using name and function as parameters + + // submitted by [edonaldson][edonaldson] + Drone.extend('pyramid', function( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); }); -The crucial difference is that the events module now has functions for each of the built-in events. The functions are accessible via TAB-completion so will help beginning programmers to explore the events at the server console window. +#### Example 2 Using just a named function as a parameter -### events.minecartActivate() + function pyramid( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); + } + Drone.extend( pyramid ); -#### Parameters +Once the method is defined (it can be defined in a new pyramid.js file) it can be used like so... - * callback - A function which is called whenever the [entity.MinecartActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MinecartActivateHook.html) is fired + var d = new Drone(self); + d.pyramid(blocks.brick.stone, 12); - * priority - optional - see events.on() for more information. +... or simply ... -### events.villagerTradeUnlock() + pyramid(blocks.brick.stone, 12); -#### Parameters +[edonaldson]: https://github.com/edonaldson - * callback - A function which is called whenever the [entity.VillagerTradeUnlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VillagerTradeUnlockHook.html) is fired +### Drone Constants - * priority - optional - see events.on() for more information. +#### Drone.PLAYER_STAIRS_FACING -### events.mobTarget() +An array which can be used when constructing stairs facing in the Drone's direction... -#### Parameters + var d = new Drone(self); + d.box(blocks.stairs.oak + ':' + Drone.PLAYER_STAIRS_FACING[d.dir]); - * callback - A function which is called whenever the [entity.MobTargetHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MobTargetHook.html) is fired +... will construct a single oak stair block facing the drone. - * priority - optional - see events.on() for more information. +#### Drone.PLAYER_SIGN_FACING -### events.chickenLayEgg() +An array which can be used when placing signs so they face in a given direction. This is used internally by the Drone.sign() method. It should also be used for placing any of the following blocks... -#### Parameters + * chest + * ladder + * furnace + * dispenser - * callback - A function which is called whenever the [entity.ChickenLayEggHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ChickenLayEggHook.html) is fired +By default, chests, dispensers, signs, ladders and furnaces are placed facing towards the drone so to place a chest facing the Drone just use: - * priority - optional - see events.on() for more information. + drone.box( blocks.chest ); -### events.potionEffectFinish() +To place a chest facing _away_ from the Drone: -#### Parameters + drone.box( blocks.chest + ':' + Drone.PLAYER_SIGN_FACING[(drone.dir + 2) % 4]); - * callback - A function which is called whenever the [entity.PotionEffectFinishHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectFinishHook.html) is fired +#### Drone.PLAYER_TORCH_FACING - * priority - optional - see events.on() for more information. +Used when placing torches. By default torches will be placed facing up. If you want to place a torch so that it faces towards the drone: -### events.entityMove() + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[drone.dir]); -#### Parameters +If you want to place a torch so it faces _away_ from the drone: - * callback - A function which is called whenever the [entity.EntityMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMoveHook.html) is fired + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[(drone.dir + 2) % 4]); - * priority - optional - see events.on() for more information. +### Drone.times() Method -### events.hangingEntityDestroy() +The times() method makes building multiple copies of buildings +easy. It's possible to create rows or grids of buildings without +resorting to `for` or `while` loops. -#### Parameters +#### Parameters - * callback - A function which is called whenever the [entity.HangingEntityDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/HangingEntityDestroyHook.html) is fired + * numTimes (optional - default 2) : The number of times you want to repeat the preceding statements. - * priority - optional - see events.on() for more information. +#### Example -### events.vehicleCollision() +Say you want to do the same thing over and over. You have a couple of options... -#### Parameters + * You can use a for loop... - * callback - A function which is called whenever the [entity.VehicleCollisionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleCollisionHook.html) is fired + d = new Drone(); for ( var i =0;i < 4; i++) { d.cottage().right(8); } - * priority - optional - see events.on() for more information. +While this will fit on the in-game prompt, it's awkward. You need to +declare a new Drone object first, then write a for loop to create the +4 cottages. It's also error prone, even the `for` loop is too much +syntax for what should really be simple. -### events.potionEffectApplied() + * You can use a while loop... + + d = new Drone(); var i=4; while (i--) { d.cottage().right(8); } -#### Parameters +... which is slightly shorter but still too much syntax. Each of the +above statements is fine for creating a 1-dimensional array of +structures. But what if you want to create a 2-dimensional or +3-dimensional array of structures? Enter the `times()` method. - * callback - A function which is called whenever the [entity.PotionEffectAppliedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectAppliedHook.html) is fired +The `times()` method lets you repeat commands in a chain any number of +times. So to create 4 cottages in a row you would use the following +statement... - * priority - optional - see events.on() for more information. + cottage().right(8).times(4); -### events.vehicleDestroy() +...which will build a cottage, then move right 8 blocks, then do it +again 4 times over so that at the end you will have 4 cottages in a +row. What's more the `times()` method can be called more than once in +a chain. So if you wanted to create a *grid* of 20 houses ( 4 x 5 ), +you would do so using the following statement... -#### Parameters + cottage().right(8).times(4).fwd(8).left(32).times(5); - * callback - A function which is called whenever the [entity.VehicleDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDestroyHook.html) is fired +... breaking it down... - * priority - optional - see events.on() for more information. + 1. The first 3 calls in the chain ( `cottage()`, `right(8)`, `times(4)` ) build a single row of 4 cottages. -### events.vehicleEnter() + 2. The last 3 calls in the chain ( `fwd(8)`, `left(32)`, `times(5)` ) move the drone forward 8 then left 32 blocks (4 x 8) to return to the original x coordinate, then everything in the chain is repeated again 5 times so that in the end, we have a grid of 20 cottages, 4 x 5. Normally this would require a nested loop but the `times()` method does away with the need for loops when repeating builds. -#### Parameters +Another example: This statement creates a row of trees 2 by 3 ... - * callback - A function which is called whenever the [entity.VehicleEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleEnterHook.html) is fired + oak().right(10).times(2).left(20).fwd(10).times(3) - * priority - optional - see events.on() for more information. +... You can see the results below. -### events.damage() +![times example 1](img/times-trees.png) -#### Parameters +### Drone.arc() method - * callback - A function which is called whenever the [entity.DamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DamageHook.html) is fired +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. - * priority - optional - see events.on() for more information. +#### Parameters -### events.entityMount() +arc() takes a single parameter - an object with the following named properties... -#### Parameters + * 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. - * callback - A function which is called whenever the [entity.EntityMountHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMountHook.html) is fired +#### Examples - * priority - optional - see events.on() for more information. +To draw a 1/4 circle (top right quadrant only) with a radius of 10 and +stroke width of 2 blocks ... -### events.slimeSplit() + arc({blockType: blocks.iron, + meta: 0, + radius: 10, + strokeWidth: 2, + quadrants: { topright: true }, + orientation: 'vertical', + stack: 1, + fill: false + } ); -#### Parameters +![arc example 1](img/arcex1.png) - * callback - A function which is called whenever the [entity.SlimeSplitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/SlimeSplitHook.html) is fired +[bres]: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm +[dv]: http://www.minecraftwiki.net/wiki/Data_values - * priority - optional - see events.on() for more information. +### Drone.bed() method -### events.endermanDropBlock() +Creates a bed. The foot of the bed will be at the drone's location and +the head of the bed will extend away from the drone. -#### Parameters +#### Example +To create a bed at the in-game prompt, look at a block then type: - * callback - A function which is called whenever the [entity.EndermanDropBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanDropBlockHook.html) is fired +```javascript +/js bed() +``` - * priority - optional - see events.on() for more information. +Like most Drone methods, this returns the drone so it can be chained like so: -### events.itemTouchGround() +```javascript +this + .fwd(3) + .bed() + .back(3) +``` +### Drone.blocktype() method -#### Parameters +Creates the text out of blocks. Useful for large-scale in-game signs. - * callback - A function which is called whenever the [entity.ItemTouchGroundHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ItemTouchGroundHook.html) is fired +#### Parameters + + * message - The message to create - (use `\n` for newlines) + * foregroundBlock (default: black wool) - The block to use for the foreground + * backgroundBlock (default: none) - The block to use for the background - * priority - optional - see events.on() for more information. +#### Example -### events.entitySpawn() +To create a 2-line high message using glowstone... -#### Parameters + blocktype("Hello\nWorld",blocks.glowstone); - * callback - A function which is called whenever the [entity.EntitySpawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntitySpawnHook.html) is fired +![blocktype example][imgbt1] - * priority - optional - see events.on() for more information. +[imgbt1]: img/blocktype1.png -### events.endermanPickupBlock() +### Copy & Paste using Drone -#### Parameters +A drone can be used to copy and paste areas of the game world. - * callback - A function which is called whenever the [entity.EndermanPickupBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanPickupBlockHook.html) is fired +### Drone.copy() method - * priority - optional - see events.on() for more information. +Copies an area so it can be pasted elsewhere. The name can be used for +pasting the copied area elsewhere... -### events.vehicleDamage() +#### Parameters -#### 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 - * callback - A function which is called whenever the [entity.VehicleDamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDamageHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. + drone.copy('somethingCool',10,5,10 ).right(12 ).paste('somethingCool' ); -### events.entityLightningStruck() +### Drone.paste() method -#### Parameters +Pastes a copied area to the current location. - * callback - A function which is called whenever the [entity.EntityLightningStruckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityLightningStruckHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. +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. -### events.entityDespawn() + drone.copy('somethingCool',10,5,10 ) + .right(12 ) + .paste('somethingCool' ); -#### Parameters +### Drone.cylinder() method - * callback - A function which is called whenever the [entity.EntityDespawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDespawnHook.html) is fired +A convenience method for building cylinders. Building begins radius blocks to the right and forward. - * priority - optional - see events.on() for more information. +#### Parameters -### events.vehicleMove() + * 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 -#### Parameters +#### Example - * callback - A function which is called whenever the [entity.VehicleMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleMoveHook.html) is fired +To create a cylinder of Iron 7 blocks in radius and 1 block high... - * priority - optional - see events.on() for more information. + cylinder(blocks.iron, 7 , 1); -### events.projectileHit() +![cylinder example](img/cylinderex1.png) -#### Parameters +### Drone.cylinder0() method - * callback - A function which is called whenever the [entity.ProjectileHitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ProjectileHitHook.html) is fired +A version of cylinder that hollows out the middle. - * priority - optional - see events.on() for more information. +#### Example -### events.entityDeath() +To create a hollow cylinder of Iron 7 blocks in radius and 1 block high... -#### Parameters + cylinder0(blocks.iron, 7, 1); - * callback - A function which is called whenever the [entity.EntityDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDeathHook.html) is fired +![cylinder0 example](img/cylinder0ex1.png) - * priority - optional - see events.on() for more information. +### Drone.door() method -### events.entityTame() +create a door - if a parameter is supplied an Iron door is created otherwise a wooden door is created. -#### Parameters +#### Parameters - * callback - A function which is called whenever the [entity.EntityTameHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityTameHook.html) is fired + * doorType (optional - default wood) - If a parameter is provided then the door is Iron. - * priority - optional - see events.on() for more information. +#### Example -### events.vehicleExit() +To create a wooden door at the crosshairs/drone's location... -#### Parameters + var drone = new Drone(self); + drone.door(); - * callback - A function which is called whenever the [entity.VehicleExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleExitHook.html) is fired +To create an iron door... - * priority - optional - see events.on() for more information. + drone.door( blocks.door_iron ); -### events.dimensionSwitch() +![iron door](img/doorex1.png) -#### Parameters +### Drone.door_iron() method - * callback - A function which is called whenever the [entity.DimensionSwitchHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DimensionSwitchHook.html) is fired +create an Iron door. - * priority - optional - see events.on() for more information. +### Drone.door2() method -### events.foodLevel() +Create double doors (left and right side) -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.FoodLevelHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodLevelHook.html) is fired + * doorType (optional - default wood) - If a parameter is provided then the door is Iron. - * priority - optional - see events.on() for more information. +#### Example -### events.bookEdit() +To create double-doors at the cross-hairs/drone's location... -#### Parameters + drone.door2(); - * callback - A function which is called whenever the [player.BookEditHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BookEditHook.html) is fired +![double doors](img/door2ex1.png) - * priority - optional - see events.on() for more information. +### Drone.door2_iron() method -### events.playerListEntry() +Create double iron doors -#### Parameters +### Drone.firework() method - * callback - A function which is called whenever the [player.PlayerListEntryHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerListEntryHook.html) is fired +Launches a firework at the drone's location. - * priority - optional - see events.on() for more information. +#### Example -### events.eat() +To launch a firework: -#### Parameters + var drone = new Drone(self); + drone.firework(); - * callback - A function which is called whenever the [player.EatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EatHook.html) is fired +### Drone.garden() method - * priority - optional - see events.on() for more information. +places random flowers and long grass (similar to the effect of placing bonemeal on grass) -### events.playerIdle() +#### Parameters -#### Parameters + * width - the width of the garden + * length - how far from the drone the garden extends - * callback - A function which is called whenever the [player.PlayerIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerIdleHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. +To create a garden 10 blocks wide by 5 blocks long... -### events.enchant() + garden(10,5); -#### Parameters +![garden example](img/gardenex1.png) - * callback - A function which is called whenever the [player.EnchantHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EnchantHook.html) is fired +### Drone.ladder() method - * priority - optional - see events.on() for more information. +Creates a ladder extending skyward. -### events.playerArmSwing() +#### Parameters -#### Parameters + * height (optional - default 1) - * callback - A function which is called whenever the [player.PlayerArmSwingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerArmSwingHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. +To create a ladder extending 10 blocks high: -### events.teleport() + var drone = new Drone(self); + drone.ladder(10) -#### Parameters +At the in-game prompt, look at a block and then type: - * callback - A function which is called whenever the [player.TeleportHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/TeleportHook.html) is fired + /js ladder(10) - * priority - optional - see events.on() for more information. +A ladder 10 blocks high will be created at the point you were looking at. -### events.anvilUse() +#### Since +##### 3.0.3 +### Drone Movement -#### Parameters +Drones can move freely in minecraft's 3-D world. You control the +Drone's movement using any of the following methods.. - * callback - A function which is called whenever the [player.AnvilUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/AnvilUseHook.html) is fired + * up() + * down() + * left() + * right() + * fwd() + * back() + * turn() - * priority - optional - see events.on() for more information. +... 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. -### events.portalUse() +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. -#### Parameters +### Drone Positional Info - * callback - A function which is called whenever the [player.PortalUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PortalUseHook.html) is fired + * getLocation() - Returns a native Java Location object for the drone - * priority - optional - see events.on() for more information. +### Drone Markers -### events.foodSaturation() +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. -#### Parameters +A 'start' checkpoint is automatically created when the Drone is first created. - * callback - A function which is called whenever the [player.FoodSaturationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodSaturationHook.html) is fired +Markers are created and returned to using the followng two methods... - * priority - optional - see events.on() for more information. + * 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. -### events.connection() +#### Parameters -#### Parameters + * name - the name of the checkpoint to save or return to. - * callback - A function which is called whenever the [player.ConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ConnectionHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. + 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'); -### events.playerRespawned() +### Drone.prism() method -#### Parameters +Creates a prism. This is useful for roofs on houses. - * callback - A function which is called whenever the [player.PlayerRespawnedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawnedHook.html) is fired +#### Parameters - * priority - optional - see events.on() for more information. + * 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) -### events.armorBroken() +#### Example -#### Parameters + prism(blocks.oak,3,12); - * callback - A function which is called whenever the [player.ArmorBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ArmorBrokenHook.html) is fired +![prism example](img/prismex1.png) - * priority - optional - see events.on() for more information. +### Drone.prism0() method -### events.levelUp() +A variation on `prism` which hollows out the inside of the prism. It +uses the same parameters as `prism`. -#### Parameters +### Drone.rand() method - * callback - A function which is called whenever the [player.LevelUpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/LevelUpHook.html) is fired +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) - * priority - optional - see events.on() for more information. +#### Example -### events.blockRightClick() +place random blocks stone, mossy stone and cracked stone (each block has the same chance of being picked) -#### Parameters + rand( [blocks.brick.stone, blocks.brick.mossy, blocks.brick.cracked ],w,d,h) - * callback - A function which is called whenever the [player.BlockRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockRightClickHook.html) is fired +to place random blocks stone has a 50% chance of being picked, - * priority - optional - see events.on() for more information. + var distribution = {}; + distribution[ blocks.brick.stone ] = 5; + distribution[ blocks.brick.mossy ] = 3; + distribution[ blocks.brick.cracked ] = 2; -### events.itemDrop() + rand( distribution, width, height, depth) -#### Parameters +regular stone has a 50% chance, mossy stone has a 30% chance and cracked stone has just a 20% chance of being picked. - * callback - A function which is called whenever the [player.ItemDropHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemDropHook.html) is fired +### Drone.wallsign() method - * priority - optional - see events.on() for more information. +Creates a wall sign (A sign attached to a wall) -### events.playerRespawning() +#### Parameters -#### Parameters + * message - can be a string or an array of strings - * callback - A function which is called whenever the [player.PlayerRespawningHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawningHook.html) is fired +#### Example - * priority - optional - see events.on() for more information. + drone.wallsign(['Welcome','to','Scriptopia']); -### events.craft() +![wall sign](img/signex2.png) -#### Parameters +### Drone.signpost() method - * callback - A function which is called whenever the [player.CraftHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/CraftHook.html) is fired +Creates a free-standing signpost - * priority - optional - see events.on() for more information. +#### Parameters -### events.experience() + * message - can be a string or an array of strings -#### Parameters +#### Example - * callback - A function which is called whenever the [player.ExperienceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ExperienceHook.html) is fired + drone.signpost(['Hello','World']); - * priority - optional - see events.on() for more information. +![ground sign](img/signex1.png) -### events.signChange() +### Drone.sign() method -#### Parameters +Deprecated: Use signpost() or wallsign() methods instead. - * callback - A function which is called whenever the [player.SignChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignChangeHook.html) is fired +Signs must use block 63 (stand-alone signs) or 68 (signs on walls) - * priority - optional - see events.on() for more information. +#### Parameters -### events.healthChange() + * message - can be a string or an array of strings. + * block - can be 63 or 68 -#### Parameters +#### Example - * callback - A function which is called whenever the [player.HealthChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/HealthChangeHook.html) is fired +To create a free-standing sign... - * priority - optional - see events.on() for more information. + drone.sign(["Hello","World"], blocks.sign_post); -### events.disconnection() +![ground sign](img/signex1.png) -#### Parameters +... to create a wall mounted sign... - * callback - A function which is called whenever the [player.DisconnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/DisconnectionHook.html) is fired + drone.sign(["Welcome","to","Scriptopia"], blocks.sign ); - * priority - optional - see events.on() for more information. +![wall sign](img/signex2.png) -### events.gameModeChange() +### Drone.sphere() method -#### Parameters +Creates a sphere. - * callback - A function which is called whenever the [player.GameModeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/GameModeChangeHook.html) is fired +#### Parameters + + * block - The block the sphere will be made of. + * radius - The radius of the sphere. - * priority - optional - see events.on() for more information. +#### Example -### events.preConnection() +To create a sphere of Iron with a radius of 10 blocks... -#### Parameters + sphere( blocks.iron, 10); - * callback - A function which is called whenever the [player.PreConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PreConnectionHook.html) is fired +![sphere example](img/sphereex1.png) - * priority - optional - see events.on() for more information. +Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the +server to be very busy for a couple of minutes while doing so. -### events.villagerTrade() +### Drone.sphere0() method -#### Parameters +Creates an empty sphere. - * callback - A function which is called whenever the [player.VillagerTradeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/VillagerTradeHook.html) is fired +#### Parameters + + * block - The block the sphere will be made of. + * radius - The radius of the sphere. - * priority - optional - see events.on() for more information. +#### Example -### events.returnFromIdle() +To create a sphere of Iron with a radius of 10 blocks... -#### Parameters + sphere0( blocks.iron, 10); - * callback - A function which is called whenever the [player.ReturnFromIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ReturnFromIdleHook.html) is fired +Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the +server to be very busy for a couple of minutes while doing so. - * priority - optional - see events.on() for more information. +### Drone.hemisphere() method -### events.slotClick() +Creates a hemisphere. Hemispheres can be either north or south. -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.SlotClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SlotClickHook.html) is fired + * block - the block the hemisphere will be made of. + * radius - the radius of the hemisphere + * northSouth - whether the hemisphere is 'north' or 'south' - * priority - optional - see events.on() for more information. +#### Example -### events.entityRightClick() +To create a wood 'north' hemisphere with a radius of 7 blocks... -#### Parameters + hemisphere(blocks.oak, 7, 'north'); - * callback - A function which is called whenever the [player.EntityRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EntityRightClickHook.html) is fired +![hemisphere example](img/hemisphereex1.png) - * priority - optional - see events.on() for more information. +### Drone.hemisphere0() method -### events.foodExhaustion() +Creates a hollow hemisphere. Hemispheres can be either north or south. -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.FoodExhaustionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodExhaustionHook.html) is fired + * block - the block the hemisphere will be made of. + * radius - the radius of the hemisphere + * northSouth - whether the hemisphere is 'north' or 'south' - * priority - optional - see events.on() for more information. +#### Example -### events.chat() +To create a glass 'north' hemisphere with a radius of 20 blocks... -#### Parameters + hemisphere0(blocks.glass, 20, 'north'); - * callback - A function which is called whenever the [player.ChatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ChatHook.html) is fired +![hemisphere example](img/hemisphereex2.png) - * priority - optional - see events.on() for more information. +### Drone.stairs() function -### events.itemPickup() +The stairs() function will build a flight of stairs -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.ItemPickupHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemPickupHook.html) is fired + * blockType - should be one of the following: - * priority - optional - see events.on() for more information. + * 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 -### events.bedExit() + * width - The width of the staircase - default is 1 + * height - The height of the staircase - default is 1 -#### Parameters +#### Example - * callback - A function which is called whenever the [player.BedExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedExitHook.html) is fired +To build an oak staircase 3 blocks wide and 5 blocks tall: - * priority - optional - see events.on() for more information. + /js stairs(blocks.stairs.oak, 3, 5) -### events.blockPlace() +Staircases do not have any blocks beneath them. -#### Parameters +### Drone Trees methods - * callback - A function which is called whenever the [player.BlockPlaceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockPlaceHook.html) is fired + * oak() + * spruce() + * birch() + * jungle() - * priority - optional - see events.on() for more information. +#### Example -### events.toolBroken() +To create 4 trees in a row, point the cross-hairs at the ground then type `/js ` and ... -#### Parameters + up( ).oak( ).right(8 ).spruce( ).right(8 ).birch( ).right(8 ).jungle( ); - * callback - A function which is called whenever the [player.ToolBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ToolBrokenHook.html) is fired +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). - * priority - optional - see events.on() for more information. +![tree example](img/treeex1.png) -### events.kick() +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. -#### Parameters +### Drone.rainbow() method - * callback - A function which is called whenever the [player.KickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/KickHook.html) is fired +Creates a Rainbow. - * priority - optional - see events.on() for more information. +#### Parameters -### events.playerDeath() + * radius (optional - default:18) - The radius of the rainbow -#### Parameters +#### Example + + var d = new Drone(); + d.rainbow(30); - * callback - A function which is called whenever the [player.PlayerDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerDeathHook.html) is fired +![rainbow example](img/rainbowex1.png) - * priority - optional - see events.on() for more information. +### Drone.spiral_stairs() method -### events.blockLeftClick() +Constructs a spiral staircase with slabs at each corner. -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.BlockLeftClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockLeftClickHook.html) is fired + * stairBlock - The block to use for stairs, should be one of the following... + - 'oak' + - 'spruce' + - 'birch' + - 'jungle' + - 'cobblestone' + - 'brick' + - 'stone' + - 'nether' + - 'sandstone' + - 'quartz' + * flights - The number of flights of stairs to build. - * priority - optional - see events.on() for more information. +![Spiral Staircase](img/spiralstair1.png) -### events.blockDestroy() +#### Example -#### Parameters +To construct a spiral staircase 5 floors high made of oak... - * callback - A function which is called whenever the [player.BlockDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockDestroyHook.html) is fired + spiral_stairs('oak', 5); - * priority - optional - see events.on() for more information. +### Drone.stairs() function -### events.bedEnter() +The stairs() function will build a flight of stairs -#### Parameters +#### Parameters - * callback - A function which is called whenever the [player.BedEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedEnterHook.html) is fired + * blockType - should be one of the following: - * priority - optional - see events.on() for more information. + * 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 -### events.signShow() + * width - The width of the staircase - default is 1 + * height - The height of the staircase - default is 1 -#### Parameters +#### Example - * callback - A function which is called whenever the [player.SignShowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignShowHook.html) is fired +To build an oak staircase 3 blocks wide and 5 blocks tall: - * priority - optional - see events.on() for more information. + /js stairs(blocks.stairs.oak, 3, 5) -### events.inventory() - -#### Parameters - - * callback - A function which is called whenever the [player.InventoryHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/InventoryHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.playerMove() - -#### Parameters - - * callback - A function which is called whenever the [player.PlayerMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerMoveHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.itemUse() - -#### Parameters - - * callback - A function which is called whenever the [player.ItemUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemUseHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.ban() - -#### Parameters - - * callback - A function which is called whenever the [player.BanHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BanHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.statGained() - -#### Parameters - - * callback - A function which is called whenever the [player.StatGainedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/StatGainedHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.smeltBegin() - -#### Parameters - - * callback - A function which is called whenever the [world.SmeltBeginHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltBeginHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.treeGrow() - -#### Parameters - - * callback - A function which is called whenever the [world.TreeGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TreeGrowHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.chunkCreated() - -#### Parameters - - * callback - A function which is called whenever the [world.ChunkCreatedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreatedHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.liquidDestroy() - -#### Parameters - - * callback - A function which is called whenever the [world.LiquidDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LiquidDestroyHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.chunkLoaded() - -#### Parameters - - * callback - A function which is called whenever the [world.ChunkLoadedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkLoadedHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.pistonRetract() - -#### Parameters - - * callback - A function which is called whenever the [world.PistonRetractHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonRetractHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.smelt() - -#### Parameters - - * callback - A function which is called whenever the [world.SmeltHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.blockUpdate() - -#### Parameters - - * callback - A function which is called whenever the [world.BlockUpdateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockUpdateHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.portalDestroy() - -#### Parameters - - * callback - A function which is called whenever the [world.PortalDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalDestroyHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.ignition() - -#### Parameters - - * callback - A function which is called whenever the [world.IgnitionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/IgnitionHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.redstoneChange() - -#### Parameters - - * callback - A function which is called whenever the [world.RedstoneChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/RedstoneChangeHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.weatherChange() - -#### Parameters - - * callback - A function which is called whenever the [world.WeatherChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/WeatherChangeHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.chunkCreation() - -#### Parameters - - * callback - A function which is called whenever the [world.ChunkCreationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreationHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.hopperTransfer() - -#### Parameters - - * callback - A function which is called whenever the [world.HopperTransferHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/HopperTransferHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.chunkUnload() - -#### Parameters - - * callback - A function which is called whenever the [world.ChunkUnloadHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkUnloadHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.blockGrow() - -#### Parameters - - * callback - A function which is called whenever the [world.BlockGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockGrowHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.dispense() - -#### Parameters - - * callback - A function which is called whenever the [world.DispenseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DispenseHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.blockDropXp() - -#### Parameters - - * callback - A function which is called whenever the [world.BlockDropXpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockDropXpHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.fireworkExplode() - -#### Parameters - - * callback - A function which is called whenever the [world.FireworkExplodeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FireworkExplodeHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.leafDecay() - -#### Parameters - - * callback - A function which is called whenever the [world.LeafDecayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LeafDecayHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.pistonExtend() - -#### Parameters - - * callback - A function which is called whenever the [world.PistonExtendHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonExtendHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.noteBlockPlay() - -#### Parameters - - * callback - A function which is called whenever the [world.NoteBlockPlayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/NoteBlockPlayHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.lightningStrike() - -#### Parameters - - * callback - A function which is called whenever the [world.LightningStrikeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LightningStrikeHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.decorate() - -#### Parameters - - * callback - A function which is called whenever the [world.DecorateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DecorateHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.explosion() - -#### Parameters - - * callback - A function which is called whenever the [world.ExplosionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ExplosionHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.tNTActivate() - -#### Parameters - - * callback - A function which is called whenever the [world.TNTActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TNTActivateHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.timeChange() - -#### Parameters - - * callback - A function which is called whenever the [world.TimeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TimeChangeHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.flow() - -#### Parameters - - * callback - A function which is called whenever the [world.FlowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FlowHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.portalCreate() - -#### Parameters - - * callback - A function which is called whenever the [world.PortalCreateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalCreateHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.blockPhysics() - -#### Parameters - - * callback - A function which is called whenever the [world.BlockPhysicsHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockPhysicsHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.playerCommand() - -#### Parameters - - * callback - A function which is called whenever the [command.PlayerCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/PlayerCommandHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.consoleCommand() - -#### Parameters - - * callback - A function which is called whenever the [command.ConsoleCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/ConsoleCommandHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.commandBlockCommand() - -#### Parameters - - * callback - A function which is called whenever the [command.CommandBlockCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/CommandBlockCommandHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.loadWorld() - -#### Parameters - - * callback - A function which is called whenever the [system.LoadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/LoadWorldHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.permissionCheck() - -#### Parameters - - * callback - A function which is called whenever the [system.PermissionCheckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PermissionCheckHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.serverGuiStart() - -#### Parameters - - * callback - A function which is called whenever the [system.ServerGuiStartHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerGuiStartHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.unloadWorld() - -#### Parameters - - * callback - A function which is called whenever the [system.UnloadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/UnloadWorldHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.pluginDisable() - -#### Parameters - - * callback - A function which is called whenever the [system.PluginDisableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginDisableHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.pluginEnable() - -#### Parameters - - * callback - A function which is called whenever the [system.PluginEnableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginEnableHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.serverTick() - -#### Parameters - - * callback - A function which is called whenever the [system.ServerTickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerTickHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.serverListPing() - -#### Parameters - - * callback - A function which is called whenever the [system.ServerListPingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerListPingHook.html) is fired - - * priority - optional - see events.on() for more information. - -### events.serverShutdown() - -#### Parameters - - * callback - A function which is called whenever the [system.ServerShutdownHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerShutdownHook.html) is fired - - * priority - optional - see events.on() for more information. +Staircases do not have any blocks beneath them. ## Blocks Module @@ -4047,894 +4978,6 @@ This function also contains values for each possible stat so you can get at stat var utils = require('utils'); var JUMPSTAT = utils.stat.JUMP; // Accessing the value var jumpCount = player.getStat ( JUMPSTAT ); // canary-specific code -## Drone Plugin - -The Drone is a convenience class for building. It can be used for... - - 1. Building - 2. Copying and Pasting - -It uses a fluent interface which means all of the Drone's methods return `this` and can be chained together like so... - - var theDrone = new Drone(self); - theDrone.up().left().box(blocks.oak).down().fwd(3).cylinder0(blocks.lava,8); - -### Constructing a Drone Object - -Drones can be created in any of the following ways... - - 1. Calling any one of the methods listed below will return a Drone object. For example... - - var d = box( blocks.oak ) - - ... creates a 1x1x1 wooden block at the cross-hairs or player's location and returns a Drone object. This might look odd (if you're familiar with Java's Object-dot-method syntax) but all of the Drone class's methods are also global functions that return new Drone objects. This is short-hand for creating drones and is useful for playing around with Drones at the in-game command prompt. It's shorter than typing ... - - var d = new Drone(self).box( blocks.oak ) - - ... All of the Drone's methods return `this` so you can chain operations together like this... - - var d = box( blocks.oak ) - .up() - .box( blocks.oak ,3,1,3) - .down() - .fwd(2) - .box( blocks.oak ) - .turn() - .fwd(2) - .box( blocks.oak ) - .turn() - .fwd(2) - .box( blocks.oak ); - - 2. Using the following form... - - d = new Drone(self) - - ...will create a new Drone taking the current player as the parameter. If the player's cross-hairs are pointing at a block at the time then, that block's location becomes the drone's 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() with either a player or location given as a parameter, then building begins at the location the player was looking at or at the location. You can get around this by pointing at a 'corner stone' just above ground level or alternatively use the following statement... - - d = new Drone(self).up(); - - ... which will move the drone up one block as soon as it's created. - - ![corner stone](img/cornerstone1.png) - - 3. Or by using the following form... - - d = new Drone(x,y,z,direction,world); - - This will create a new Drone at the location you specified using x, y, z In minecraft, the X axis runs west to east and the Z axis runs north to south. The direction parameter says what direction you want the drone to face: 0 = east, 1 = south, 2 = west, 3 = north. If the direction parameter is omitted, the player's direction is used instead. Both the `direction` and `world` parameters are optional. - - 4. Create a new Drone based on a Location object... - - d = new Drone(location); - - This is useful when you want to create a drone at a given `org.bukkit.Location` . The `Location` class is used throughout the bukkit API. For example, if you want to create a drone when a block is broken at the block's location you would do so like this... - - events.blockBreak( function( event ) { - var location = event.block.location; - var drone = new Drone(location); - // do more stuff with the drone here... - }); - -#### Parameters - - * Player : If a player reference is given as the sole parameter then the block the player was looking at will be used as the starting point for the drone. If the player was not looking at a block then the player's location will be used as the starting point. If a `Player` object is provided as a paramter then it should be the only parameter. - * location : *NB* If a `Location` object is provided as a parameter, then it should be the only parameter. - * x : The x coordinate of the Drone (x,y,z,direction and world are not needed if either a player or location parameter is provided) - * y : The y coordinate of the Drone - * z : The z coordinate of the Drone - * direction : The direction in which the Drone is facing. Possible values are 0 (east), 1 (south), 2 (west) or 3 (north) - * world : The world in which the drone is created. - -### Drone.box() method - -the box() method is a convenience method for building things. (For the more performance-oriented method - see cuboid) - -#### parameters - - * b - 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` - * w (optional - default 1) - the width of the structure - * h (optional - default 1) - the height of the structure - * d (optional - default 1) - the depth of the structure - NB this is not how deep underground the structure lies - this is how far away (depth of field) from the drone the structure will extend. - -#### Example - -To create a black structure 4 blocks wide, 9 blocks tall and 1 block long... - - box(blocks.wool.black, 4, 9, 1); - -... or the following code does the same but creates a variable that can be used for further methods... - - var drone = new Drone(self); - drone.box(blocks.wool.black, 4, 9, 1); - -![box example 1](img/boxex1.png) - -### Drone.box0() method - -Another convenience method - this one creates 4 walls with no floor or ceiling. - -#### 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 (optional - default 1) - the width of the structure - * height (optional - default 1) - the height of the structure - * length (optional - default 1) - the length of the structure - how far - away (depth of field) from the drone the structure will extend. - -#### Example - -To create a stone building with the insided hollowed out 7 wide by 3 tall by 6 long... - - box0( blocks.stone, 7, 3, 6); - -![example box0](img/box0ex1.png) - -### Drone.boxa() method - -Construct a cuboid using an array of blocks. As the drone moves first along the width axis, then the height (y axis) then the length, each block is picked from the array and placed. - -#### Parameters - - * blocks - An array of blocks - each block in the array will be placed in turn. - * width - * height - * length - -#### Example - -Construct a rainbow-colored road 100 blocks long... - - var rainbowColors = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, - blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple]; - - boxa(rainbowColors,7,1,30); - -![boxa example](img/boxaex1.png) - -### Chaining - -All of the Drone methods return a Drone object, which means methods can be 'chained' together so instead of writing this... - - drone = new Drone( self ); - drone.fwd( 3 ); - drone.left( 2 ); - drone.box( blocks.grass ); // create a grass block - drone.up(); - drone.box( blocks.grass ); // create another grass block - drone.down(); - -...you could simply write ... - - var drone = new Drone(self).fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down(); - -... since each Drone method is also a global function that constructs a drone if none is supplied, you can shorten even further to just... - - fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down() - -The Drone object uses a [Fluent Interface][fl] to make ScriptCraft scripts more concise and easier to write and read. Minecraft's in-game command prompt is limited to about 80 characters so chaining drone commands together means more can be done before hitting the command prompt limit. For complex building you should save your commands in a new script file and load it using /js load() - -[fl]: http://en.wikipedia.org/wiki/Fluent_interface - -### Drone Properties - - * x - The Drone's position along the west-east axis (x increases as you move east) - * y - The Drone's position along the vertical axis (y increses as you move up) - * z - The Drone's position along the north-south axis (z increases as you move south) - * dir - The Drone's direction 0 is east, 1 is south , 2 is west and 3 is north. - -### Extending Drone - -The Drone object can be easily extended - new buidling recipes/blueprints can be added and can become part of a Drone's chain using the *static* method `Drone.extend`. - -### Drone.extend() static method - -Use this method to add new methods (which also become chainable global functions) to the Drone object. - -#### Parameters - - * name - The name of the new method e.g. 'pyramid'. - * function - The method body. - -Alternatively if you provide just a function as a parameter, then the function name will be used as the new method name. For example the following two approaches are both valid. - -#### Example 1 Using name and function as parameters - - // submitted by [edonaldson][edonaldson] - Drone.extend('pyramid', function( block,height) { - this.chkpt('pyramid'); - for ( var i = height; i > 0; i -= 2) { - this.box(block, i, 1, i).up().right().fwd(); - } - return this.move('pyramid'); - }); - -#### Example 2 Using just a named function as a parameter - - function pyramid( block,height) { - this.chkpt('pyramid'); - for ( var i = height; i > 0; i -= 2) { - this.box(block, i, 1, i).up().right().fwd(); - } - return this.move('pyramid'); - } - Drone.extend( pyramid ); - -Once the method is defined (it can be defined in a new pyramid.js file) it can be used like so... - - var d = new Drone(self); - d.pyramid(blocks.brick.stone, 12); - -... or simply ... - - pyramid(blocks.brick.stone, 12); - -[edonaldson]: https://github.com/edonaldson - -### Drone Constants - -#### Drone.PLAYER_STAIRS_FACING - -An array which can be used when constructing stairs facing in the Drone's direction... - - var d = new Drone(self); - d.box(blocks.stairs.oak + ':' + Drone.PLAYER_STAIRS_FACING[d.dir]); - -... will construct a single oak stair block facing the drone. - -#### Drone.PLAYER_SIGN_FACING - -An array which can be used when placing signs so they face in a given direction. This is used internally by the Drone.sign() method. It should also be used for placing any of the following blocks... - - * chest - * ladder - * furnace - * dispenser - -By default, chests, dispensers, signs, ladders and furnaces are placed facing towards the drone so to place a chest facing the Drone just use: - - drone.box( blocks.chest ); - -To place a chest facing _away_ from the Drone: - - drone.box( blocks.chest + ':' + Drone.PLAYER_SIGN_FACING[(drone.dir + 2) % 4]); - -#### Drone.PLAYER_TORCH_FACING - -Used when placing torches. By default torches will be placed facing up. If you want to place a torch so that it faces towards the drone: - - drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[drone.dir]); - -If you want to place a torch so it faces _away_ from the drone: - - drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[(drone.dir + 2) % 4]); - -### Drone.times() Method - -The times() method makes building multiple copies of buildings -easy. It's possible to create rows or grids of buildings without -resorting to `for` or `while` loops. - -#### Parameters - - * numTimes (optional - default 2) : The number of times you want to repeat the preceding statements. - -#### Example - -Say you want to do the same thing over and over. You have a couple of options... - - * You can use a for loop... - - d = new Drone(); for ( var i =0;i < 4; i++) { d.cottage().right(8); } - -While this will fit on the in-game prompt, it's awkward. You need to -declare a new Drone object first, then write a for loop to create the -4 cottages. It's also error prone, even the `for` loop is too much -syntax for what should really be simple. - - * You can use a while loop... - - d = new Drone(); var i=4; while (i--) { d.cottage().right(8); } - -... which is slightly shorter but still too much syntax. Each of the -above statements is fine for creating a 1-dimensional array of -structures. But what if you want to create a 2-dimensional or -3-dimensional array of structures? Enter the `times()` method. - -The `times()` method lets you repeat commands in a chain any number of -times. So to create 4 cottages in a row you would use the following -statement... - - cottage().right(8).times(4); - -...which will build a cottage, then move right 8 blocks, then do it -again 4 times over so that at the end you will have 4 cottages in a -row. What's more the `times()` method can be called more than once in -a chain. So if you wanted to create a *grid* of 20 houses ( 4 x 5 ), -you would do so using the following statement... - - cottage().right(8).times(4).fwd(8).left(32).times(5); - -... breaking it down... - - 1. The first 3 calls in the chain ( `cottage()`, `right(8)`, `times(4)` ) build a single row of 4 cottages. - - 2. The last 3 calls in the chain ( `fwd(8)`, `left(32)`, `times(5)` ) move the drone forward 8 then left 32 blocks (4 x 8) to return to the original x coordinate, then everything in the chain is repeated again 5 times so that in the end, we have a grid of 20 cottages, 4 x 5. Normally this would require a nested loop but the `times()` method does away with the need for loops when repeating builds. - -Another example: This statement creates a row of trees 2 by 3 ... - - oak().right(10).times(2).left(20).fwd(10).times(3) - -... You can see the results below. - -![times example 1](img/times-trees.png) - -### 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 - -### Drone.bed() method - -Creates a bed. The foot of the bed will be at the drone's location and -the head of the bed will extend away from the drone. - -#### Example -To create a bed at the in-game prompt, look at a block then type: - -```javascript -/js bed() -``` - -Like most Drone methods, this returns the drone so it can be chained like so: - -```javascript -this - .fwd(3) - .bed() - .back(3) -``` -### Drone.blocktype() method - -Creates the text out of blocks. Useful for large-scale in-game signs. - -#### Parameters - - * message - The message to create - (use `\n` for newlines) - * foregroundBlock (default: black wool) - The block to use for the foreground - * backgroundBlock (default: none) - The block to use for the background - -#### Example - -To create a 2-line high message using glowstone... - - blocktype("Hello\nWorld",blocks.glowstone); - -![blocktype example][imgbt1] - -[imgbt1]: img/blocktype1.png - -### 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' ); - -### 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) - -### 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(self); - 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 - -### 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) - -### Drone.ladder() method - -Creates a ladder extending skyward. - -#### Parameters - - * height (optional - default 1) - -#### Example - -To create a ladder extending 10 blocks high: - - var drone = new Drone(self); - drone.ladder(10) - -At the in-game prompt, look at a block and then type: - - /js ladder(10) - -A ladder 10 blocks high will be created at the point you were looking at. - -#### Since -##### 3.0.3 -### 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'); - -### 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`. - -### Drone.rainbow() method - -Creates a Rainbow. - -#### Parameters - - * radius (optional - default:18) - The radius of the rainbow - -#### Example - - var d = new Drone(); - d.rainbow(30); - -![rainbow example](img/rainbowex1.png) - -### 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. - -### Drone.wallsign() method - -Creates a wall sign (A sign attached to a wall) - -#### Parameters - - * message - can be a string or an array of strings - -#### Example - - drone.wallsign(['Welcome','to','Scriptopia']); - -![wall sign](img/signex2.png) - -### Drone.signpost() method - -Creates a free-standing signpost - -#### Parameters - - * message - can be a string or an array of strings - -#### Example - - drone.signpost(['Hello','World']); - -![ground sign](img/signex1.png) - -### Drone.sign() method - -Deprecated: Use signpost() or wallsign() methods instead. - -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"], blocks.sign_post); - -![ground sign](img/signex1.png) - -... to create a wall mounted sign... - - drone.sign(["Welcome","to","Scriptopia"], blocks.sign ); - -![wall sign](img/signex2.png) - -### Drone.sphere() method - -Creates a sphere. - -#### Parameters - - * block - The block the sphere will be made of. - * radius - The radius of the sphere. - -#### Example - -To create a sphere of Iron with a radius of 10 blocks... - - sphere( blocks.iron, 10); - -![sphere example](img/sphereex1.png) - -Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the -server to be very busy for a couple of minutes while doing so. - -### Drone.sphere0() method - -Creates an empty sphere. - -#### Parameters - - * block - The block the sphere will be made of. - * radius - The radius of the sphere. - -#### Example - -To create a sphere of Iron with a radius of 10 blocks... - - sphere0( blocks.iron, 10); - -Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the -server to be very busy for a couple of minutes while doing so. - -### Drone.hemisphere() method - -Creates a hemisphere. Hemispheres can be either north or south. - -#### Parameters - - * block - the block the hemisphere will be made of. - * radius - the radius of the hemisphere - * northSouth - whether the hemisphere is 'north' or 'south' - -#### Example - -To create a wood 'north' hemisphere with a radius of 7 blocks... - - hemisphere(blocks.oak, 7, 'north'); - -![hemisphere example](img/hemisphereex1.png) - -### Drone.hemisphere0() method - -Creates a hollow hemisphere. Hemispheres can be either north or south. - -#### Parameters - - * block - the block the hemisphere will be made of. - * radius - the radius of the hemisphere - * northSouth - whether the hemisphere is 'north' or 'south' - -#### Example - -To create a glass 'north' hemisphere with a radius of 20 blocks... - - hemisphere0(blocks.glass, 20, 'north'); - -![hemisphere example](img/hemisphereex2.png) - -### Drone.spiral_stairs() method - -Constructs a spiral staircase with slabs at each corner. - -#### Parameters - - * stairBlock - The block to use for stairs, should be one of the following... - - 'oak' - - 'spruce' - - 'birch' - - 'jungle' - - 'cobblestone' - - 'brick' - - 'stone' - - 'nether' - - 'sandstone' - - 'quartz' - * flights - The number of flights of stairs to build. - -![Spiral Staircase](img/spiralstair1.png) - -#### Example - -To construct a spiral staircase 5 floors high made of oak... - - spiral_stairs('oak', 5); - -### 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. - -### 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. - ## Example Plugin #1 - A simple extension to Minecraft. A simple minecraft plugin. The most basic module. diff --git a/src/docs/js/generateApiDocs.js b/src/docs/js/generateApiDocs.js index 3a7155c..ee3e101 100644 --- a/src/docs/js/generateApiDocs.js +++ b/src/docs/js/generateApiDocs.js @@ -116,10 +116,13 @@ store.sort(sorter([ /lib\/require\.js$/, /lib\/plugin\.js$/, /lib\/events\.js$/, + /lib\/events\-helper\-canary/, + /lib\/events\-helper\-bukkit/, /lib\//, + /modules\/drone\/index\.js/, + /modules\/drone\//, + /plugins\/drone\//, /modules\//, - /drone\.js/, - /drone\//, /examples\// ])); //err.println("store=" + JSON.stringify(store)); diff --git a/src/main/js/plugins/drone/arc.js b/src/main/js/modules/drone/arc.js similarity index 98% rename from src/main/js/plugins/drone/arc.js rename to src/main/js/modules/drone/arc.js index 95c7bde..6658a37 100644 --- a/src/main/js/plugins/drone/arc.js +++ b/src/main/js/modules/drone/arc.js @@ -41,8 +41,6 @@ stroke width of 2 blocks ... [dv]: http://www.minecraftwiki.net/wiki/Data_values ***/ - -var Drone = require('./drone').Drone; /* do the bresenham thing */ @@ -261,8 +259,9 @@ function arcImpl( params ) { params.drone.move('arc2' ); }; - -Drone.extend(function arc( params ) { - params.drone = this; - arcImpl(params ); -} ); +module.exports = function(Drone){ + Drone.extend(function arc( params ) { + params.drone = this; + arcImpl( params ); + }); +}; diff --git a/src/main/js/modules/drone/bed.js b/src/main/js/modules/drone/bed.js new file mode 100644 index 0000000..a1c29da --- /dev/null +++ b/src/main/js/modules/drone/bed.js @@ -0,0 +1,55 @@ +'use strict'; +/*global require, Packages, __plugin, module*/ +var blocks = require('blocks'); +/************************************************************************ +### Drone.bed() method + +Creates a bed. The foot of the bed will be at the drone's location and +the head of the bed will extend away from the drone. + +#### Example +To create a bed at the in-game prompt, look at a block then type: + +```javascript +/js bed() +``` + +Like most Drone methods, this returns the drone so it can be chained like so: + +```javascript +this + .fwd(3) + .bed() + .back(3) +``` +***/ +var bedDirections = { + 0:3, // east + 1:0, // south + 2:1, // west + 3:2 // north +}; +module.exports = function(Drone){ + + Drone.extend( function bed(){ + this.then(function(){ + var foot = this.setBlock(blocks.bed, bedDirections[this.dir], 0,0,0, false); + var head = this.setBlock(blocks.bed, bedDirections[this.dir] + 8, 0,0,1, false); + if (Drone.bountiful){ + var prop = require('blockhelper').property; + var BedHalf = Packages.net.canarymod.api.world.blocks.properties.BlockPropertyEnums.BedHalf; + prop(foot) + .set('facing',this.dir) + .set('part', BedHalf.FOOT); + prop(head) + .set('facing',this.dir) + .set('part', BedHalf.HEAD); + } + if (__plugin.canary){ + foot.update(); + head.update(); + } + }); + }); +}; + diff --git a/src/main/js/plugins/drone/blocktype.js b/src/main/js/modules/drone/blocktype.js similarity index 98% rename from src/main/js/plugins/drone/blocktype.js rename to src/main/js/modules/drone/blocktype.js index 7710381..dec8356 100644 --- a/src/main/js/plugins/drone/blocktype.js +++ b/src/main/js/modules/drone/blocktype.js @@ -1,4 +1,3 @@ -var Drone = require('./drone').Drone; var blocks = require('blocks'); /************************************************************************ @@ -348,10 +347,10 @@ function blocktype( message, fg, bg, immediate ) { fg = blocks.wool.black; } - bmfg = this._getBlockIdAndMeta( fg ); + bmfg = this.getBlockIdAndMeta( fg ); bmbg = null; if ( typeof bg != 'undefined' ) { - bmbg = this._getBlockIdAndMeta( bg ); + bmbg = this.getBlockIdAndMeta( bg ); } lines = message.split( '\n' ); lineCount = lines.length; @@ -393,7 +392,9 @@ function blocktype( message, fg, bg, immediate ) { return this.move( 'blocktext' ); } -Drone.extend(blocktype); +module.exports = function(Drone){ + Drone.extend(blocktype); +}; diff --git a/src/main/js/plugins/drone/copypaste.js b/src/main/js/modules/drone/copypaste.js similarity index 90% rename from src/main/js/plugins/drone/copypaste.js rename to src/main/js/modules/drone/copypaste.js index b3b7fc5..8b41b0b 100644 --- a/src/main/js/plugins/drone/copypaste.js +++ b/src/main/js/modules/drone/copypaste.js @@ -1,6 +1,6 @@ 'use strict'; -/*global require*/ -var Drone = require('./drone').Drone; +/*global require, module*/ + /************************************************************************ ### Copy & Paste using Drone @@ -37,9 +37,11 @@ point) into memory. the copied area can be referenced using the name .paste('somethingCool' ); ***/ -function paste( name, immediate ) -{ - var ccContent = Drone.clipBoard[name]; +var clipBoard = {}; + +function paste( name, immediate ){ + var Drone = this.constructor; + var ccContent = clipBoard[name]; if (ccContent == undefined){ console.warn('Nothing called ' + name + ' in clipboard!'); return; @@ -59,6 +61,7 @@ function paste( name, immediate ) newDir, dir, a, + c, len; // // need to adjust blocks which face a direction @@ -89,7 +92,7 @@ function paste( name, immediate ) dir = md & 0x3; a = Drone.PLAYER_STAIRS_FACING; len = a.length; - for ( var c=0;c < len;c++ ) { + for ( c = 0; c < len; c++ ) { if ( a[c] == dir ) { break; } @@ -109,7 +112,7 @@ function paste( name, immediate ) case 68: // wall sign a = Drone.PLAYER_SIGN_FACING; len = a.length; - for ( var c=0;c < len;c++ ) { + for ( c=0; c < len; c++ ) { if ( a[c] == md ) { break; } @@ -136,8 +139,10 @@ function copy( name, w, h, d ) { } ); } ); } ); - Drone.clipBoard[name] = {dir: this.dir, blocks: ccContent}; + clipBoard[name] = {dir: this.dir, blocks: ccContent}; } -Drone.clipBoard = {}; -Drone.extend( copy ); -Drone.extend( paste ); + +module.exports = function(Drone){ + Drone.extend( copy ); + Drone.extend( paste ); +}; diff --git a/src/main/js/plugins/drone/cylinders.js b/src/main/js/modules/drone/cylinders.js similarity index 89% rename from src/main/js/plugins/drone/cylinders.js rename to src/main/js/modules/drone/cylinders.js index d62bece..cd5094e 100644 --- a/src/main/js/plugins/drone/cylinders.js +++ b/src/main/js/modules/drone/cylinders.js @@ -32,7 +32,7 @@ To create a hollow cylinder of Iron 7 blocks in radius and 1 block high... ![cylinder0 example](img/cylinder0ex1.png) ***/ -var Drone = require('./drone').Drone; + function cylinder0( block,radius,height,exactParams ) { var arcParams = { radius: radius, @@ -46,7 +46,7 @@ function cylinder0( block,radius,height,exactParams ) { arcParams[p] = exactParams[p]; } }else{ - var md = this._getBlockIdAndMeta(block ); + var md = this.getBlockIdAndMeta(block ); arcParams.blockType = md[0]; arcParams.meta = md[1]; } @@ -64,12 +64,13 @@ function cylinder( block,radius,height,exactParams ) { arcParams.blockType = exactParams.blockType; arcParams.meta = exactParams.meta; }else{ - var md = this._getBlockIdAndMeta(block ); + var md = this.getBlockIdAndMeta(block ); arcParams.blockType = md[0]; arcParams.meta = md[1]; } return this.arc(arcParams ); }; - -Drone.extend(cylinder0 ); -Drone.extend(cylinder ); +module.exports = function(Drone){ + Drone.extend(cylinder0 ); + Drone.extend(cylinder ); +}; diff --git a/src/main/js/plugins/drone/doors.js b/src/main/js/modules/drone/doors.js similarity index 76% rename from src/main/js/plugins/drone/doors.js rename to src/main/js/modules/drone/doors.js index 31b7049..54f5229 100644 --- a/src/main/js/plugins/drone/doors.js +++ b/src/main/js/modules/drone/doors.js @@ -1,3 +1,4 @@ +/*global module*/ 'use strict'; /************************************************************************* ### Drone.door() method @@ -47,8 +48,7 @@ Create double iron doors ***/ -var Drone = require('./drone').Drone, - blocks = require('blocks'); +var blocks = require('blocks'); /*global require, Packages, __plugin*/ function door( doorMaterial, hinge) { if ( typeof doorMaterial == 'undefined' ) { @@ -57,6 +57,7 @@ function door( doorMaterial, hinge) { if (typeof hinge == 'undefined') { hinge = 'left'; } + var Drone = this.constructor; this.then(function(){ var lower = this.setBlock(doorMaterial, this.dir, 0, 0, 0, false); var upper = this.setBlock(doorMaterial, hinge=='left' ? 8 : 9, 0,1,0, false); @@ -77,22 +78,24 @@ function door( doorMaterial, hinge) { } }); } -Drone.extend( door ); +module.exports = function(Drone){ + Drone.extend( door ); -Drone.extend( function door_iron( ) { - this.door(blocks.door_iron); -} ); + Drone.extend( function door_iron( ) { + this.door(blocks.door_iron); + } ); -Drone.extend( function door2( doorMaterial ) { - if ( typeof doorMaterial == 'undefined' ) { - doorMaterial = blocks.door_wood; - } - this - .door( doorMaterial, 'left') - .right() - .door( doorMaterial, 'right') - .left(); -} ); -Drone.extend( function door2_iron( ) { - this.door2( blocks.door_iron ); -} ); + Drone.extend( function door2( doorMaterial ) { + if ( typeof doorMaterial == 'undefined' ) { + doorMaterial = blocks.door_wood; + } + this + .door( doorMaterial, 'left') + .right() + .door( doorMaterial, 'right') + .left(); + } ); + Drone.extend( function door2_iron( ) { + this.door2( blocks.door_iron ); + } ); +}; diff --git a/src/main/js/modules/drone/firework.js b/src/main/js/modules/drone/firework.js new file mode 100644 index 0000000..764750a --- /dev/null +++ b/src/main/js/modules/drone/firework.js @@ -0,0 +1,21 @@ +'use strict'; +/*global module, require*/ +var fireworks = require('fireworks'); +/************************************************************************* +### Drone.firework() method + +Launches a firework at the drone's location. + +#### Example + +To launch a firework: + + var drone = new Drone(self); + drone.firework(); + +***/ +module.exports = function(Drone){ + Drone.extend( function firework( ) { + fireworks.firework( this.getLocation() ); + }); +}; diff --git a/src/main/js/plugins/drone/garden.js b/src/main/js/modules/drone/garden.js similarity index 90% rename from src/main/js/plugins/drone/garden.js rename to src/main/js/modules/drone/garden.js index 0e0ac06..9baf227 100644 --- a/src/main/js/plugins/drone/garden.js +++ b/src/main/js/modules/drone/garden.js @@ -1,3 +1,5 @@ +/*global module, require*/ +'use strict'; /************************************************************************ ### Drone.garden() method @@ -17,7 +19,6 @@ To create a garden 10 blocks wide by 5 blocks long... ![garden example](img/gardenex1.png) ***/ -var Drone = require('./drone').Drone; var blocks = require('blocks'); function garden( width, depth ) { @@ -43,4 +44,6 @@ function garden( width, depth ) { .rand( dist, width, 1, depth, false /* don't overwrite */ ) .down(); } -Drone.extend(garden); +module.exports = function(Drone){ + Drone.extend(garden); +}; diff --git a/src/main/js/modules/drone/index.js b/src/main/js/modules/drone/index.js new file mode 100644 index 0000000..76505e2 --- /dev/null +++ b/src/main/js/modules/drone/index.js @@ -0,0 +1,909 @@ +'use strict'; +/*global __plugin, require, org, setTimeout, addUnloadHandler, global, Packages, server, module*/ +var utils = require('utils'), + blocks = require('blocks'), + THOUSAND = 1000, + MILLION = THOUSAND * THOUSAND; + + +/********************************************************************* +## Drone Plugin + +The Drone is a convenience class for building. It can be used for... + + 1. Building + 2. Copying and Pasting + +It uses a fluent interface which means all of the Drone's methods return `this` and can be chained together like so... + + var theDrone = new Drone(self); + theDrone.up().left().box(blocks.oak).down().fwd(3).cylinder0(blocks.lava,8); + +### Constructing a Drone Object + +Drones can be created in any of the following ways... + + 1. Calling any one of the methods listed below will return a Drone object. For example... + + var d = box( blocks.oak ) + + ... creates a 1x1x1 wooden block at the cross-hairs or player's location and returns a Drone object. This might look odd (if you're familiar with Java's Object-dot-method syntax) but all of the Drone class's methods are also global functions that return new Drone objects. This is short-hand for creating drones and is useful for playing around with Drones at the in-game command prompt. It's shorter than typing ... + + var d = new Drone(self).box( blocks.oak ) + + ... All of the Drone's methods return `this` so you can chain operations together like this... + + var d = box( blocks.oak ) + .up() + .box( blocks.oak ,3,1,3) + .down() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ); + + 2. Using the following form... + + d = new Drone(self) + + ...will create a new Drone taking the current player as the parameter. If the player's cross-hairs are pointing at a block at the time then, that block's location becomes the drone's 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() with either a player or location given as a parameter, then building begins at the location the player was looking at or at the location. You can get around this by pointing at a 'corner stone' just above ground level or alternatively use the following statement... + + d = new Drone(self).up(); + + ... which will move the drone up one block as soon as it's created. + + ![corner stone](img/cornerstone1.png) + + 3. Or by using the following form... + + d = new Drone(x,y,z,direction,world); + + This will create a new Drone at the location you specified using x, y, z In minecraft, the X axis runs west to east and the Z axis runs north to south. The direction parameter says what direction you want the drone to face: 0 = east, 1 = south, 2 = west, 3 = north. If the direction parameter is omitted, the player's direction is used instead. Both the `direction` and `world` parameters are optional. + + 4. Create a new Drone based on a Location object... + + d = new Drone(location); + + This is useful when you want to create a drone at a given `org.bukkit.Location` . The `Location` class is used throughout the bukkit API. For example, if you want to create a drone when a block is broken at the block's location you would do so like this... + + events.blockBreak( function( event ) { + var location = event.block.location; + var drone = new Drone(location); + // do more stuff with the drone here... + }); + +#### Parameters + + * Player : If a player reference is given as the sole parameter then the block the player was looking at will be used as the starting point for the drone. If the player was not looking at a block then the player's location will be used as the starting point. If a `Player` object is provided as a paramter then it should be the only parameter. + * location : *NB* If a `Location` object is provided as a parameter, then it should be the only parameter. + * x : The x coordinate of the Drone (x,y,z,direction and world are not needed if either a player or location parameter is provided) + * y : The y coordinate of the Drone + * z : The z coordinate of the Drone + * direction : The direction in which the Drone is facing. Possible values are 0 (east), 1 (south), 2 (west) or 3 (north) + * world : The world in which the drone is created. + +### Drone.box() method + +the box() method is a convenience method for building things. (For the more performance-oriented method - see cuboid) + +#### parameters + + * b - 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` + * w (optional - default 1) - the width of the structure + * h (optional - default 1) - the height of the structure + * d (optional - default 1) - the depth of the structure - NB this is not how deep underground the structure lies - this is how far away (depth of field) from the drone the structure will extend. + +#### Example + +To create a black structure 4 blocks wide, 9 blocks tall and 1 block long... + + box(blocks.wool.black, 4, 9, 1); + +... or the following code does the same but creates a variable that can be used for further methods... + + var drone = new Drone(self); + drone.box(blocks.wool.black, 4, 9, 1); + +![box example 1](img/boxex1.png) + +### Drone.box0() method + +Another convenience method - this one creates 4 walls with no floor or ceiling. + +#### 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 (optional - default 1) - the width of the structure + * height (optional - default 1) - the height of the structure + * length (optional - default 1) - the length of the structure - how far + away (depth of field) from the drone the structure will extend. + +#### Example + +To create a stone building with the insided hollowed out 7 wide by 3 tall by 6 long... + + box0( blocks.stone, 7, 3, 6); + +![example box0](img/box0ex1.png) + +### Drone.boxa() method + +Construct a cuboid using an array of blocks. As the drone moves first along the width axis, then the height (y axis) then the length, each block is picked from the array and placed. + +#### Parameters + + * blocks - An array of blocks - each block in the array will be placed in turn. + * width + * height + * length + +#### Example + +Construct a rainbow-colored road 100 blocks long... + + var rainbowColors = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, + blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple]; + + boxa(rainbowColors,7,1,30); + +![boxa example](img/boxaex1.png) + +### Chaining + +All of the Drone methods return a Drone object, which means methods can be 'chained' together so instead of writing this... + + drone = new Drone( self ); + drone.fwd( 3 ); + drone.left( 2 ); + drone.box( blocks.grass ); // create a grass block + drone.up(); + drone.box( blocks.grass ); // create another grass block + drone.down(); + +...you could simply write ... + + var drone = new Drone(self).fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down(); + +... since each Drone method is also a global function that constructs a drone if none is supplied, you can shorten even further to just... + + fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down() + +The Drone object uses a [Fluent Interface][fl] to make ScriptCraft scripts more concise and easier to write and read. Minecraft's in-game command prompt is limited to about 80 characters so chaining drone commands together means more can be done before hitting the command prompt limit. For complex building you should save your commands in a new script file and load it using /js load() + +[fl]: http://en.wikipedia.org/wiki/Fluent_interface + +### Drone Properties + + * x - The Drone's position along the west-east axis (x increases as you move east) + * y - The Drone's position along the vertical axis (y increses as you move up) + * z - The Drone's position along the north-south axis (z increases as you move south) + * dir - The Drone's direction 0 is east, 1 is south , 2 is west and 3 is north. + +### Extending Drone + +The Drone object can be easily extended - new buidling recipes/blueprints can be added and can become part of a Drone's chain using the *static* method `Drone.extend`. + +### Drone.extend() static method + +Use this method to add new methods (which also become chainable global functions) to the Drone object. + +#### Parameters + + * name - The name of the new method e.g. 'pyramid'. + * function - The method body. + +Alternatively if you provide just a function as a parameter, then the function name will be used as the new method name. For example the following two approaches are both valid. + +#### Example 1 Using name and function as parameters + + // submitted by [edonaldson][edonaldson] + Drone.extend('pyramid', function( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); + }); + +#### Example 2 Using just a named function as a parameter + + function pyramid( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); + } + Drone.extend( pyramid ); + +Once the method is defined (it can be defined in a new pyramid.js file) it can be used like so... + + var d = new Drone(self); + d.pyramid(blocks.brick.stone, 12); + +... or simply ... + + pyramid(blocks.brick.stone, 12); + +[edonaldson]: https://github.com/edonaldson + +### Drone Constants + +#### Drone.PLAYER_STAIRS_FACING + +An array which can be used when constructing stairs facing in the Drone's direction... + + var d = new Drone(self); + d.box(blocks.stairs.oak + ':' + Drone.PLAYER_STAIRS_FACING[d.dir]); + +... will construct a single oak stair block facing the drone. + +#### Drone.PLAYER_SIGN_FACING + +An array which can be used when placing signs so they face in a given direction. This is used internally by the Drone.sign() method. It should also be used for placing any of the following blocks... + + * chest + * ladder + * furnace + * dispenser + +By default, chests, dispensers, signs, ladders and furnaces are placed facing towards the drone so to place a chest facing the Drone just use: + + drone.box( blocks.chest ); + +To place a chest facing _away_ from the Drone: + + drone.box( blocks.chest + ':' + Drone.PLAYER_SIGN_FACING[(drone.dir + 2) % 4]); + +#### Drone.PLAYER_TORCH_FACING + +Used when placing torches. By default torches will be placed facing up. If you want to place a torch so that it faces towards the drone: + + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[drone.dir]); + +If you want to place a torch so it faces _away_ from the drone: + + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[(drone.dir + 2) % 4]); + +***/ + +// +// Implementation +// ============== +// +// There is no need to read any further unless you want to understand how the Drone object works. +// +function getDirFromRotation( location ) { + // 0 = east, 1 = south, 2 = west, 3 = north + // 46 to 135 = west + // 136 to 225 = north + // 226 to 315 = east + // 316 to 45 = south + var r; + if (__plugin.canary ) { + r = location.rotation; + } + if (__plugin.bukkit) { + r = location.yaw; + } + + // west = -270 + // north = -180 + // east = -90 + // south = 0 + + r = (r + 360 ) % 360; // east could be 270 or -90 + + if ( r > 45 && r <= 135 ) + return 2; // west + if ( r > 135 && r <= 225 ) + return 3; // north + if ( r > 225 && r <= 315 ) + return 0; // east + return 1; // south +} +/* + low-level function to place a block in the world - all drone methods which + place blocks ultimately invoke this function. +*/ +function putBlock( x, y, z, blockId, metadata, world, dir, update ) { + if ( typeof metadata == 'undefined' ) { + metadata = 0; + } + var block = world.getBlockAt( x, y, z ); + + if (__plugin.canary) { + var BlockType = Packages.net.canarymod.api.world.blocks.BlockType; + block.type = BlockType.fromId(blockId); + var applyProperties = require('blockhelper').applyProperties; + applyProperties(block, metadata); + if (typeof update === 'undefined'){ + update = true; + } + if (update){ + block.update(); + } + } + if (__plugin.bukkit) { + block.setTypeIdAndData( blockId, metadata, false ); + block.data = metadata; + } + return block; +} +/* + Drone constructs a new Drone object +*/ +function Drone( x, y, z, dir, world ) { + this.record = false; + var usePlayerCoords = false; + var player = (typeof self !== 'undefined' ? self : null); + var playerPos; + if ( x.location && x.name) { + player = x; + } + playerPos = x.location; + + var that = this; + var populateFromLocation = function( loc ) { + that.x = loc.x; + that.y = loc.y; + that.z = loc.z; + that.dir = getDirFromRotation(loc); + that.world = loc.world; + }; + var mp = utils.getMousePos( player ); + if ( typeof x == 'undefined' || x.location ) { + if ( mp ) { + populateFromLocation( mp ); + if ( playerPos ) { + this.dir = getDirFromRotation(playerPos); + } + } else { + // base it on the player's current location + usePlayerCoords = true; + // + // it's possible that drone.js could be loaded by a non-playing op + // (from the server console) + // + if ( !playerPos ) { + return null; + } + populateFromLocation( playerPos ); + } + } else { + if ( arguments[0].x && arguments[0].y && arguments[0].z ) { + populateFromLocation( arguments[ 0 ] ); + } else { + this.x = x; + this.y = y; + this.z = z; + if ( typeof dir == 'undefined' ) { + this.dir = getDirFromRotation( playerPos); + } else { + this.dir = dir%4; + } + if ( typeof world == 'undefined' ) { + this.world = playerPos.world; + } else { + this.world = world; + } + } + } + + if ( usePlayerCoords ) { + this.fwd( 3 ); + } + this.chkpt( 'start' ); + this.record = true; + this.history = []; + this.player = player; + return this; +} + +Drone.getDirFromRotation = getDirFromRotation; + +Drone.opsPerSec = 10; +var theQueue = []; +function processQueue(){ + var process, + i = 0, + queues = getAllQueues(); + + for ( ; i < queues.length; i++ ) { + process = queues[i].shift(); + if (process){ + try { + process(); + } catch( e ) { + console.log('Drone build error: ' + e + ' while processing ' + process); + } + } + } + setTimeout( processQueue, 1000 / Drone.opsPerSec ); +}; +setTimeout( processQueue, 1000 / Drone.opsPerSec ); + +addUnloadHandler( function() { + var pendingBuildOps = 0; + var allQueues = getAllQueues(); + for (var i = 0; i < allQueues.length; i++){ + pendingBuildOps += allQueues[i].length; + } + if (pendingBuildOps > 0){ + console.warn('There were ' + pendingBuildOps + ' pending build operations which were cancelled'); + } +}); +// +// add custom methods to the Drone object using this function +// +Drone.extend = function( name, func ) { + if (arguments.length == 1){ + func = name; + if ( !func.name ){ + throw 'A Drone extension function must have a name!'; + } + name = func.name; + } + Drone.prototype[ '_' + name ] = func; + Drone.prototype[ name ] = function( ) { + if ( this.record ) { + this.history.push( [ name, arguments ] ); + } + var oldVal = this.record; + this.record = false; + this[ '_' + name ].apply( this, arguments ); + this.record = oldVal; + return this; + }; + + global[name] = function( ) { + var result = new Drone( self ); + result[name].apply( result, arguments ); + return result; + }; +}; + +/************************************************************************** +### Drone.times() Method + +The times() method makes building multiple copies of buildings +easy. It's possible to create rows or grids of buildings without +resorting to `for` or `while` loops. + +#### Parameters + + * numTimes (optional - default 2) : The number of times you want to repeat the preceding statements. + +#### Example + +Say you want to do the same thing over and over. You have a couple of options... + + * You can use a for loop... + + d = new Drone(); for ( var i =0;i < 4; i++) { d.cottage().right(8); } + +While this will fit on the in-game prompt, it's awkward. You need to +declare a new Drone object first, then write a for loop to create the +4 cottages. It's also error prone, even the `for` loop is too much +syntax for what should really be simple. + + * You can use a while loop... + + d = new Drone(); var i=4; while (i--) { d.cottage().right(8); } + +... which is slightly shorter but still too much syntax. Each of the +above statements is fine for creating a 1-dimensional array of +structures. But what if you want to create a 2-dimensional or +3-dimensional array of structures? Enter the `times()` method. + +The `times()` method lets you repeat commands in a chain any number of +times. So to create 4 cottages in a row you would use the following +statement... + + cottage().right(8).times(4); + +...which will build a cottage, then move right 8 blocks, then do it +again 4 times over so that at the end you will have 4 cottages in a +row. What's more the `times()` method can be called more than once in +a chain. So if you wanted to create a *grid* of 20 houses ( 4 x 5 ), +you would do so using the following statement... + + cottage().right(8).times(4).fwd(8).left(32).times(5); + +... breaking it down... + + 1. The first 3 calls in the chain ( `cottage()`, `right(8)`, `times(4)` ) build a single row of 4 cottages. + + 2. The last 3 calls in the chain ( `fwd(8)`, `left(32)`, `times(5)` ) move the drone forward 8 then left 32 blocks (4 x 8) to return to the original x coordinate, then everything in the chain is repeated again 5 times so that in the end, we have a grid of 20 cottages, 4 x 5. Normally this would require a nested loop but the `times()` method does away with the need for loops when repeating builds. + +Another example: This statement creates a row of trees 2 by 3 ... + + oak().right(10).times(2).left(20).fwd(10).times(3) + +... You can see the results below. + +![times example 1](img/times-trees.png) + +***/ +Drone.prototype.times = function( numTimes, commands ) { + if ( typeof numTimes == 'undefined' ) { + numTimes = 2; + } + if ( typeof commands == 'undefined' ) { + commands = this.history.concat(); + } + + this.history = [ [ 'times', [ numTimes + 1, commands ] ] ]; + var oldVal = this.record; + this.record = false; + for ( var j = 1; j < numTimes; j++ ) { + for ( var i = 0; i < commands.length; i++) { + var command = commands[i]; + var methodName = command[0]; + var args = command[1]; + this[ methodName ].apply( this, args ); + } + } + this.record = oldVal; + return this; +}; + + +Drone.prototype.getBlock = function(){ + return this.world.getBlockAt(this.x,this.y,this.z); +}; +Drone.prototype.setBlock = function(blockType, data, ow, oh, od, update){ + if (typeof ow == 'undefined') + ow = 0; + if (typeof oh == 'undefined') + oh = 0; + if (typeof od == 'undefined') + od = 0; + this + .right(ow) + .up(oh) + .fwd(od); + var result = putBlock(this.x, this.y, this.z, blockType, data, this.world, this.dir, update); + this + .left(ow) + .down(oh) + .back(od); + return result; +}; +Drone.prototype.traverseWidth = function(width, callback){ + _traverse[this.dir].width(this, width, callback); +}; +Drone.prototype.traverseHeight = function(height, callback){ + traverseHeight(this, height, callback); +}; +Drone.prototype.traverseDepth = function(depth, callback){ + _traverse[this.dir].depth(this, depth, callback); +}; +// +// building +// + +var playerQueues = {}; +/* + if the drone has an associated player, then use that player's queue otherwise + use the global queue. +*/ +function getQueue( drone ){ + if ( drone.player ) { + var playerName = ''+drone.player.name; + var result = playerQueues[playerName]; + if (result === undefined){ + playerQueues[playerName] = []; + return playerQueues[playerName]; + } + return result; + } else { + return theQueue; + } +} +function getAllQueues() { + var result = [ theQueue ]; + for (var pq in playerQueues) { + result.push(playerQueues[pq]) ; + } + return result; +} +Drone.prototype.cuboida = function(/* Array */ blocks, w, h, d, overwrite, immediate ) { + // + // wph 20140823 make a copy because don't want to modify array in background + // + var blocksForBuild = blocks.slice(); + var len = blocksForBuild.length, + i = 0; + + if ( !immediate ) { + for ( ; i < len; i++ ) { + blocksForBuild[i] = this.getBlockIdAndMeta( blocksForBuild[ i ] ); + } + var clone = Drone.clone(this); + var impl = this.cuboida.bind(clone, blocksForBuild, w, h, d, overwrite, true); + getQueue(this).push( function cuboida(){ impl(); }); + return this; + } + if ( typeof overwrite == 'undefined' ) { + overwrite = true; + } + if ( typeof h == 'undefined' ) { + h = 1; + } + if ( typeof d == 'undefined' ) { + d = 1; + } + if ( typeof w == 'undefined' ) { + w = 1; + } + var bi = 0; + + traverseDHW( this, d,h,w, function traverseWidthCallback( ) { + var properBlock = blocksForBuild[ bi % len ]; + this.setBlock(properBlock[0], properBlock[1]); + bi++; + }); + return this; +}; +Drone.MAX_VOLUME = 1 * MILLION; +Drone.MAX_SIDE = 1 * THOUSAND; + +var tooBig = function(w, h, d ) { + return ( w * h * d ) >= Drone.MAX_VOLUME || + ( w >= Drone.MAX_SIDE ) || + ( h >= Drone.MAX_SIDE ) || + ( d >= Drone.MAX_SIDE ); +}; +/* + faster cuboid because blockid, meta and world must be provided + use this method when you need to repeatedly place blocks + */ +Drone.prototype.cuboidX = function( blockType, meta, w, h, d, immediate ) { + + if ( typeof h == 'undefined' ) { + h = 1; + } + if ( typeof d == 'undefined' ) { + d = 1; + } + if ( typeof w == 'undefined' ) { + w = 1; + } + if ( tooBig( w, h, d ) ) { + this.sign([ + 'Build too Big!', + 'width:' + w, + 'height:' + h, + 'depth:' + d + ], 68); + console.warn('Build too big! ' + w + ' X ' + h + ' X ' + d); + return this; + } + if ( !immediate ) { + var clone = Drone.clone(this); + var impl = this.cuboidX.bind(clone, blockType, meta, w, h, d, true); + getQueue(this).push(function cuboidX(){ impl(); }); + return this; + } + traverseDHW( this, d,h,w, function( ) { + this.setBlock( blockType, meta ); + }); + return this; + +}; +/* + deferred execution of a drone method +*/ +Drone.prototype.then = function( next ){ + getQueue(this).push( next.bind( Drone.clone(this) ) ); +}; +Drone.prototype.cuboid = function( block, w, h, d, immediate ) { + var bm = this.getBlockIdAndMeta( block ); + return this.cuboidX( bm[0], bm[1], w, h, d, immediate); +}; + +Drone.prototype.cuboid0 = function( block, w, h, d, immediate ) { + var start = 'cuboid0' + w + h + d + immediate; + this + .chkpt( start ) + .cuboid( block, w, h, 1, immediate ) // Front wall + .cuboid( block, 1, h, d, immediate ) // Left wall + .right( w - 1 ) + .cuboid( block, 1, h, d, immediate ) // Right wall + .left( w - 1 ) + .fwd( d - 1 ) + .cuboid( block, w, h, 1, immediate ) // Back wall + .move( start ); +}; + + + +// player dirs: 0 = east, 1 = south, 2 = west, 3 = north +// 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) +Drone.PLAYER_SIGN_FACING = [ 4, 2, 5, 3 ]; +Drone.PLAYER_TORCH_FACING = [ 2, 4, 1, 3 ]; + +Drone.extend('box', Drone.prototype.cuboid ); +Drone.extend('box0',Drone.prototype.cuboid0 ); +Drone.extend('boxa',Drone.prototype.cuboida ); +// +// show the Drone's position and direction +// +Drone.prototype.toString = function( ) { + var dirs = ['east','south','west','north']; + return 'x: ' + this.x + ' y: '+this.y + ' z: ' + this.z + ' dir: ' + this.dir + ' '+dirs[this.dir]; +}; +Drone.prototype.debug = function( ) { + console.log(this.toString( ) ); + return this; +}; + +function getBlockIdAndMeta( b ) { + var defaultMeta = 0, + i = 0, + bs, + md, + sp; + if (typeof b === 'number' || /^[0-9]+$/.test(b)) { + // wph 20130414 - use sensible defaults for certain blocks e.g. stairs + // should face the drone. + switch (b) { + case blocks.stairs.oak: + case blocks.stairs.cobblestone: + case blocks.stairs.brick: + case blocks.stairs.stone: + case blocks.stairs.nether: + case blocks.stairs.sandstone: + case blocks.stairs.spruce: + case blocks.stairs.jungle: + case blocks.stairs.quartz: + defaultMeta = Drone.PLAYER_STAIRS_FACING[ this.dir % 4 ]; + break; + case blocks.sign: + case blocks.ladder: + // bug: furnace, chest, dispenser don't always use the right metadata + case blocks.furnace: + case blocks.furnace_burning: + case blocks.chest: + case blocks.enderchest: + case blocks.dispenser: + defaultMeta = Drone.PLAYER_SIGN_FACING[ this.dir % 4 ]; + break; + case blocks.sign_post: + defaultMeta = ( 12 + ( ( this.dir + 2 ) * 4 ) ) % 16; + break; + } + return [ b, defaultMeta ]; + } + if ( typeof b === 'string' ) { + bs = b; + sp = bs.indexOf(':' ); + if ( sp == -1 ) { + b = parseInt( bs ); + return [ b, defaultMeta ]; + } + b = parseInt(bs.substring(0,sp ) ); + md = parseInt(bs.substring(sp+1,bs.length ) ); + return [b,md]; + } + if (b.id){ + // wph 20141230 we are dealing with an object + var blockInfo = b; + var metadata = {}; + for (i in b){ + if (i !== 'id') + metadata[i] = b[i]; + } + return [b.id, metadata]; + } +} +var _traverse = [{},{},{},{}]; +// east +function walkWidthEast( drone, n,callback ) { + var s = drone.z, e = s + n; + for ( ; drone.z < e; drone.z++ ) { + callback.call(drone ,drone.z-s ); + } + drone.z = s; +} +function walkDepthEast( drone,n,callback ) { + var s = drone.x, e = s+n; + for ( ;drone.x < e;drone.x++ ) { + callback.call(drone, drone.x-s ); + } + drone.x = s; +} +function walkWidthSouth( drone,n,callback ) { + var s = drone.x, e = s-n; + for ( ;drone.x > e;drone.x-- ) { + callback.call(drone, s-drone.x ); + } + drone.x = s; +} +function walkWidthWest( drone,n,callback ) { + var s = drone.z, e = s-n; + for ( ;drone.z > e;drone.z-- ) { + callback.call(drone, s-drone.z ); + } + drone.z = s; +} +_traverse[0].width = walkWidthEast; +_traverse[0].depth = walkDepthEast; +// south +_traverse[1].width = walkWidthSouth; +_traverse[1].depth = walkWidthEast; +// west +_traverse[2].width = walkWidthWest; +_traverse[2].depth = walkWidthSouth; +// north +_traverse[3].width = walkDepthEast; +_traverse[3].depth = walkWidthWest; +function traverseHeight( drone,n,callback ) { + var s = drone.y, e = s + n; + for ( ; drone.y < e; drone.y++ ) { + callback.call(drone, drone.y-s ); + } + drone.y = s; +}; +function traverseDHW( drone, d,h,w, callback ){ + _traverse[drone.dir].depth( drone, d, function traverseDepthCallback( ) { + traverseHeight( this, h, function traverseHeightCallback( ) { + _traverse[this.dir].width( this, w, callback); + }); + }); +} + +Drone.clone = function(origin) { + var result = new Drone(origin.x,origin.y,origin.z, origin.dir, origin.world); + return result; +}; +// +// wph 20130130 - make this a method - extensions can use it. +// +Drone.prototype.getBlockIdAndMeta = getBlockIdAndMeta; +Drone.prototype._getBlockIdAndMeta = function(b){ + console.warn('_getBlockIdAndMeta is deprecated. Use .getBlockIdAndMeta() instead'); + return this.getBlockIdAndMeta(b); +}; +Drone.bountiful = __plugin.canary ? parseFloat(server.canaryModVersion) > 1.7 : false; + +var droneCoreExts = [ + './arc', + './bed', + './blocktype', + './copypaste', + './cylinders', + './doors', + './firework', + './garden', + './ladder', + './movement', + './prism', + './rand', + './sign', + './sphere', + './stairs', + './trees' +]; +utils.foreach(droneCoreExts, function(path){ + require(path)(Drone); +}); +module.exports = Drone; diff --git a/src/main/js/plugins/drone/ladder.js b/src/main/js/modules/drone/ladder.js similarity index 90% rename from src/main/js/plugins/drone/ladder.js rename to src/main/js/modules/drone/ladder.js index 6e29116..312648a 100644 --- a/src/main/js/plugins/drone/ladder.js +++ b/src/main/js/modules/drone/ladder.js @@ -1,5 +1,5 @@ 'use strict'; -var Drone = require('./drone').Drone; +/*global require, module*/ /************************************************************************ ### Drone.ladder() method @@ -40,4 +40,7 @@ function ladder( height ){ } }); } -Drone.extend( ladder ); + +module.exports = function(Drone){ + Drone.extend( ladder ); +}; diff --git a/src/main/js/plugins/drone/movement.js b/src/main/js/modules/drone/movement.js similarity index 86% rename from src/main/js/plugins/drone/movement.js rename to src/main/js/modules/drone/movement.js index 293a9e7..2d63d4a 100644 --- a/src/main/js/plugins/drone/movement.js +++ b/src/main/js/modules/drone/movement.js @@ -1,7 +1,5 @@ 'use strict'; -/*global require,__plugin*/ -var Drone = require('./drone').Drone, - bkLocation = org.bukkit.Location; +/*global require,__plugin, module, Packages, org*/ /************************************************************************ ### Drone Movement @@ -89,12 +87,18 @@ _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 ) { +function turn( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + this.dir += n; + this.dir %=4; +} +function chkpt( name ) { this._checkpoints[ name ] = { x:this.x, y:this.y, z:this.z, dir:this.dir }; -}); - -Drone.extend(function move( ) { +} +function move( ) { + var Drone = this.constructor; if ( arguments[0].x && arguments[0].y && arguments[0].z) { this.x = arguments[0].x; this.y = arguments[0].y; @@ -122,64 +126,64 @@ Drone.extend(function move( ) { 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 ) { +} +function right( n ) { if ( typeof n == 'undefined' ) { n = 1; } _movements[ this.dir ].right( this, n ); -}); - -Drone.extend( function left( n ) { +} +function left( n ) { if ( typeof n == 'undefined') { n = 1; } _movements[ this.dir ].left( this, n ); -}); - -Drone.extend( function fwd( n ) { +} +function fwd( n ) { if ( typeof n == 'undefined' ) { n = 1; } _movements[ this.dir ].fwd( this, n ); -}); - -Drone.extend( function back( n ) { +} +function back( n ) { if ( typeof n == 'undefined' ) { n = 1; } _movements[ this.dir ].back( this, n ); -}); - -Drone.extend( function up( n ) { +} +function up( n ) { if ( typeof n == 'undefined' ) { n = 1; } this.y+= n; -}); - -Drone.extend( function down( n ) { +} +function down( n ) { if ( typeof n == 'undefined' ) { n = 1; } this.y-= n; -}); - -Drone.prototype.getLocation = function( ) { +} +function getLocation( ) { 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) { + var bkLocation = org.bukkit.Location; return new bkLocation( this.world, this.x, this.y, this.z ); } +} +module.exports = function(Drone){ + Drone.prototype._checkpoints = {}; + Drone.prototype.getLocation = getLocation; + Drone.extend( chkpt ); + Drone.extend( move ); + Drone.extend( turn ); + Drone.extend( right ); + Drone.extend( left ); + Drone.extend( fwd ); + Drone.extend( back ); + Drone.extend( up ); + Drone.extend( down ); }; + diff --git a/src/main/js/plugins/drone/prism.js b/src/main/js/modules/drone/prism.js similarity index 94% rename from src/main/js/plugins/drone/prism.js rename to src/main/js/modules/drone/prism.js index 2fce9e1..1096514 100644 --- a/src/main/js/plugins/drone/prism.js +++ b/src/main/js/modules/drone/prism.js @@ -1,6 +1,5 @@ 'use strict'; -/*global require*/ -var Drone = require('./drone').Drone; +/*global require, module*/ /************************************************************************ ### Drone.prism() method @@ -93,5 +92,7 @@ function prism0( block,w,d ) { .back(); } } -Drone.extend(prism0); -Drone.extend(prism); +module.exports = function(Drone){ + Drone.extend(prism0); + Drone.extend(prism); +}; diff --git a/src/main/js/plugins/drone/rand.js b/src/main/js/modules/drone/rand.js similarity index 92% rename from src/main/js/plugins/drone/rand.js rename to src/main/js/modules/drone/rand.js index a1c75ca..8a7ec1a 100644 --- a/src/main/js/plugins/drone/rand.js +++ b/src/main/js/modules/drone/rand.js @@ -1,5 +1,5 @@ 'use strict'; -/*global require*/ +/*global require, module*/ /************************************************************************ ### Drone.rand() method @@ -23,7 +23,6 @@ to place random blocks stone has a 50% chance of being picked, 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 // @@ -56,11 +55,13 @@ function _rand( blockDistribution ) { fisherYates(blockDistribution ); return blockDistribution; } - -Drone.extend( function rand( dist, width, height, depth, overwrite ) { +function rand( dist, width, height, depth, overwrite ) { if ( typeof overwrite == 'undefined' ) { overwrite = true; } var randomized = _rand( dist ); this.boxa( randomized, width, height, depth, overwrite); -} ); +} +module.exports = function(Drone){ + Drone.extend( rand ); +}; diff --git a/src/main/js/plugins/drone/sign.js b/src/main/js/modules/drone/sign.js similarity index 92% rename from src/main/js/plugins/drone/sign.js rename to src/main/js/modules/drone/sign.js index 9af69f2..8d84a7f 100644 --- a/src/main/js/plugins/drone/sign.js +++ b/src/main/js/modules/drone/sign.js @@ -1,7 +1,6 @@ 'use strict'; -/*global require, echo,__plugin*/ -var Drone = require('./drone').Drone, - blocks = require('blocks'); +/*global require, echo,__plugin, module*/ +var blocks = require('blocks'); /************************************************************************ ### Drone.wallsign() method @@ -124,7 +123,7 @@ function sign( message, block ) { if ( message.constructor != Array ) { message = [message]; } - var bm = this._getBlockIdAndMeta( block ); + var bm = this.getBlockIdAndMeta( block ); block = bm[0]; var meta = bm[1]; if ( block !== blocks.sign_post && block !== blocks.sign ) { @@ -138,6 +137,8 @@ function sign( message, block ) { putSign( this, message, block, meta); } -Drone.extend(sign); -Drone.extend(signpost); -Drone.extend(wallsign); +module.exports = function(Drone){ + Drone.extend(sign); + Drone.extend(signpost); + Drone.extend(wallsign); +}; diff --git a/src/main/js/plugins/drone/sphere.js b/src/main/js/modules/drone/sphere.js similarity index 92% rename from src/main/js/plugins/drone/sphere.js rename to src/main/js/modules/drone/sphere.js index bffea0a..c805654 100644 --- a/src/main/js/plugins/drone/sphere.js +++ b/src/main/js/modules/drone/sphere.js @@ -1,5 +1,5 @@ -var Drone = require('./drone').Drone; - +'use strict'; +/*global module*/ /************************************************************************ ### Drone.sphere() method @@ -22,11 +22,11 @@ Spheres are time-consuming to make. You *can* make large spheres (250 radius) bu server to be very busy for a couple of minutes while doing so. ***/ -Drone.extend( 'sphere', function( block, radius ) { +function sphere( block, radius ) { var lastRadius = radius, slices = [ [ radius , 0 ] ], diameter = radius * 2, - bm = this._getBlockIdAndMeta( block ), + bm = this.getBlockIdAndMeta( block ), r2 = radius * radius, i = 0, newRadius, @@ -83,7 +83,7 @@ Drone.extend( 'sphere', function( block, radius ) { .down( v ); } return this.move( 'sphere' ); -}); +} /************************************************************************ ### Drone.sphere0() method @@ -104,12 +104,12 @@ Spheres are time-consuming to make. You *can* make large spheres (250 radius) bu server to be very busy for a couple of minutes while doing so. ***/ -Drone.extend('sphere0', function(block,radius) +function sphere0(block,radius) { var lastRadius = radius, slices = [ [ radius, 0 ] ], diameter = radius * 2, - bm = this._getBlockIdAndMeta( block ), + bm = this.getBlockIdAndMeta( block ), r2 = radius*radius, i, newRadius, @@ -185,7 +185,7 @@ Drone.extend('sphere0', function(block,radius) return this; -}); +} /************************************************************************ ### Drone.hemisphere() method @@ -206,11 +206,11 @@ To create a wood 'north' hemisphere with a radius of 7 blocks... ![hemisphere example](img/hemisphereex1.png) ***/ -Drone.extend( 'hemisphere', function( block, radius, northSouth ) { +function hemisphere( block, radius, northSouth ) { var lastRadius = radius, slices = [ [ radius, 0 ] ], diameter = radius * 2, - bm = this._getBlockIdAndMeta(block), + bm = this.getBlockIdAndMeta(block), r2 = radius * radius, i = 0, newRadius; @@ -260,7 +260,7 @@ Drone.extend( 'hemisphere', function( block, radius, northSouth ) { } } return this.move( 'hsphere' ); -}); +} /************************************************************************ ### Drone.hemisphere0() method @@ -281,22 +281,16 @@ To create a glass 'north' hemisphere with a radius of 20 blocks... ![hemisphere example](img/hemisphereex2.png) ***/ -Drone.extend( 'hemisphere0', function( block, radius, northSouth ) { +function hemisphere0( block, radius, northSouth ) { if ( radius > 255 ) { throw new Error('Hemisphere radius must be less than 256 blocks'); } -/* - return this.hemisphere( block, radius, northSouth) - .fwd().right().up( northSouth == 'north' ? 0 : 1 ) - .hemisphere( 0, radius-1, northSouth ) - .back().left().down( northSouth == 'north' ? 0 : 1 ); -*/ var lastRadius = radius, slices = [ [ radius, 0 ] ], diameter = radius * 2, - bm = this._getBlockIdAndMeta(block), + bm = this.getBlockIdAndMeta(block), r2 = radius * radius, i = 0, len, @@ -393,4 +387,10 @@ Drone.extend( 'hemisphere0', function( block, radius, northSouth ) { } return this.move( 'hsphere0' ); -}); +} +module.exports = function(Drone){ + Drone.extend( sphere ); + Drone.extend( sphere0 ); + Drone.extend( hemisphere ); + Drone.extend( hemisphere0 ); +}; diff --git a/src/main/js/plugins/drone/stairs.js b/src/main/js/modules/drone/stairs.js similarity index 87% rename from src/main/js/plugins/drone/stairs.js rename to src/main/js/modules/drone/stairs.js index f0e61d7..1576a46 100644 --- a/src/main/js/plugins/drone/stairs.js +++ b/src/main/js/modules/drone/stairs.js @@ -1,3 +1,5 @@ +'use strict'; +/*global module*/ /************************************************************************** ### Drone.stairs() function @@ -30,8 +32,7 @@ To build an oak staircase 3 blocks wide and 5 blocks tall: Staircases do not have any blocks beneath them. ***/ -var Drone = require('./drone').Drone, - blocks = require('blocks'); +var blocks = require('blocks'); /*global require*/ function stairs(blockType, width, height){ if (typeof width === 'undefined') @@ -42,7 +43,7 @@ function stairs(blockType, width, height){ blockType = blocks.stairs.oak; } this.then(function(){ - var bm = this._getBlockIdAndMeta(blockType); + var bm = this.getBlockIdAndMeta(blockType); this.chkpt('_stairs'); while (height > 0) { this.traverseWidth(width, function(){ @@ -56,4 +57,6 @@ function stairs(blockType, width, height){ }); } -Drone.extend(stairs); +module.exports = function(Drone){ + Drone.extend(stairs); +}; diff --git a/src/main/js/plugins/drone/test.js b/src/main/js/modules/drone/test.js similarity index 60% rename from src/main/js/plugins/drone/test.js rename to src/main/js/modules/drone/test.js index 5057151..5b870b8 100644 --- a/src/main/js/plugins/drone/test.js +++ b/src/main/js/modules/drone/test.js @@ -1,6 +1,6 @@ -var Drone = require('./drone').Drone; - -Drone.prototype.testHorizontalStrokeWidth = function(){ +'use strict'; +/*global module*/ +function testHorizontalStrokeWidth(){ this.arc({ blockType: 42, meta: 0, @@ -9,9 +9,8 @@ Drone.prototype.testHorizontalStrokeWidth = function(){ strokeWidth: 3, quadrants: {topright:true,topleft:true,bottomleft:true,bottomright:true} }); -}; - -Drone.prototype.testVerticalStrokeWidth = function(){ +} +function testVerticalStrokeWidth(){ this.arc({ blockType: 42, meta: 0, @@ -20,4 +19,8 @@ Drone.prototype.testVerticalStrokeWidth = function(){ strokeWidth: 3, quadrants: {topright:true,topleft:true,bottomleft:true,bottomright:true} }); +} +module.exports = function(Drone){ + Drone.prototype.testHorizontalStrokeWidth = testHorizontalStrokeWidth; + Drone.prototype.testVerticalStrokeWidth = testVerticalStrokeWidth; }; diff --git a/src/main/js/plugins/drone/trees.js b/src/main/js/modules/drone/trees.js similarity index 95% rename from src/main/js/plugins/drone/trees.js rename to src/main/js/modules/drone/trees.js index 25855cb..797c418 100644 --- a/src/main/js/plugins/drone/trees.js +++ b/src/main/js/modules/drone/trees.js @@ -1,5 +1,5 @@ 'use strict'; -/*global require, __plugin, Packages, org, echo */ +/*global require, __plugin, Packages, org, echo, module */ var blocks = require('blocks'); /************************************************************************ ### Drone Trees methods @@ -28,7 +28,6 @@ successful if the tree is placed on grass in a setting where trees can grow. ***/ -var Drone = require('./drone').Drone; function bukkitTreeFactory( k, v ) { return function( ) { var block = this.getBlock(); @@ -71,7 +70,7 @@ function canaryTreeFactory( k, v ){ } }; } -function main(){ +module.exports = function (Drone){ var trees = { oak: null, birch: null, @@ -96,5 +95,5 @@ function main(){ Drone.extend(p, bukkitTreeFactory ( p, trees[p] ) ); } } -} -main(); +}; + diff --git a/src/main/js/plugins/drone/bed.js b/src/main/js/plugins/drone/bed.js deleted file mode 100644 index 86c1303..0000000 --- a/src/main/js/plugins/drone/bed.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict'; -/*global require, Packages, __plugin*/ -var Drone = require('./drone').Drone, - blocks = require('blocks'); -/************************************************************************ -### Drone.bed() method - -Creates a bed. The foot of the bed will be at the drone's location and -the head of the bed will extend away from the drone. - -#### Example -To create a bed at the in-game prompt, look at a block then type: - -```javascript -/js bed() -``` - -Like most Drone methods, this returns the drone so it can be chained like so: - -```javascript -this - .fwd(3) - .bed() - .back(3) -``` -***/ -var bedDirections = { - 0:3, // east - 1:0, // south - 2:1, // west - 3:2 // north -}; -function bed(){ - this.then(function(){ - var foot = this.setBlock(blocks.bed, bedDirections[this.dir], 0,0,0, false); - var head = this.setBlock(blocks.bed, bedDirections[this.dir] + 8, 0,0,1, false); - if (Drone.bountiful){ - var prop = require('blockhelper').property; - var BedHalf = Packages.net.canarymod.api.world.blocks.properties.BlockPropertyEnums.BedHalf; - prop(foot) - .set('facing',this.dir) - .set('part', BedHalf.FOOT); - prop(head) - .set('facing',this.dir) - .set('part', BedHalf.HEAD); - } - if (__plugin.canary){ - foot.update(); - head.update(); - } - }); - -} -Drone.extend( bed ); - diff --git a/src/main/js/plugins/drone/contrib/castle.js b/src/main/js/plugins/drone/contrib/castle.js index d7d7d50..baba3c8 100644 --- a/src/main/js/plugins/drone/contrib/castle.js +++ b/src/main/js/plugins/drone/contrib/castle.js @@ -1,4 +1,4 @@ -var Drone = require('../drone').Drone; +var Drone = require('drone'); // // a castle is just a big wide fort with 4 taller forts at each corner // diff --git a/src/main/js/plugins/drone/contrib/chessboard.js b/src/main/js/plugins/drone/contrib/chessboard.js index 6f773e4..145c54d 100644 --- a/src/main/js/plugins/drone/contrib/chessboard.js +++ b/src/main/js/plugins/drone/contrib/chessboard.js @@ -1,4 +1,4 @@ -var Drone = require('../drone').Drone; +var Drone = require('drone'); var blocks = require('blocks'); /** diff --git a/src/main/js/plugins/drone/contrib/cottage.js b/src/main/js/plugins/drone/contrib/cottage.js index 627578c..4affef6 100644 --- a/src/main/js/plugins/drone/contrib/cottage.js +++ b/src/main/js/plugins/drone/contrib/cottage.js @@ -1,4 +1,4 @@ -var Drone = require('../drone').Drone; +var Drone = require('drone'); var blocks = require('blocks'); // // usage: diff --git a/src/main/js/plugins/drone/contrib/dancefloor.js b/src/main/js/plugins/drone/contrib/dancefloor.js index 885e69c..abd1946 100644 --- a/src/main/js/plugins/drone/contrib/dancefloor.js +++ b/src/main/js/plugins/drone/contrib/dancefloor.js @@ -1,4 +1,4 @@ -var Drone = require('../drone').Drone; +var Drone = require('drone'); var blocks = require('blocks'); // // Create a floor of colored tiles some of which emit light. diff --git a/src/main/js/plugins/drone/contrib/fort.js b/src/main/js/plugins/drone/contrib/fort.js index b51f87b..69619ff 100644 --- a/src/main/js/plugins/drone/contrib/fort.js +++ b/src/main/js/plugins/drone/contrib/fort.js @@ -1,5 +1,5 @@ 'use strict'; -var Drone = require('../drone').Drone; +var Drone = require('drone'); var blocks = require('blocks'); // // constructs a medieval fort diff --git a/src/main/js/plugins/drone/contrib/hangtorch.js b/src/main/js/plugins/drone/contrib/hangtorch.js index 34edd7a..5ec7258 100644 --- a/src/main/js/plugins/drone/contrib/hangtorch.js +++ b/src/main/js/plugins/drone/contrib/hangtorch.js @@ -1,6 +1,6 @@ 'use strict'; /*global require, __plugin, org*/ -var Drone = require('../drone').Drone, +var Drone = require('drone'), bkMaterial = org.bukkit.Material, blocks = require('blocks'); @@ -21,7 +21,7 @@ function canHang( block ) { return false; } function hangtorch() { - var torch = '50:' + Drone.PLAYER_TORCH_FACING[this.dir]; + var torch = blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[this.dir]; var moves = 0; var block = this.getBlock(); diff --git a/src/main/js/plugins/drone/contrib/lcd-clock.js b/src/main/js/plugins/drone/contrib/lcd-clock.js index 0cfd769..f813c69 100644 --- a/src/main/js/plugins/drone/contrib/lcd-clock.js +++ b/src/main/js/plugins/drone/contrib/lcd-clock.js @@ -10,10 +10,7 @@ /js clock.stop24(); ... stops the clock... */ -var Drone = require('../drone').Drone, - blocktype = require('../blocktype'), - blocks = require('blocks'); - +var blocks = require('blocks'); exports.LCDClock = function(drone, fgColor,bgColor,border) { diff --git a/src/main/js/plugins/drone/contrib/logo.js b/src/main/js/plugins/drone/contrib/logo.js index 77631eb..c5ad9c4 100644 --- a/src/main/js/plugins/drone/contrib/logo.js +++ b/src/main/js/plugins/drone/contrib/logo.js @@ -1,4 +1,7 @@ -var Drone = require('../drone').Drone; +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); // // Constructs the JS logo @@ -9,61 +12,77 @@ var Drone = require('../drone').Drone; // bg // the material that the square will be made of // -Drone.extend('logojs', function(fg, bg) { +function logojs(fg, bg) { // foreground defaults to gray wool if (typeof fg == "undefined") - fg = '35:7'; + fg = blocks.wool.gray; // background defaults to gold blocks if (typeof bg == "undefined") - bg = 41; + bg = blocks.gold; // Draw the sqaure - this.chkpt('logojs-start') - .up() - .box(bg, 100, 100, 1); + this + .chkpt('logojs-start') + .up() + .box(bg, 100, 100, 1); // Draw the J, starting with the hook - this.right(30).up(13) - .box(fg) - .right().down() - .box(fg, 1, 3, 1) - .right().down() - .box(fg, 1, 5, 1) - .right().down() - .box(fg, 1, 7, 1) - .right() - .box(fg, 1, 8, 1) - .right().down() - .box(fg, 1, 10, 1) - .right() - .box(fg, 1, 9, 1) - .right() - .box(fg, 1, 8, 1) - .right().down() - .box(fg, 2, 8, 1) - .right(2) - .box(fg, 4, 7, 1) - .right(4) - .box(fg, 1, 8, 1) - .right() - .box(fg, 1, 9, 1) - .right().up() - .box(fg, 3, 10, 1) - .right(3).up() - .box(fg, 2, 9, 1) - .right(2).up() - .box(fg, 2, 8, 1) - .right(2).up() - .box(fg, 1, 7, 1) - .right().up() - .box(fg, 1, 6, 1) - .right().up() - .box(fg, 1, 5, 1) - .right().up(2) - .box(fg, 1, 3, 1) - .left(9).up(3) - .box(fg, 10, 31, 1) + this + .right(30) + .up(13) + .box(fg) + .right() + .down() + .box(fg, 1, 3, 1) + .right() + .down() + .box(fg, 1, 5, 1) + .right() + .down() + .box(fg, 1, 7, 1) + .right() + .box(fg, 1, 8, 1) + .right() + .down() + .box(fg, 1, 10, 1) + .right() + .box(fg, 1, 9, 1) + .right() + .box(fg, 1, 8, 1) + .right() + .down() + .box(fg, 2, 8, 1) + .right(2) + .box(fg, 4, 7, 1) + .right(4) + .box(fg, 1, 8, 1) + .right() + .box(fg, 1, 9, 1) + .right() + .up() + .box(fg, 3, 10, 1) + .right(3) + .up() + .box(fg, 2, 9, 1) + .right(2) + .up() + .box(fg, 2, 8, 1) + .right(2) + .up() + .box(fg, 1, 7, 1) + .right() + .up() + .box(fg, 1, 6, 1) + .right() + .up() + .box(fg, 1, 5, 1) + .right() + .up(2) + .box(fg, 1, 3, 1) + .left(9) + .up(3) + .box(fg, 10, 31, 1) // Draw the S // It's drawn in three strokes from bottom to top. Look for when @@ -181,7 +200,7 @@ Drone.extend('logojs', function(fg, bg) { this.move('logojs-start'); return this; -}); +} // // Makes a cube of JS logos! // This is a wrapper for logojs() so look at its docs @@ -189,7 +208,7 @@ Drone.extend('logojs', function(fg, bg) { // Until the drone can rotate on its Z axis we can't // use logojs() to create top/bottom sides of cube. // -Drone.extend('logojscube', function(fg, bg) { +function logojscube(fg, bg) { this.chkpt('jscube-start') .logojs(fg, bg); @@ -216,4 +235,6 @@ Drone.extend('logojscube', function(fg, bg) { .logojs(fg, bg); return this; -}); +} +Drone.extend( logojs ); +Drone.extend( logojscube ); diff --git a/src/main/js/plugins/drone/contrib/mazegen.js b/src/main/js/plugins/drone/contrib/mazegen.js index 4a0364f..8f20a30 100644 --- a/src/main/js/plugins/drone/contrib/mazegen.js +++ b/src/main/js/plugins/drone/contrib/mazegen.js @@ -1,6 +1,6 @@ // Maze generation based on http://rosettacode.org/wiki/Maze_generation#JavaScript -var Drone = require('../drone').Drone; +var Drone = require('drone'); // User-facing code starts here // Example: Try /js maze(5,7) Drone.extend( function maze( size_x, size_y ) { diff --git a/src/main/js/plugins/drone/contrib/rainbow.js b/src/main/js/plugins/drone/contrib/rainbow.js index a16f179..dd24d88 100644 --- a/src/main/js/plugins/drone/contrib/rainbow.js +++ b/src/main/js/plugins/drone/contrib/rainbow.js @@ -1,5 +1,7 @@ -var Drone = require('../drone').Drone; -var blocks = require('blocks'); +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); /************************************************************************ ### Drone.rainbow() method @@ -33,7 +35,7 @@ function rainbow( radius ) { colors = blocks.rainbow.slice(0); colors.push(blocks.air); for ( i = 0; i < colors.length; i++ ) { - bm = this._getBlockIdAndMeta( colors[i] ); + bm = this.getBlockIdAndMeta( colors[i] ); this.arc({ blockType: bm[0], meta: bm[1], diff --git a/src/main/js/plugins/drone/contrib/redstonewire.js b/src/main/js/plugins/drone/contrib/redstonewire.js index 19d256a..fa74a62 100644 --- a/src/main/js/plugins/drone/contrib/redstonewire.js +++ b/src/main/js/plugins/drone/contrib/redstonewire.js @@ -1,5 +1,7 @@ -var Drone = require('../drone').Drone; -var blocks = require('blocks'); +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); // // usage: diff --git a/src/main/js/plugins/drone/contrib/spiral_stairs.js b/src/main/js/plugins/drone/contrib/spiral_stairs.js index 7f52b14..4f9b356 100644 --- a/src/main/js/plugins/drone/contrib/spiral_stairs.js +++ b/src/main/js/plugins/drone/contrib/spiral_stairs.js @@ -1,5 +1,7 @@ -var Drone = require('../drone').Drone; -var blocks = require('blocks'); +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); /************************************************************************ ### Drone.spiral_stairs() method diff --git a/src/main/js/plugins/drone/contrib/temple.js b/src/main/js/plugins/drone/contrib/temple.js index a04b197..d2436ca 100644 --- a/src/main/js/plugins/drone/contrib/temple.js +++ b/src/main/js/plugins/drone/contrib/temple.js @@ -1,5 +1,5 @@ -var Drone = require('../drone').Drone; -var blocks = require('blocks'); +var Drone = require('drone'), + blocks = require('blocks'); // // constructs a mayan temple // diff --git a/src/main/js/plugins/drone/drone-firework.js b/src/main/js/plugins/drone/drone-firework.js deleted file mode 100644 index 8ffddbc..0000000 --- a/src/main/js/plugins/drone/drone-firework.js +++ /dev/null @@ -1,6 +0,0 @@ -var fireworks = require('fireworks'); -var Drone = require('./drone').Drone; -Drone.extend( 'firework', function( ) { - fireworks.firework( this.getLocation() ); -}); - diff --git a/src/main/js/plugins/drone/drone.js b/src/main/js/plugins/drone/drone.js index 5ceb569..54931e7 100644 --- a/src/main/js/plugins/drone/drone.js +++ b/src/main/js/plugins/drone/drone.js @@ -1,882 +1,4 @@ /*global __plugin, require, org, setTimeout, addUnloadHandler, exports, global, Packages, server*/ -var utils = require('utils'), - blocks = require('blocks'), - THOUSAND = 1000, - MILLION = THOUSAND * THOUSAND; - - -/********************************************************************* -## Drone Plugin - -The Drone is a convenience class for building. It can be used for... - - 1. Building - 2. Copying and Pasting - -It uses a fluent interface which means all of the Drone's methods return `this` and can be chained together like so... - - var theDrone = new Drone(self); - theDrone.up().left().box(blocks.oak).down().fwd(3).cylinder0(blocks.lava,8); - -### Constructing a Drone Object - -Drones can be created in any of the following ways... - - 1. Calling any one of the methods listed below will return a Drone object. For example... - - var d = box( blocks.oak ) - - ... creates a 1x1x1 wooden block at the cross-hairs or player's location and returns a Drone object. This might look odd (if you're familiar with Java's Object-dot-method syntax) but all of the Drone class's methods are also global functions that return new Drone objects. This is short-hand for creating drones and is useful for playing around with Drones at the in-game command prompt. It's shorter than typing ... - - var d = new Drone(self).box( blocks.oak ) - - ... All of the Drone's methods return `this` so you can chain operations together like this... - - var d = box( blocks.oak ) - .up() - .box( blocks.oak ,3,1,3) - .down() - .fwd(2) - .box( blocks.oak ) - .turn() - .fwd(2) - .box( blocks.oak ) - .turn() - .fwd(2) - .box( blocks.oak ); - - 2. Using the following form... - - d = new Drone(self) - - ...will create a new Drone taking the current player as the parameter. If the player's cross-hairs are pointing at a block at the time then, that block's location becomes the drone's 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() with either a player or location given as a parameter, then building begins at the location the player was looking at or at the location. You can get around this by pointing at a 'corner stone' just above ground level or alternatively use the following statement... - - d = new Drone(self).up(); - - ... which will move the drone up one block as soon as it's created. - - ![corner stone](img/cornerstone1.png) - - 3. Or by using the following form... - - d = new Drone(x,y,z,direction,world); - - This will create a new Drone at the location you specified using x, y, z In minecraft, the X axis runs west to east and the Z axis runs north to south. The direction parameter says what direction you want the drone to face: 0 = east, 1 = south, 2 = west, 3 = north. If the direction parameter is omitted, the player's direction is used instead. Both the `direction` and `world` parameters are optional. - - 4. Create a new Drone based on a Location object... - - d = new Drone(location); - - This is useful when you want to create a drone at a given `org.bukkit.Location` . The `Location` class is used throughout the bukkit API. For example, if you want to create a drone when a block is broken at the block's location you would do so like this... - - events.blockBreak( function( event ) { - var location = event.block.location; - var drone = new Drone(location); - // do more stuff with the drone here... - }); - -#### Parameters - - * Player : If a player reference is given as the sole parameter then the block the player was looking at will be used as the starting point for the drone. If the player was not looking at a block then the player's location will be used as the starting point. If a `Player` object is provided as a paramter then it should be the only parameter. - * location : *NB* If a `Location` object is provided as a parameter, then it should be the only parameter. - * x : The x coordinate of the Drone (x,y,z,direction and world are not needed if either a player or location parameter is provided) - * y : The y coordinate of the Drone - * z : The z coordinate of the Drone - * direction : The direction in which the Drone is facing. Possible values are 0 (east), 1 (south), 2 (west) or 3 (north) - * world : The world in which the drone is created. - -### Drone.box() method - -the box() method is a convenience method for building things. (For the more performance-oriented method - see cuboid) - -#### parameters - - * b - 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` - * w (optional - default 1) - the width of the structure - * h (optional - default 1) - the height of the structure - * d (optional - default 1) - the depth of the structure - NB this is not how deep underground the structure lies - this is how far away (depth of field) from the drone the structure will extend. - -#### Example - -To create a black structure 4 blocks wide, 9 blocks tall and 1 block long... - - box(blocks.wool.black, 4, 9, 1); - -... or the following code does the same but creates a variable that can be used for further methods... - - var drone = new Drone(self); - drone.box(blocks.wool.black, 4, 9, 1); - -![box example 1](img/boxex1.png) - -### Drone.box0() method - -Another convenience method - this one creates 4 walls with no floor or ceiling. - -#### 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 (optional - default 1) - the width of the structure - * height (optional - default 1) - the height of the structure - * length (optional - default 1) - the length of the structure - how far - away (depth of field) from the drone the structure will extend. - -#### Example - -To create a stone building with the insided hollowed out 7 wide by 3 tall by 6 long... - - box0( blocks.stone, 7, 3, 6); - -![example box0](img/box0ex1.png) - -### Drone.boxa() method - -Construct a cuboid using an array of blocks. As the drone moves first along the width axis, then the height (y axis) then the length, each block is picked from the array and placed. - -#### Parameters - - * blocks - An array of blocks - each block in the array will be placed in turn. - * width - * height - * length - -#### Example - -Construct a rainbow-colored road 100 blocks long... - - var rainbowColors = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, - blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple]; - - boxa(rainbowColors,7,1,30); - -![boxa example](img/boxaex1.png) - -### Chaining - -All of the Drone methods return a Drone object, which means methods can be 'chained' together so instead of writing this... - - drone = new Drone( self ); - drone.fwd( 3 ); - drone.left( 2 ); - drone.box( blocks.grass ); // create a grass block - drone.up(); - drone.box( blocks.grass ); // create another grass block - drone.down(); - -...you could simply write ... - - var drone = new Drone(self).fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down(); - -... since each Drone method is also a global function that constructs a drone if none is supplied, you can shorten even further to just... - - fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down() - -The Drone object uses a [Fluent Interface][fl] to make ScriptCraft scripts more concise and easier to write and read. Minecraft's in-game command prompt is limited to about 80 characters so chaining drone commands together means more can be done before hitting the command prompt limit. For complex building you should save your commands in a new script file and load it using /js load() - -[fl]: http://en.wikipedia.org/wiki/Fluent_interface - -### Drone Properties - - * x - The Drone's position along the west-east axis (x increases as you move east) - * y - The Drone's position along the vertical axis (y increses as you move up) - * z - The Drone's position along the north-south axis (z increases as you move south) - * dir - The Drone's direction 0 is east, 1 is south , 2 is west and 3 is north. - -### Extending Drone - -The Drone object can be easily extended - new buidling recipes/blueprints can be added and can become part of a Drone's chain using the *static* method `Drone.extend`. - -### Drone.extend() static method - -Use this method to add new methods (which also become chainable global functions) to the Drone object. - -#### Parameters - - * name - The name of the new method e.g. 'pyramid'. - * function - The method body. - -Alternatively if you provide just a function as a parameter, then the function name will be used as the new method name. For example the following two approaches are both valid. - -#### Example 1 Using name and function as parameters - - // submitted by [edonaldson][edonaldson] - Drone.extend('pyramid', function( block,height) { - this.chkpt('pyramid'); - for ( var i = height; i > 0; i -= 2) { - this.box(block, i, 1, i).up().right().fwd(); - } - return this.move('pyramid'); - }); - -#### Example 2 Using just a named function as a parameter - - function pyramid( block,height) { - this.chkpt('pyramid'); - for ( var i = height; i > 0; i -= 2) { - this.box(block, i, 1, i).up().right().fwd(); - } - return this.move('pyramid'); - } - Drone.extend( pyramid ); - -Once the method is defined (it can be defined in a new pyramid.js file) it can be used like so... - - var d = new Drone(self); - d.pyramid(blocks.brick.stone, 12); - -... or simply ... - - pyramid(blocks.brick.stone, 12); - -[edonaldson]: https://github.com/edonaldson - -### Drone Constants - -#### Drone.PLAYER_STAIRS_FACING - -An array which can be used when constructing stairs facing in the Drone's direction... - - var d = new Drone(self); - d.box(blocks.stairs.oak + ':' + Drone.PLAYER_STAIRS_FACING[d.dir]); - -... will construct a single oak stair block facing the drone. - -#### Drone.PLAYER_SIGN_FACING - -An array which can be used when placing signs so they face in a given direction. This is used internally by the Drone.sign() method. It should also be used for placing any of the following blocks... - - * chest - * ladder - * furnace - * dispenser - -By default, chests, dispensers, signs, ladders and furnaces are placed facing towards the drone so to place a chest facing the Drone just use: - - drone.box( blocks.chest ); - -To place a chest facing _away_ from the Drone: - - drone.box( blocks.chest + ':' + Drone.PLAYER_SIGN_FACING[(drone.dir + 2) % 4]); - -#### Drone.PLAYER_TORCH_FACING - -Used when placing torches. By default torches will be placed facing up. If you want to place a torch so that it faces towards the drone: - - drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[drone.dir]); - -If you want to place a torch so it faces _away_ from the drone: - - drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[(drone.dir + 2) % 4]); - -***/ - -// -// Implementation -// ============== -// -// There is no need to read any further unless you want to understand how the Drone object works. -// -function getDirFromRotation( location ) { - // 0 = east, 1 = south, 2 = west, 3 = north - // 46 to 135 = west - // 136 to 225 = north - // 226 to 315 = east - // 316 to 45 = south - var r; - if (__plugin.canary ) { - r = location.rotation; - } - if (__plugin.bukkit) { - r = location.yaw; - } - - // west = -270 - // north = -180 - // east = -90 - // south = 0 - - r = (r + 360 ) % 360; // east could be 270 or -90 - - if ( r > 45 && r <= 135 ) - return 2; // west - if ( r > 135 && r <= 225 ) - return 3; // north - if ( r > 225 && r <= 315 ) - return 0; // east - return 1; // south -} -function putBlock( x, y, z, blockId, metadata, world, dir, update ) { - if ( typeof metadata == 'undefined' ) { - metadata = 0; - } - var block = world.getBlockAt( x, y, z ); - - if (__plugin.canary) { - var BlockType = Packages.net.canarymod.api.world.blocks.BlockType; - block.type = BlockType.fromId(blockId); - var applyProperties = require('blockhelper').applyProperties; - applyProperties(block, metadata); - if (typeof update === 'undefined'){ - update = true; - } - if (update){ - block.update(); - } - } - if (__plugin.bukkit) { - block.setTypeIdAndData( blockId, metadata, false ); - block.data = metadata; - } - return block; -} - -function Drone( x, y, z, dir, world ) { - this.record = false; - var usePlayerCoords = false; - var player = (typeof self !== 'undefined' ? self : null); - var playerPos; - if ( x.location && x.name) { - player = x; - } - playerPos = x.location; - - var that = this; - var populateFromLocation = function( loc ) { - that.x = loc.x; - that.y = loc.y; - that.z = loc.z; - that.dir = getDirFromRotation(loc); - that.world = loc.world; - }; - var mp = utils.getMousePos( player ); - if ( typeof x == 'undefined' || x.location ) { - if ( mp ) { - populateFromLocation( mp ); - if ( playerPos ) { - this.dir = getDirFromRotation(playerPos); - } - } else { - // base it on the player's current location - usePlayerCoords = true; - // - // it's possible that drone.js could be loaded by a non-playing op - // (from the server console) - // - if ( !playerPos ) { - return null; - } - populateFromLocation( playerPos ); - } - } else { - if ( arguments[0].x && arguments[0].y && arguments[0].z ) { - populateFromLocation( arguments[ 0 ] ); - } else { - this.x = x; - this.y = y; - this.z = z; - if ( typeof dir == 'undefined' ) { - this.dir = getDirFromRotation( playerPos); - } else { - this.dir = dir%4; - } - if ( typeof world == 'undefined' ) { - this.world = playerPos.world; - } else { - this.world = world; - } - } - } - - if ( usePlayerCoords ) { - this.fwd( 3 ); - } - this.chkpt( 'start' ); - this.record = true; - this.history = []; - this.player = player; - return this; -} - -exports.Drone = Drone; -/* - because this is a plugin, any of its exports will be exported globally. - Since 'blocks' is a module not a plugin it is convenient to export it via - the Drone module. - */ +var blocks = require('blocks'); +exports.Drone = require('drone'); exports.blocks = blocks; -Drone.getDirFromRotation = getDirFromRotation; -Drone.queue = []; - -Drone.opsPerSec = 10; -Drone.processQueue = function processQueue(){ - var process, - i = 0, - queues = getAllQueues(); - - for ( ; i < queues.length; i++ ) { - process = queues[i].shift(); - if (process){ - try { - process(); - } catch( e ) { - console.log('Drone build error: ' + e + ' while processing ' + process); - } - } - } - setTimeout( Drone.processQueue, 1000 / Drone.opsPerSec ); -}; -setTimeout( Drone.processQueue, 1000 / Drone.opsPerSec ); - -addUnloadHandler( function() { - var pendingBuildOps = 0; - var allQueues = getAllQueues(); - for (var i = 0; i < allQueues.length; i++){ - pendingBuildOps += allQueues[i].length; - } - if (pendingBuildOps > 0){ - console.warn('There were ' + pendingBuildOps + ' pending build operations which were cancelled'); - } -}); -// -// add custom methods to the Drone object using this function -// -Drone.extend = function( name, func ) { - if (arguments.length == 1){ - func = name; - if ( !func.name ){ - throw 'A Drone extension function must have a name!'; - } - name = func.name; - } - Drone.prototype[ '_' + name ] = func; - Drone.prototype[ name ] = function( ) { - if ( this.record ) { - this.history.push( [ name, arguments ] ); - } - var oldVal = this.record; - this.record = false; - this[ '_' + name ].apply( this, arguments ); - this.record = oldVal; - return this; - }; - - global[name] = function( ) { - var result = new Drone( self ); - result[name].apply( result, arguments ); - return result; - }; -}; - -/************************************************************************** -### Drone.times() Method - -The times() method makes building multiple copies of buildings -easy. It's possible to create rows or grids of buildings without -resorting to `for` or `while` loops. - -#### Parameters - - * numTimes (optional - default 2) : The number of times you want to repeat the preceding statements. - -#### Example - -Say you want to do the same thing over and over. You have a couple of options... - - * You can use a for loop... - - d = new Drone(); for ( var i =0;i < 4; i++) { d.cottage().right(8); } - -While this will fit on the in-game prompt, it's awkward. You need to -declare a new Drone object first, then write a for loop to create the -4 cottages. It's also error prone, even the `for` loop is too much -syntax for what should really be simple. - - * You can use a while loop... - - d = new Drone(); var i=4; while (i--) { d.cottage().right(8); } - -... which is slightly shorter but still too much syntax. Each of the -above statements is fine for creating a 1-dimensional array of -structures. But what if you want to create a 2-dimensional or -3-dimensional array of structures? Enter the `times()` method. - -The `times()` method lets you repeat commands in a chain any number of -times. So to create 4 cottages in a row you would use the following -statement... - - cottage().right(8).times(4); - -...which will build a cottage, then move right 8 blocks, then do it -again 4 times over so that at the end you will have 4 cottages in a -row. What's more the `times()` method can be called more than once in -a chain. So if you wanted to create a *grid* of 20 houses ( 4 x 5 ), -you would do so using the following statement... - - cottage().right(8).times(4).fwd(8).left(32).times(5); - -... breaking it down... - - 1. The first 3 calls in the chain ( `cottage()`, `right(8)`, `times(4)` ) build a single row of 4 cottages. - - 2. The last 3 calls in the chain ( `fwd(8)`, `left(32)`, `times(5)` ) move the drone forward 8 then left 32 blocks (4 x 8) to return to the original x coordinate, then everything in the chain is repeated again 5 times so that in the end, we have a grid of 20 cottages, 4 x 5. Normally this would require a nested loop but the `times()` method does away with the need for loops when repeating builds. - -Another example: This statement creates a row of trees 2 by 3 ... - - oak().right(10).times(2).left(20).fwd(10).times(3) - -... You can see the results below. - -![times example 1](img/times-trees.png) - -***/ -Drone.prototype.times = function( numTimes, commands ) { - if ( typeof numTimes == 'undefined' ) { - numTimes = 2; - } - if ( typeof commands == 'undefined' ) { - commands = this.history.concat(); - } - - this.history = [ [ 'times', [ numTimes + 1, commands ] ] ]; - var oldVal = this.record; - this.record = false; - for ( var j = 1; j < numTimes; j++ ) { - for ( var i = 0; i < commands.length; i++) { - var command = commands[i]; - var methodName = command[0]; - var args = command[1]; - this[ methodName ].apply( this, args ); - } - } - this.record = oldVal; - return this; -}; - - -Drone.prototype.getBlock = function(){ - return this.world.getBlockAt(this.x,this.y,this.z); -}; -Drone.prototype.setBlock = function(blockType, data, ow, oh, od, update){ - if (typeof ow == 'undefined') - ow = 0; - if (typeof oh == 'undefined') - oh = 0; - if (typeof od == 'undefined') - od = 0; - this - .right(ow) - .up(oh) - .fwd(od); - var result = putBlock(this.x, this.y, this.z, blockType, data, this.world, this.dir, update); - this - .left(ow) - .down(oh) - .back(od); - return result; -}; -Drone.prototype.traverseWidth = function(width, callback){ - _traverse[this.dir].width(this, width, callback); -}; -Drone.prototype.traverseHeight = function(height, callback){ - traverseHeight(this, height, callback); -}; -Drone.prototype.traverseDepth = function(depth, callback){ - _traverse[this.dir].depth(this, depth, callback); -}; -// -// building -// - -var playerQueues = {}; -/* - if the drone has an associated player, then use that player's queue otherwise - use the global queue. -*/ -function getQueue( drone ){ - if ( drone.player ) { - var playerName = ''+drone.player.name; - var result = playerQueues[playerName]; - if (result === undefined){ - playerQueues[playerName] = []; - return playerQueues[playerName]; - } - return result; - } else { - return Drone.queue; - } -} -function getAllQueues() { - var result = [ Drone.queue ]; - for (var pq in playerQueues) { - result.push(playerQueues[pq]) ; - } - return result; -} -Drone.prototype.cuboida = function(/* Array */ blocks, w, h, d, overwrite, immediate ) { - // - // wph 20140823 make a copy because don't want to modify array in background - // - var blocksForBuild = blocks.slice(); - var len = blocksForBuild.length, - i = 0; - - if ( !immediate ) { - for ( ; i < len; i++ ) { - blocksForBuild[i] = this._getBlockIdAndMeta( blocksForBuild[ i ] ); - } - var clone = Drone.clone(this); - var impl = this.cuboida.bind(clone, blocksForBuild, w, h, d, overwrite, true); - getQueue(this).push( function cuboida(){ impl(); }); - return this; - } - if ( typeof overwrite == 'undefined' ) { - overwrite = true; - } - if ( typeof h == 'undefined' ) { - h = 1; - } - if ( typeof d == 'undefined' ) { - d = 1; - } - if ( typeof w == 'undefined' ) { - w = 1; - } - var bi = 0; - - traverseDHW( this, d,h,w, function traverseWidthCallback( ) { - var properBlock = blocksForBuild[ bi % len ]; - this.setBlock(properBlock[0], properBlock[1]); - bi++; - }); - return this; -}; -Drone.MAX_VOLUME = 1 * MILLION; -Drone.MAX_SIDE = 1 * THOUSAND; - -var tooBig = function(w, h, d ) { - return ( w * h * d ) >= Drone.MAX_VOLUME || - ( w >= Drone.MAX_SIDE ) || - ( h >= Drone.MAX_SIDE ) || - ( d >= Drone.MAX_SIDE ); -}; -/* - faster cuboid because blockid, meta and world must be provided - use this method when you need to repeatedly place blocks - */ -Drone.prototype.cuboidX = function( blockType, meta, w, h, d, immediate ) { - - if ( typeof h == 'undefined' ) { - h = 1; - } - if ( typeof d == 'undefined' ) { - d = 1; - } - if ( typeof w == 'undefined' ) { - w = 1; - } - if ( tooBig( w, h, d ) ) { - this.sign([ - 'Build too Big!', - 'width:' + w, - 'height:' + h, - 'depth:' + d - ], 68); - console.warn('Build too big! ' + w + ' X ' + h + ' X ' + d); - return this; - } - if ( !immediate ) { - var clone = Drone.clone(this); - var impl = this.cuboidX.bind(clone, blockType, meta, w, h, d, true); - getQueue(this).push(function cuboidX(){ impl(); }); - return this; - } - traverseDHW( this, d,h,w, function( ) { - this.setBlock( blockType, meta ); - }); - return this; - -}; -/* - deferred execution of a drone method -*/ -Drone.prototype.then = function( next ){ - getQueue(this).push( next.bind( Drone.clone(this) ) ); -}; -Drone.prototype.cuboid = function( block, w, h, d, immediate ) { - var bm = this._getBlockIdAndMeta( block ); - return this.cuboidX( bm[0], bm[1], w, h, d, immediate); -}; - -Drone.prototype.cuboid0 = function( block, w, h, d, immediate ) { - var start = 'cuboid0' + w + h + d + immediate; - this - .chkpt( start ) - .cuboid( block, w, h, 1, immediate ) // Front wall - .cuboid( block, 1, h, d, immediate ) // Left wall - .right( w - 1 ) - .cuboid( block, 1, h, d, immediate ) // Right wall - .left( w - 1 ) - .fwd( d - 1 ) - .cuboid( block, w, h, 1, immediate ) // Back wall - .move( start ); -}; - - - -// player dirs: 0 = east, 1 = south, 2 = west, 3 = north -// 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) -Drone.PLAYER_SIGN_FACING = [ 4, 2, 5, 3 ]; -Drone.PLAYER_TORCH_FACING = [ 2, 4, 1, 3 ]; - -Drone.extend('box', Drone.prototype.cuboid ); -Drone.extend('box0',Drone.prototype.cuboid0 ); -Drone.extend('boxa',Drone.prototype.cuboida ); -// -// show the Drone's position and direction -// -Drone.prototype.toString = function( ) { - var dirs = ['east','south','west','north']; - return 'x: ' + this.x + ' y: '+this.y + ' z: ' + this.z + ' dir: ' + this.dir + ' '+dirs[this.dir]; -}; -Drone.prototype.debug = function( ) { - console.log(this.toString( ) ); - return this; -}; - -function _getBlockIdAndMeta( b ) { - var defaultMeta = 0, - i = 0, - bs, - md, - sp; - if (typeof b === 'number' || /^[0-9]+$/.test(b)) { - // wph 20130414 - use sensible defaults for certain blocks e.g. stairs - // should face the drone. - switch (b) { - case blocks.stairs.oak: - case blocks.stairs.cobblestone: - case blocks.stairs.brick: - case blocks.stairs.stone: - case blocks.stairs.nether: - case blocks.stairs.sandstone: - case blocks.stairs.spruce: - case blocks.stairs.jungle: - case blocks.stairs.quartz: - defaultMeta = Drone.PLAYER_STAIRS_FACING[ this.dir % 4 ]; - break; - case blocks.sign: - case blocks.ladder: - // bug: furnace, chest, dispenser don't always use the right metadata - case blocks.furnace: - case blocks.furnace_burning: - case blocks.chest: - case blocks.enderchest: - case blocks.dispenser: - defaultMeta = Drone.PLAYER_SIGN_FACING[ this.dir % 4 ]; - break; - case blocks.sign_post: - defaultMeta = ( 12 + ( ( this.dir + 2 ) * 4 ) ) % 16; - break; - } - return [ b, defaultMeta ]; - } - if ( typeof b === 'string' ) { - bs = b; - sp = bs.indexOf(':' ); - if ( sp == -1 ) { - b = parseInt( bs ); - return [ b, defaultMeta ]; - } - b = parseInt(bs.substring(0,sp ) ); - md = parseInt(bs.substring(sp+1,bs.length ) ); - return [b,md]; - } - if (b.id){ - // wph 20141230 we are dealing with an object - var blockInfo = b; - var metadata = {}; - for (i in b){ - if (i !== 'id') - metadata[i] = b[i]; - } - return [b.id, metadata]; - } -} -var _traverse = [{},{},{},{}]; -// east -function walkWidthEast( drone, n,callback ) { - var s = drone.z, e = s + n; - for ( ; drone.z < e; drone.z++ ) { - callback.call(drone ,drone.z-s ); - } - drone.z = s; -} -function walkDepthEast( drone,n,callback ) { - var s = drone.x, e = s+n; - for ( ;drone.x < e;drone.x++ ) { - callback.call(drone, drone.x-s ); - } - drone.x = s; -} -function walkWidthSouth( drone,n,callback ) { - var s = drone.x, e = s-n; - for ( ;drone.x > e;drone.x-- ) { - callback.call(drone, s-drone.x ); - } - drone.x = s; -} -function walkWidthWest( drone,n,callback ) { - var s = drone.z, e = s-n; - for ( ;drone.z > e;drone.z-- ) { - callback.call(drone, s-drone.z ); - } - drone.z = s; -} -_traverse[0].width = walkWidthEast; -_traverse[0].depth = walkDepthEast; -// south -_traverse[1].width = walkWidthSouth; -_traverse[1].depth = walkWidthEast; -// west -_traverse[2].width = walkWidthWest; -_traverse[2].depth = walkWidthSouth; -// north -_traverse[3].width = walkDepthEast; -_traverse[3].depth = walkWidthWest; -function traverseHeight( drone,n,callback ) { - var s = drone.y, e = s + n; - for ( ; drone.y < e; drone.y++ ) { - callback.call(drone, drone.y-s ); - } - drone.y = s; -}; -function traverseDHW( drone, d,h,w, callback ){ - _traverse[drone.dir].depth( drone, d, function traverseDepthCallback( ) { - traverseHeight( this, h, function traverseHeightCallback( ) { - _traverse[this.dir].width( this, w, callback); - }); - }); -} - -Drone.clone = function(origin) { - var result = new Drone(origin.x,origin.y,origin.z, origin.dir, origin.world); - return result; -}; -// -// wph 20130130 - make this a method - extensions can use it. -// -Drone.prototype._getBlockIdAndMeta = _getBlockIdAndMeta; -Drone.bountiful = __plugin.canary ? parseFloat(server.canaryModVersion) > 1.7 : false;