renamed from select.js
This commit is contained in:
parent
e46451b13b
commit
7462dd119e
1 changed files with 219 additions and 0 deletions
219
js-plugins/signs/menu.js
Normal file
219
js-plugins/signs/menu.js
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
Define the signs module - signs are persistent
|
||||
(that is - a menu sign will still be a menu after th
|
||||
server has shut down and started up) plugins now have persistent state - Yay!
|
||||
*/
|
||||
var signs = signs || plugin("signs", {
|
||||
/*
|
||||
construct an interactive menu which can then be attached to a Sign.
|
||||
*/
|
||||
menu: function(
|
||||
/* String */ label,
|
||||
/* Array */ options,
|
||||
/* Function */ onInteract,
|
||||
/* Number */ defaultSelection ){}
|
||||
/*
|
||||
more to come - clocks
|
||||
*/
|
||||
},true);
|
||||
/*
|
||||
private implementation
|
||||
*/
|
||||
(function(){
|
||||
/*
|
||||
redraw a menu sign
|
||||
*/
|
||||
var _redrawMenuSign = function(p_sign,p_selectedIndex,p_displayOptions)
|
||||
{
|
||||
var optLen = p_displayOptions.length;
|
||||
// the offset is where the menu window begins
|
||||
var offset = Math.max(0, Math.min(optLen-3, Math.floor(p_selectedIndex/3) * 3));
|
||||
for (var i = 0;i < 3; i++){
|
||||
var text = "";
|
||||
if (offset+i < optLen)
|
||||
text = p_displayOptions[offset+i];
|
||||
if (offset+i == p_selectedIndex)
|
||||
text = ("" + text).replace(/^ /,">");
|
||||
p_sign.setLine(i+1,text);
|
||||
}
|
||||
p_sign.update(true);
|
||||
};
|
||||
signs._updaters = {};
|
||||
|
||||
/*
|
||||
construct an interactive menu to be subsequently attached to
|
||||
one or more Signs.
|
||||
*/
|
||||
signs.menu = function(
|
||||
/* String */ label,
|
||||
/* Array */ options,
|
||||
/* Function */ callback,
|
||||
/* Number */ selectedIndex)
|
||||
{
|
||||
|
||||
if (typeof selectedIndex == "undefined")
|
||||
selectedIndex = 0;
|
||||
|
||||
//
|
||||
// variables common to all instances of this menu can go here
|
||||
//
|
||||
var labelPadding = "---------------";
|
||||
var optionPadding = " ";
|
||||
|
||||
var paddedLabel = (labelPadding+label+labelPadding).substr(((label.length+30)/2)-7,15);
|
||||
var optLen = options.length;
|
||||
var displayOptions = [];
|
||||
for (var i =0;i < options.length;i++){
|
||||
displayOptions[i] = (" " + options[i] + optionPadding).substring(0,15);
|
||||
}
|
||||
|
||||
var theSigns = this;
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
if (typeof sign == "undefined"){
|
||||
var mouseLoc = getMousePos();
|
||||
if (mouseLoc){
|
||||
sign = mouseLoc.block.state;
|
||||
}else{
|
||||
throw new Exception("You must provide a sign!");
|
||||
}
|
||||
}
|
||||
//
|
||||
// per-sign variables go here
|
||||
//
|
||||
var cSelectedIndex = selectedIndex;
|
||||
sign.setLine(0,paddedLabel);
|
||||
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);
|
||||
};
|
||||
|
||||
/*
|
||||
get a unique ID for this particular sign instance
|
||||
*/
|
||||
var signLoc = sign.block.location;
|
||||
var menuSignSaveData = [""+signLoc.world.name, signLoc.x,signLoc.y,signLoc.z];
|
||||
var menuSignUID = JSON.stringify(menuSignSaveData);
|
||||
/*
|
||||
keep a reference to the update function for use by the event handler
|
||||
*/
|
||||
theSigns._updaters[menuSignUID] = _updateSign;
|
||||
|
||||
// initialize the sign
|
||||
_redrawMenuSign(sign,cSelectedIndex,displayOptions);
|
||||
|
||||
/*
|
||||
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){
|
||||
if (typeof theSigns.store.menus == "undefined")
|
||||
theSigns.store.menus = {};
|
||||
var signLocations = theSigns.store.menus[label];
|
||||
if (typeof signLocations == "undefined")
|
||||
signLocations = theSigns.store.menus[label] = [];
|
||||
signLocations.push(menuSignSaveData);
|
||||
}
|
||||
return sign;
|
||||
};
|
||||
|
||||
/*
|
||||
a new sign definition - need to store (in-memory only)
|
||||
it's 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.
|
||||
*/
|
||||
|
||||
if (this.store.menus && this.store.menus[label])
|
||||
{
|
||||
var signsOfSameLabel = this.store.menus[label];
|
||||
var defragged = [];
|
||||
var len = signsOfSameLabel.length;
|
||||
for (var i = 0; i < len ; i++)
|
||||
{
|
||||
var loc = signsOfSameLabel[i];
|
||||
var world = org.bukkit.Bukkit.getWorld(loc[0]);
|
||||
if (!world)
|
||||
continue;
|
||||
var block = world.getBlockAt(loc[1],loc[2],loc[3]);
|
||||
if (block.state instanceof org.bukkit.block.Sign){
|
||||
convertToMenuSign(block.state,false);
|
||||
defragged.push(loc);
|
||||
}
|
||||
}
|
||||
/*
|
||||
remove data for signs which no longer exist.
|
||||
*/
|
||||
if (defragged.length != len){
|
||||
this.store.menus[label] = defragged;
|
||||
}
|
||||
}
|
||||
return convertToMenuSign;
|
||||
};
|
||||
|
||||
/*
|
||||
All dependecies ( 'events' module ) have loaded
|
||||
*/
|
||||
ready(function(){
|
||||
//
|
||||
// Usage:
|
||||
// In game, create a sign , target it and type /js signs.testMenu()
|
||||
//
|
||||
signs.testMenu = signs.menu(
|
||||
"Dinner",
|
||||
["Lamb","Pork","Chicken","Duck","Beef"],
|
||||
function(event){
|
||||
event.player.sendMessage("You chose " + event.text);
|
||||
});
|
||||
//
|
||||
// This is an example sign that displays a menu of times of day
|
||||
// interacting with the sign will change the time of day accordingly.
|
||||
//
|
||||
// In game, create a sign , target it and type /js signs.timeOfDay()
|
||||
//
|
||||
signs.timeOfDay = signs.menu(
|
||||
"Time",
|
||||
["Dawn","Midday","Dusk","Midnight"],
|
||||
function(event){
|
||||
event.player.location.world.setTime( event.number * 6000 );
|
||||
});
|
||||
|
||||
//
|
||||
// update it every time player interacts with it.
|
||||
//
|
||||
events.on("player.PlayerInteractEvent",function(listener, event) {
|
||||
/*
|
||||
look up our list of menu signs. If there's a matching location and there's
|
||||
a sign, then update it.
|
||||
*/
|
||||
if (! event.clickedBlock.state instanceof org.bukkit.block.Sign)
|
||||
return;
|
||||
var evtLocStr = locationToString(event.clickedBlock.location);
|
||||
var signUpdater = signs._updaters[evtLocStr]
|
||||
if (signUpdater)
|
||||
signUpdater(event.player, event.clickedBlock.state);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}());
|
||||
|
||||
|
Reference in a new issue