Fix issue #111, reorg of lib/ and (undoc'd) persistence
parent
c77e78c2e5
commit
aefc98f172
After Width: | Height: | Size: 98 KiB |
@ -0,0 +1,33 @@
|
||||
|
||||
module.exports = function($){
|
||||
|
||||
// wph 20140105 trim not availabe in String on Mac OS.
|
||||
if (typeof String.prototype.trim == 'undefined'){
|
||||
String.prototype.trim = function(){
|
||||
return this.replace(/^\s+|\s+$/g,'');
|
||||
};
|
||||
}
|
||||
|
||||
$.setTimeout = function( callback, delayInMillis){
|
||||
/*
|
||||
javascript programmers familiar with setTimeout know that it expects
|
||||
a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks
|
||||
(where 1 tick = 1/20th second)
|
||||
*/
|
||||
var bukkitTask = server.scheduler.runTaskLater(__plugin, callback, delayInMillis/50);
|
||||
return bukkitTask;
|
||||
};
|
||||
$.clearTimeout = function(bukkitTask){
|
||||
bukkitTask.cancel();
|
||||
};
|
||||
|
||||
$.setInterval = function(callback, intervalInMillis){
|
||||
var delay = intervalInMillis/ 50;
|
||||
var bukkitTask = server.scheduler.runTaskTimer(__plugin, callback, delay, delay);
|
||||
return bukkitTask;
|
||||
};
|
||||
$.clearInterval = function(bukkitTask){
|
||||
bukkitTask.cancel();
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,37 @@
|
||||
|
||||
var _dataDir = null;
|
||||
var _persistentData = {};
|
||||
|
||||
module.exports = function( rootDir, $ ){
|
||||
|
||||
_dataDir = new java.io.File( rootDir, 'data');
|
||||
|
||||
$.persist = function(name, data, write){
|
||||
var i, dataFromFile;
|
||||
if (typeof data == 'undefined')
|
||||
data = {};
|
||||
if (typeof write == 'undefined')
|
||||
write = false;
|
||||
if (!write){
|
||||
dataFromFile = $.load(_dataDir.canonicalPath + '/' + name + '-store.json');
|
||||
if (dataFromFile){
|
||||
for (i in dataFromFile){
|
||||
data[i] = dataFromFile[i];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// flush data to file
|
||||
$.save(data, _dataDir.canonicalPath + '/' + name + '-store.json');
|
||||
}
|
||||
_persistentData[name] = data;
|
||||
return data;
|
||||
};
|
||||
|
||||
$.addUnloadHandler(function(){
|
||||
for (var name in _persistentData){
|
||||
var data = _persistentData[name];
|
||||
$.save(data, _dataDir.canonicalPath + '/' + name + '-store.json');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -0,0 +1,225 @@
|
||||
/*************************************************************************
|
||||
## Cow Clicker Mini-Game
|
||||
|
||||
### How to Play
|
||||
|
||||
At the in-game prompt type `jsp cowclicker` to start or stop
|
||||
playing. Right-Click on Cows to score points. No points for killing
|
||||
cows (hint: use the same keyboard keys you'd use for opening doors).
|
||||
|
||||
Every time you click a cow your score increases by 1 point. Your score
|
||||
is displayed in a side-bar along the right edge of of the screen.
|
||||
|
||||

|
||||
|
||||
### Rules
|
||||
|
||||
* You can join and leave the Cow Clicker game at any time by typing
|
||||
`/jsp cowclicker` at the in-game prompt.
|
||||
|
||||
* Once you leave the game, your score is reset to zero.
|
||||
|
||||
* You can disconnect from the server and your score will be saved for
|
||||
the next time you join.
|
||||
|
||||
### Gameplay Mechanics
|
||||
|
||||
This is meant as a trivially simple use of the [Bukkit Scoreboard
|
||||
API][bukscore]. There are many things you'll want to consider when constructing
|
||||
your own mini-game...
|
||||
|
||||
* Is the game itself a long-lived game - that is - should players and
|
||||
scores be persisted (stored) between server restarts?
|
||||
|
||||
* What should happen when a player quits the server - should this also be
|
||||
understood as quitting the mini-game?
|
||||
|
||||
* What should happen when a player who was previously playing the
|
||||
mini-game, joins the server - should they automatically resume the
|
||||
mini-game?
|
||||
|
||||
[bukscore]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scoreboard/package-summary.html
|
||||
|
||||
***/
|
||||
|
||||
var store = {};
|
||||
|
||||
var scoreboardConfig = {
|
||||
cowclicker: {SIDEBAR: 'Cows Clicked'}
|
||||
};
|
||||
|
||||
/*
|
||||
The scoreboard is a simple wrapper around the Bukkit Scoreboard API.
|
||||
It's only concerned with display of scores, not maintaining them - that's the game's job.
|
||||
*/
|
||||
var scoreboard = (function(options){
|
||||
var temp = {};
|
||||
var ccScoreboard;
|
||||
var DisplaySlot = org.bukkit.scoreboard.DisplaySlot;
|
||||
|
||||
return {
|
||||
start: function(){
|
||||
var objective, slot;
|
||||
ccScoreboard = server.scoreboardManager.getNewScoreboard();
|
||||
for (objective in options){
|
||||
var ccObj = ccScoreboard.registerNewObjective(objective,'dummy');
|
||||
for (slot in options[objective]){
|
||||
ccObj.displaySlot = DisplaySlot[slot];
|
||||
ccObj.displayName = options[objective][slot];
|
||||
}
|
||||
}
|
||||
},
|
||||
stop: function(){
|
||||
var objective, slot;
|
||||
for (objective in options){
|
||||
ccScoreboard.getObjective(objective).unregister();
|
||||
for (slot in options[objective]){
|
||||
ccScoreboard.clearSlot(DisplaySlot[slot]);
|
||||
}
|
||||
}
|
||||
},
|
||||
update: function(objective,player,score){
|
||||
if (player.scoreboard && player.scoreboard != ccScoreboard)
|
||||
{
|
||||
temp[player.name] = player.scoreboard;
|
||||
player.scoreboard = ccScoreboard;
|
||||
}
|
||||
ccScoreboard.getObjective(objective).getScore(player).score = score;
|
||||
},
|
||||
restore: function(player){
|
||||
// offlineplayers don't have a scoreboard
|
||||
if (player.scoreboard)
|
||||
player.scoreboard = temp[player.name];
|
||||
}
|
||||
};
|
||||
}(scoreboardConfig));
|
||||
|
||||
var _onPlayerInteract = function(listener, event){
|
||||
var player = event.player;
|
||||
var Bukkit = org.bukkit.Bukkit;
|
||||
|
||||
if (!store[player.name])
|
||||
return;
|
||||
|
||||
var clickedEntity = event.rightClicked;
|
||||
var loc = clickedEntity.location;
|
||||
var sound = function(snd,vol,pitch){
|
||||
loc.world.playSound(loc,snd,vol,pitch);
|
||||
};
|
||||
if (clickedEntity instanceof org.bukkit.entity.Cow)
|
||||
{
|
||||
store[player.name].score++;
|
||||
scoreboard.update('cowclicker', player, store[player.name].score);
|
||||
|
||||
Bukkit.dispatchCommand(player, 'me clicked a cow!');
|
||||
sound(org.bukkit.Sound.CLICK,1,1);
|
||||
setTimeout(function(){
|
||||
sound(org.bukkit.Sound.COW_HURT,10,0.85)
|
||||
},200);
|
||||
}
|
||||
};
|
||||
var _onPlayerQuit = function(listener, event){
|
||||
_removePlayer(event.player)
|
||||
};
|
||||
var _onPlayerJoin = function(listener, event){
|
||||
var gamePlayer = store[event.player.name];
|
||||
if (gamePlayer)
|
||||
_addPlayer(event.player, gamePlayer.score);
|
||||
};
|
||||
|
||||
var _startGame = function(){
|
||||
if (config.verbose)
|
||||
console.log('Staring game: Cow Clicker');
|
||||
|
||||
events.on('player.PlayerQuitEvent', _onPlayerQuit);
|
||||
events.on('player.PlayerJoinEvent', _onPlayerJoin);
|
||||
events.on('player.PlayerInteractEntityEvent', _onPlayerInteract);
|
||||
|
||||
scoreboard.start();
|
||||
|
||||
store = persist('cowclicker',store);
|
||||
for (var p in store){
|
||||
var player = server.getPlayer(p);
|
||||
if (player){
|
||||
/*
|
||||
only add online players
|
||||
*/
|
||||
var score = store[p].score;
|
||||
_addPlayer(player, score);
|
||||
}
|
||||
}
|
||||
};
|
||||
var _addPlayer = function(player,score){
|
||||
if (config.verbose)
|
||||
console.log('Adding player %s to Cow Clicker game',player);
|
||||
|
||||
if (typeof score == 'undefined')
|
||||
score = 0;
|
||||
store[player.name] = {score: score};
|
||||
scoreboard.update('cowclicker', player,store[player.name].score);
|
||||
|
||||
player.sendMessage('Go forth and click some cows!');
|
||||
};
|
||||
|
||||
var _removePlayer = function(player,notify){
|
||||
|
||||
if (player instanceof org.bukkit.OfflinePlayer && player.player)
|
||||
player = player.player;
|
||||
|
||||
if (!store[player.name])
|
||||
return;
|
||||
if (config.verbose)
|
||||
console.log('Removing player %s from Cow Clicker', player);
|
||||
|
||||
var playerScore = store[player.name].score;
|
||||
|
||||
scoreboard.restore(player);
|
||||
|
||||
delete store[player.name];
|
||||
if (notify && player){
|
||||
player.sendMessage('You clicked ' + playerScore + ' cows! ' +
|
||||
'You must be tired after all that clicking.');
|
||||
}
|
||||
};
|
||||
var _removeAllPlayers = function(notify){
|
||||
if (typeof notify == 'undefined')
|
||||
notify = false;
|
||||
for (var p in store){
|
||||
var player = server.getOfflinePlayer(p);
|
||||
if (player)
|
||||
_removePlayer(player,notify);
|
||||
delete store[p];
|
||||
}
|
||||
}
|
||||
var _stopGame = function(removePlayers){
|
||||
if (typeof removePlayers == 'undefined')
|
||||
removePlayers = true;
|
||||
if (config.verbose)
|
||||
console.log('Stopping game: Cow Clicker');
|
||||
scoreboard.stop();
|
||||
if (!removePlayers)
|
||||
return;
|
||||
_removeAllPlayers(false);
|
||||
persist('cowclicker',store.pers,'w');
|
||||
|
||||
};
|
||||
/*
|
||||
start the game automatically when this module is loaded.
|
||||
*/
|
||||
_startGame();
|
||||
/*
|
||||
players can join and leave the game by typing `jsp cowclicker`
|
||||
*/
|
||||
command('cowclicker', function(params, sender){
|
||||
if (!store[sender.name])
|
||||
_addPlayer(sender);
|
||||
else
|
||||
_removePlayer(sender);
|
||||
});
|
||||
/*
|
||||
stop the game when ScriptCraft is unloaded.
|
||||
*/
|
||||
addUnloadHandler(function(){
|
||||
_stopGame(false);
|
||||
});
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*************************************************************************
|
||||
## Spawn Plugin
|
||||
|
||||
Allows in-game operators to easily spawn creatures at current location.
|
||||
|
||||
### Usage
|
||||
|
||||
/jsp spawn cow
|
||||
/jsp spawn sheep
|
||||
/jsp spawn wolf
|
||||
|
||||
This command supports TAB completion so to see a list of possible
|
||||
entitities, type `/jsp spawn ' at the in-game command prompt, then
|
||||
press TAB. Visit
|
||||
<http://jd.bukkit.org/beta/apidocs/org/bukkit/entity/EntityType.html>
|
||||
for a list of possible entities (creatures) which can be spawned.
|
||||
|
||||
***/
|
||||
var entities = [];
|
||||
var Types = org.bukkit.entity.EntityType
|
||||
for (var t in Types){
|
||||
if (Types[t] && Types[t].ordinal){
|
||||
entities.push(t);
|
||||
}
|
||||
}
|
||||
command('spawn', function(parameters, sender){
|
||||
if (!sender.op){
|
||||
sender.sendMessage('Only operators can perform this command');
|
||||
return;
|
||||
}
|
||||
var location = sender.location;
|
||||
var world = location.world;
|
||||
var type = ('' + parameters[0]).toUpperCase();
|
||||
world.spawnEntity(location, org.bukkit.entity.EntityType[type]);
|
||||
},entities);
|
Reference in new issue