2015-01-11 01:09:56 +01:00
|
|
|
'use strict';
|
|
|
|
/*global events, require, org, module, persist, __plugin*/
|
2014-02-19 23:17:19 +01:00
|
|
|
var utils = require('utils'),
|
|
|
|
stringExt = require('utils/string-exts'),
|
2015-06-01 08:34:54 +02:00
|
|
|
store = persist('signs',{});
|
2014-02-19 23:17:19 +01:00
|
|
|
|
2013-01-18 00:28:39 +01:00
|
|
|
/*
|
|
|
|
Define the signs module - signs are persistent
|
2013-12-24 01:17:33 +01:00
|
|
|
(that is - a menu sign will still be a menu after the
|
2013-01-18 00:28:39 +01:00
|
|
|
server has shut down and started up) plugins now have persistent state - Yay!
|
|
|
|
*/
|
2015-01-11 01:09:56 +01:00
|
|
|
var signs = { };
|
|
|
|
var hasSign = null;
|
|
|
|
module.exports = function(hs){
|
|
|
|
hasSign = hs;
|
|
|
|
return signs;
|
|
|
|
};
|
2013-12-24 01:17:33 +01:00
|
|
|
|
2015-01-11 01:09:56 +01:00
|
|
|
var setLine = null;
|
|
|
|
if (__plugin.canary){
|
|
|
|
setLine = function(sign, i, text){
|
|
|
|
sign.setTextOnLine( text, i);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (__plugin.bukkit){
|
|
|
|
setLine = function(sign, i, text){
|
|
|
|
sign.setLine( i, text);
|
|
|
|
};
|
|
|
|
}
|
2013-12-24 01:17:33 +01:00
|
|
|
|
2013-01-18 00:28:39 +01:00
|
|
|
/*
|
2013-12-24 01:17:33 +01:00
|
|
|
redraw a menu sign
|
2013-01-18 00:28:39 +01:00
|
|
|
*/
|
2014-01-29 20:49:15 +01:00
|
|
|
var _redrawMenuSign = function( p_sign, p_selectedIndex, p_displayOptions ) {
|
|
|
|
var optLen = p_displayOptions.length,
|
|
|
|
i,
|
|
|
|
text;
|
|
|
|
// the offset is where the menu window begins
|
|
|
|
var offset = Math.max( 0, Math.min( optLen-3, Math.floor( p_selectedIndex/3 ) * 3) );
|
|
|
|
for ( i = 0;i < 3; i++ ) {
|
|
|
|
text = "";
|
|
|
|
if ( offset+i < optLen ) {
|
|
|
|
text = p_displayOptions[offset+i];
|
2013-12-24 01:17:33 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( offset+i == p_selectedIndex ) {
|
|
|
|
text = ('' + text).replace(/^ /,">");
|
|
|
|
}
|
2015-01-11 01:09:56 +01:00
|
|
|
setLine(p_sign, i+1, text);
|
|
|
|
}
|
|
|
|
if (__plugin.canary){
|
|
|
|
p_sign.update();
|
|
|
|
}
|
|
|
|
if (__plugin.bukkit){
|
|
|
|
p_sign.update( true );
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
2013-12-24 01:17:33 +01:00
|
|
|
};
|
2013-12-26 16:38:24 +01:00
|
|
|
|
2013-12-24 01:17:33 +01:00
|
|
|
var _updaters = {};
|
|
|
|
/*
|
|
|
|
construct an interactive menu to be subsequently attached to
|
|
|
|
one or more Signs.
|
|
|
|
*/
|
2015-01-11 01:09:56 +01:00
|
|
|
signs.menu = signMenu;
|
|
|
|
|
|
|
|
function signMenu( label, options, callback, selectedIndex ) {
|
2014-01-29 20:49:15 +01:00
|
|
|
|
|
|
|
if ( typeof selectedIndex == "undefined" ) {
|
|
|
|
selectedIndex = 0;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// variables common to all instances of this menu can go here
|
|
|
|
//
|
|
|
|
var labelPadding = "---------------";
|
|
|
|
var optionPadding = " ";
|
|
|
|
var i;
|
|
|
|
var paddedLabel = ( labelPadding + label + labelPadding)
|
|
|
|
.substr( ( ( label.length+30 ) / 2 ) - 7, 15 );
|
|
|
|
var optLen = options.length;
|
|
|
|
var displayOptions = [];
|
|
|
|
for ( i = 0; i < options.length; i++ ) {
|
|
|
|
displayOptions[i] = (" " + options[i] + optionPadding).substring(0,15);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
this function is returned by signs.menu and when it is invoked it will
|
|
|
|
attach menu behaviour to an existing sign in the world.
|
|
|
|
signs.menu is for use by Plugin Authors.
|
|
|
|
The function returned by signs.menu is for use by admins/ops.
|
|
|
|
*/
|
|
|
|
var convertToMenuSign = function(/* Sign */ sign, save) {
|
|
|
|
if (typeof save == "undefined") {
|
|
|
|
save = true;
|
2013-12-24 01:17:33 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
//
|
|
|
|
// per-sign variables go here
|
|
|
|
//
|
|
|
|
var cSelectedIndex = selectedIndex;
|
2015-01-11 01:09:56 +01:00
|
|
|
setLine(sign, 0, paddedLabel.bold());
|
2014-01-29 20:49:15 +01:00
|
|
|
var _updateSign = function( p_player, p_sign ) {
|
|
|
|
cSelectedIndex = ( cSelectedIndex + 1 ) % optLen;
|
|
|
|
_redrawMenuSign( p_sign, cSelectedIndex, displayOptions );
|
|
|
|
var signSelectionEvent = {
|
|
|
|
player: p_player,
|
|
|
|
sign: p_sign,
|
|
|
|
text: options[ cSelectedIndex ],
|
|
|
|
number: cSelectedIndex
|
|
|
|
};
|
|
|
|
callback( signSelectionEvent );
|
|
|
|
};
|
2013-01-18 00:28:39 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
/*
|
|
|
|
get a unique ID for this particular sign instance
|
|
|
|
*/
|
|
|
|
var signLoc = sign.block.location;
|
|
|
|
var menuSignSaveData = utils.locationToJSON( signLoc );
|
|
|
|
var menuSignUID = JSON.stringify( menuSignSaveData );
|
|
|
|
/*
|
|
|
|
keep a reference to the update function for use by the event handler
|
|
|
|
*/
|
|
|
|
_updaters[ menuSignUID ] = _updateSign;
|
2013-01-18 00:28:39 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
// initialize the sign
|
|
|
|
_redrawMenuSign( sign, cSelectedIndex, displayOptions );
|
2013-01-18 00:28:39 +01:00
|
|
|
|
2013-12-24 01:17:33 +01:00
|
|
|
/*
|
2014-01-29 20:49:15 +01:00
|
|
|
whenever a sign is placed somewhere in the world
|
|
|
|
(which is what this function does)
|
|
|
|
save its location for loading and initialization
|
|
|
|
when the server starts up again.
|
|
|
|
*/
|
|
|
|
if ( save ) {
|
2015-01-11 01:09:56 +01:00
|
|
|
if ( typeof store.menus == "undefined") {
|
|
|
|
store.menus = {};
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
2015-01-11 01:09:56 +01:00
|
|
|
var signLocations = store.menus[label];
|
2014-01-29 20:49:15 +01:00
|
|
|
if ( typeof signLocations == "undefined" ) {
|
2015-01-11 01:09:56 +01:00
|
|
|
signLocations = store.menus[label] = [];
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
signLocations.push( menuSignSaveData );
|
|
|
|
}
|
|
|
|
return sign;
|
2015-01-11 01:09:56 +01:00
|
|
|
}; // end of convertToMenuSign function
|
2013-12-24 01:17:33 +01:00
|
|
|
|
2014-01-29 20:49:15 +01:00
|
|
|
/*
|
|
|
|
a new sign definition - need to store (in-memory only)
|
|
|
|
its behaviour and bring back to life other signs of the
|
|
|
|
same type in the world. Look for other static signs in the
|
|
|
|
world with this same label and make dynamic again.
|
|
|
|
*/
|
|
|
|
|
2015-01-11 01:09:56 +01:00
|
|
|
if ( store.menus && store.menus[label] ) {
|
|
|
|
var signsOfSameLabel = store.menus[ label ];
|
2014-01-29 20:49:15 +01:00
|
|
|
var defragged = [];
|
|
|
|
var len = signsOfSameLabel.length;
|
|
|
|
for ( i = 0; i < len; i++ ) {
|
2015-01-11 01:09:56 +01:00
|
|
|
var loc = utils.locationFromJSON(signsOfSameLabel[i]);
|
|
|
|
var block = utils.blockAt(loc);
|
|
|
|
var sign = hasSign(block);
|
|
|
|
if ( sign) {
|
|
|
|
convertToMenuSign( sign, false );
|
2014-01-29 20:49:15 +01:00
|
|
|
defragged.push( loc );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
remove data for signs which no longer exist.
|
|
|
|
*/
|
|
|
|
if ( defragged.length != len ) {
|
2015-01-11 01:09:56 +01:00
|
|
|
store.menus[label] = defragged;
|
2013-12-24 01:17:33 +01:00
|
|
|
}
|
2014-01-29 20:49:15 +01:00
|
|
|
}
|
|
|
|
return convertToMenuSign;
|
2013-12-24 01:17:33 +01:00
|
|
|
};
|
2013-01-18 00:28:39 +01:00
|
|
|
|
2015-01-11 01:09:56 +01:00
|
|
|
/*
|
2014-09-30 00:42:41 +02:00
|
|
|
if (__plugin.canary){
|
|
|
|
console.warn('signs/menu is not yet supported in CanaryMod');
|
|
|
|
return;
|
|
|
|
}
|
2015-01-11 01:09:56 +01:00
|
|
|
*/
|
|
|
|
if (__plugin.canary){
|
|
|
|
events.blockRightClick( function( event ){
|
|
|
|
var sign = hasSign(event.blockClicked);
|
|
|
|
if (! sign){
|
|
|
|
// it's not a sign
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var evtLocStr = utils.locationToString(event.blockClicked.location);
|
|
|
|
var signUpdater = _updaters[evtLocStr];
|
|
|
|
if ( signUpdater ) {
|
|
|
|
signUpdater( event.player, sign);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (__plugin.bukkit){
|
|
|
|
//
|
|
|
|
// update it every time player interacts with it.
|
|
|
|
//
|
|
|
|
events.playerInteract( function( event ) {
|
|
|
|
/*
|
|
|
|
look up our list of menu signs. If there's a matching location and there's
|
|
|
|
a sign, then update it.
|
|
|
|
*/
|
|
|
|
var sign = hasSign(event.clickedBlock);
|
|
|
|
if ( ! sign ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var evtLocStr = utils.locationToString(event.clickedBlock.location);
|
|
|
|
var signUpdater = _updaters[evtLocStr];
|
|
|
|
if ( signUpdater ) {
|
|
|
|
signUpdater( event.player, sign );
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2013-01-18 00:28:39 +01:00
|
|
|
|
|
|
|
|