Fix issue #111, reorg of lib/ and (undoc'd) persistence
This commit is contained in:
parent
c77e78c2e5
commit
aefc98f172
18 changed files with 514 additions and 106 deletions
11
build.xml
11
build.xml
|
@ -7,13 +7,6 @@
|
||||||
<property name="minecraft.dir" location="${dist}/minecraft" />
|
<property name="minecraft.dir" location="${dist}/minecraft" />
|
||||||
<property name="js-plugins-dir" value="scriptcraft"/>
|
<property name="js-plugins-dir" value="scriptcraft"/>
|
||||||
<property name="http.agent" value="'Walter'" />
|
<property name="http.agent" value="'Walter'" />
|
||||||
<target name="testy">
|
|
||||||
<echo message="${http.agent}"/>
|
|
||||||
<get src="http://dl.bukkit.org/api/1.0/downloads/projects/CraftBukkit/?_accept=application/xml"
|
|
||||||
verbose="true"
|
|
||||||
httpusecaches="false"
|
|
||||||
dest="${minecraft.dir}/waltbukkit.xml" />
|
|
||||||
</target>
|
|
||||||
<target name="init">
|
<target name="init">
|
||||||
<property file="build.local.properties"/>
|
<property file="build.local.properties"/>
|
||||||
<tstamp>
|
<tstamp>
|
||||||
|
@ -144,7 +137,7 @@ Walter Higgins
|
||||||
|
|
||||||
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
|
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
|
||||||
<mkdir dir="${dist}/${DSTAMP}" />
|
<mkdir dir="${dist}/${DSTAMP}" />
|
||||||
<jar jarfile="${dist}/${DSTAMP}/ScriptCraft.jar" basedir="${build}"/>
|
<jar jarfile="${dist}/${DSTAMP}/scriptcraft.jar" basedir="${build}"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="clean" description="clean up" >
|
<target name="clean" description="clean up" >
|
||||||
|
@ -157,6 +150,6 @@ Walter Higgins
|
||||||
<fileset dir="${minecraft.dir}/plugins/" includes="scriptcraft*.*"/>
|
<fileset dir="${minecraft.dir}/plugins/" includes="scriptcraft*.*"/>
|
||||||
</delete>
|
</delete>
|
||||||
<mkdir dir="${minecraft.dir}/plugins" />
|
<mkdir dir="${minecraft.dir}/plugins" />
|
||||||
<copy file="${dist}/${DSTAMP}/ScriptCraft.jar" todir="${minecraft.dir}/plugins"/>
|
<copy file="${dist}/${DSTAMP}/scriptcraft.jar" todir="${minecraft.dir}/plugins"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -117,6 +117,8 @@ Walter Higgins
|
||||||
* [Example Plugin #7 - Listening for events, Greet players when they join the game.](#example-plugin-7---listening-for-events-greet-players-when-they-join-the-game)
|
* [Example Plugin #7 - Listening for events, Greet players when they join the game.](#example-plugin-7---listening-for-events-greet-players-when-they-join-the-game)
|
||||||
* [Arrows Plugin](#arrows-plugin)
|
* [Arrows Plugin](#arrows-plugin)
|
||||||
* [Usage:](#usage-6)
|
* [Usage:](#usage-6)
|
||||||
|
* [Spawn Plugin](#spawn-plugin)
|
||||||
|
* [Usage](#usage-7)
|
||||||
* [alias Plugin](#alias-plugin)
|
* [alias Plugin](#alias-plugin)
|
||||||
* [Examples](#examples-2)
|
* [Examples](#examples-2)
|
||||||
* [Classroom Plugin](#classroom-plugin)
|
* [Classroom Plugin](#classroom-plugin)
|
||||||
|
@ -135,6 +137,10 @@ Walter Higgins
|
||||||
* [Example](#example-1)
|
* [Example](#example-1)
|
||||||
* [SnowballFight mini-game](#snowballfight-mini-game)
|
* [SnowballFight mini-game](#snowballfight-mini-game)
|
||||||
* [Description](#description-2)
|
* [Description](#description-2)
|
||||||
|
* [Cow Clicker Mini-Game](#cow-clicker-mini-game)
|
||||||
|
* [How to Play](#how-to-play)
|
||||||
|
* [Rules](#rules)
|
||||||
|
* [Gameplay Mechanics](#gameplay-mechanics)
|
||||||
|
|
||||||
## Modules in Scriptcraft
|
## Modules in Scriptcraft
|
||||||
|
|
||||||
|
@ -2340,6 +2346,18 @@ All of the above functions can take an optional player object or name
|
||||||
as a parameter. For example: `/js arrows.explosive('player23')` makes
|
as a parameter. For example: `/js arrows.explosive('player23')` makes
|
||||||
player23's arrows explosive.
|
player23's arrows explosive.
|
||||||
|
|
||||||
|
## Spawn Plugin
|
||||||
|
|
||||||
|
Allows in-game operators to easily spawn creatures at current location.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
/jsp spawn cow
|
||||||
|
/jsp spawn sheep
|
||||||
|
/jsp spawn wolf
|
||||||
|
|
||||||
|
See <http://jd.bukkit.org/beta/apidocs/org/bukkit/entity/EntityType.html> for a list of possible entities (creatures) which can be spawned.
|
||||||
|
|
||||||
## alias Plugin
|
## alias Plugin
|
||||||
|
|
||||||
The alias module lets players and server admins create their own
|
The alias module lets players and server admins create their own
|
||||||
|
@ -2621,3 +2639,44 @@ player returns to their previous mode of play (creative or
|
||||||
survival). Create a small arena with a couple of small buildings for
|
survival). Create a small arena with a couple of small buildings for
|
||||||
cover to make the game more fun.
|
cover to make the game more fun.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
![cow clicker](img/cowclicker.png)
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,11 @@ using the more succinct...
|
||||||
it is easier to read. The important thing to remember when using the
|
it is easier to read. The important thing to remember when using the
|
||||||
Bukkit (or any Java API) from Javascript is that for any Java Bean, a
|
Bukkit (or any Java API) from Javascript is that for any Java Bean, a
|
||||||
property called `propertyName` will have a getter called
|
property called `propertyName` will have a getter called
|
||||||
`getPropertyName()` and a setter called `setPropertyName`. From this
|
`getPropertyName()` and a setter called `setPropertyName()`. From this
|
||||||
rule you can infer what any Bukkit class properties are. For example,
|
rule you can infer what any Bukkit class properties are. For example,
|
||||||
the [Bukkit Player][bukpl] object has the following methods...
|
the [Bukkit Player][bukpl] object has the following methods...
|
||||||
|
|
||||||
* float getWalSpeed()
|
* float getWalkSpeed()
|
||||||
* void setWalkSpeed(float speed)
|
* void setWalkSpeed(float speed)
|
||||||
|
|
||||||
... so from this you can infer that every Player object has a
|
... so from this you can infer that every Player object has a
|
||||||
|
@ -61,7 +61,7 @@ the world in which a player is located...
|
||||||
If you're new to Java and the [Bukkit API][bukapi] is the first time
|
If you're new to Java and the [Bukkit API][bukapi] is the first time
|
||||||
you've browsed Java documentation, you may be wondering where the
|
you've browsed Java documentation, you may be wondering where the
|
||||||
`location` property came from - the `location` property is "inherited"
|
`location` property came from - the `location` property is "inherited"
|
||||||
by one of the Player classes super-classes. You'll see the
|
from one of the Player class's super-classes (it's ancestors). You'll see the
|
||||||
`getLocation()` method listed under a section titled **Methods
|
`getLocation()` method listed under a section titled **Methods
|
||||||
inherited from interface org.bukkit.entity.Entity** in the
|
inherited from interface org.bukkit.entity.Entity** in the
|
||||||
[Player][bukpl] javadoc page.
|
[Player][bukpl] javadoc page.
|
||||||
|
|
BIN
docs/img/cowclicker.png
Normal file
BIN
docs/img/cowclicker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
|
@ -1,3 +1,25 @@
|
||||||
|
# 2014 01 12
|
||||||
|
|
||||||
|
## Important
|
||||||
|
The ScriptCraft.jar file has been renamed scriptcraft.jar (see bug fix
|
||||||
|
details below). This means that you will have to remove the existing
|
||||||
|
`plugins/ScriptCraft.jar` file if present.
|
||||||
|
|
||||||
|
Bug Fix: On Mac OS, the plugins/scriptcraft directory is copied to
|
||||||
|
plugins/ScriptCraftPlugin the 2nd time ScriptCraftPlugin is loaded.
|
||||||
|
This has been fixed by changing the plugin name from ScriptCraftPlugin
|
||||||
|
to scriptcraft. The jar file has also been rename from
|
||||||
|
ScriptCraft.jar to scriptcraft.jar.
|
||||||
|
|
||||||
|
New command: `jsp spawn` lets in-game operators spawn any type of
|
||||||
|
entity. For example `/jsp spawn cow` will spawn a cow at the in-game
|
||||||
|
operator's current location.
|
||||||
|
|
||||||
|
New minigame: Cow Clicker. A simple demonstration of using Bukkit's
|
||||||
|
Scoreboard API. Players click cows to score points. Scores are
|
||||||
|
displayed in a side bar on screen. Players join or leave the game by
|
||||||
|
typing `/jsp cowclicker` at the in-game prompt.
|
||||||
|
|
||||||
# 2014 01 05
|
# 2014 01 05
|
||||||
|
|
||||||
Bug Fix: On Mac OS, alias plugin caused Exceptions due to missing
|
Bug Fix: On Mac OS, alias plugin caused Exceptions due to missing
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
args = args.slice(1);
|
args = args.slice(1);
|
||||||
|
|
||||||
|
// 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,'');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var template = args[0];
|
var template = args[0];
|
||||||
|
|
||||||
var BufferedReader = java.io.BufferedReader;
|
var BufferedReader = java.io.BufferedReader;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
/**
|
/**
|
||||||
* Unzips bundled javascript code.
|
* Unzips bundled javascript code.
|
||||||
*/
|
*/
|
||||||
private void unzipJS()
|
private void unzipJS() throws IOException
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// does the js-plugins directory exist?
|
// does the js-plugins directory exist?
|
||||||
|
@ -37,9 +37,13 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
File jsPlugins = new File(JS_PLUGINS_DIR);
|
File jsPlugins = new File(JS_PLUGINS_DIR);
|
||||||
if (!jsPlugins.exists())
|
if (!jsPlugins.exists())
|
||||||
{
|
{
|
||||||
getLogger().finest("Directory " + JS_PLUGINS_DIR + " does not exist.");
|
getLogger().info("Directory " + jsPlugins.getCanonicalPath() + " does not exist.");
|
||||||
getLogger().finest("Initializing " + JS_PLUGINS_DIR + " directory with contents from plugin archive.");
|
getLogger().info("Initializing " + jsPlugins.getCanonicalPath() + " directory with contents from plugin archive.");
|
||||||
jsPlugins.mkdir();
|
try{
|
||||||
|
jsPlugins.mkdirs();
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new RuntimeException("Failed to create directory " + jsPlugins.getCanonicalPath() + ":" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipInputStream zis = new ZipInputStream(getResource(JS_PLUGINS_ZIP));
|
ZipInputStream zis = new ZipInputStream(getResource(JS_PLUGINS_ZIP));
|
||||||
|
@ -48,7 +52,7 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
while ( ( entry = zis.getNextEntry() ) != null)
|
while ( ( entry = zis.getNextEntry() ) != null)
|
||||||
{
|
{
|
||||||
String filename = entry.getName();
|
String filename = entry.getName();
|
||||||
//File newFile = new File(jsPlugins.getName() + File.separator + filename);
|
|
||||||
File newFile = new File(jsPlugins, filename);
|
File newFile = new File(jsPlugins, filename);
|
||||||
|
|
||||||
//create all non exists folders
|
//create all non exists folders
|
||||||
|
@ -59,17 +63,23 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
//
|
//
|
||||||
// only write out to file if zip entry is newer than file
|
// only write out to file if zip entry is newer than file
|
||||||
//
|
//
|
||||||
|
String reason = null;
|
||||||
long zTime = entry.getTime();
|
long zTime = entry.getTime();
|
||||||
boolean unzip = false;
|
boolean unzip = false;
|
||||||
if (!newFile.exists())
|
if (!newFile.exists()){
|
||||||
unzip = true;
|
reason = "NE";
|
||||||
else{
|
|
||||||
long fTime = newFile.lastModified();
|
|
||||||
if (zTime > fTime)
|
|
||||||
unzip = true;
|
unzip = true;
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
long fTime = newFile.lastModified();
|
||||||
|
if (zTime > fTime){
|
||||||
|
reason = "" + new Long((zTime-fTime)/3600000) + "h";
|
||||||
|
unzip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (unzip){
|
if (unzip){
|
||||||
getLogger().info("Unzipping " + newFile.getCanonicalPath());
|
getLogger().info("Unzipping " + newFile.getCanonicalPath() + " (" + reason + ")" );
|
||||||
FileOutputStream fout = new FileOutputStream(newFile);
|
FileOutputStream fout = new FileOutputStream(newFile);
|
||||||
for (int c = zis.read(); c != -1; c = zis.read()) {
|
for (int c = zis.read(); c != -1; c = zis.read()) {
|
||||||
fout.write(c);
|
fout.write(c);
|
||||||
|
@ -90,9 +100,9 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
@Override
|
@Override
|
||||||
public void onEnable()
|
public void onEnable()
|
||||||
{
|
{
|
||||||
unzipJS();
|
|
||||||
FileReader reader = null;
|
FileReader reader = null;
|
||||||
try{
|
try{
|
||||||
|
unzipJS();
|
||||||
ScriptEngineManager factory = new ScriptEngineManager();
|
ScriptEngineManager factory = new ScriptEngineManager();
|
||||||
File bootScript = new File(JS_PLUGINS_DIR + "/lib/scriptcraft.js");
|
File bootScript = new File(JS_PLUGINS_DIR + "/lib/scriptcraft.js");
|
||||||
this.engine = factory.getEngineByName("JavaScript");
|
this.engine = factory.getEngineByName("JavaScript");
|
||||||
|
@ -103,6 +113,7 @@ public class ScriptCraftPlugin extends JavaPlugin implements Listener
|
||||||
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
this.getLogger().severe(e.getMessage());
|
||||||
}finally {
|
}finally {
|
||||||
if (reader != null){
|
if (reader != null){
|
||||||
try {
|
try {
|
||||||
|
|
33
src/main/javascript/lib/js-patch.js
Normal file
33
src/main/javascript/lib/js-patch.js
Normal file
|
@ -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();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
37
src/main/javascript/lib/persistence.js
Normal file
37
src/main/javascript/lib/persistence.js
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -3,23 +3,6 @@ var console = require('./console');
|
||||||
var File = java.io.File;
|
var File = java.io.File;
|
||||||
var FileWriter = java.io.FileWriter;
|
var FileWriter = java.io.FileWriter;
|
||||||
var PrintWriter = java.io.PrintWriter;
|
var PrintWriter = java.io.PrintWriter;
|
||||||
|
|
||||||
/*
|
|
||||||
Save a javascript object to a file (saves using JSON notation)
|
|
||||||
*/
|
|
||||||
var _save = function(object, filename){
|
|
||||||
var objectToStr = null;
|
|
||||||
try{
|
|
||||||
objectToStr = JSON.stringify(object,null,2);
|
|
||||||
}catch(e){
|
|
||||||
print("ERROR: " + e.getMessage() + " while saving " + filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var f = (filename instanceof File) ? filename : new File(filename);
|
|
||||||
var out = new PrintWriter(new FileWriter(f));
|
|
||||||
out.println( objectToStr );
|
|
||||||
out.close();
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
plugin management
|
plugin management
|
||||||
*/
|
*/
|
||||||
|
@ -34,25 +17,18 @@ var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPer
|
||||||
return _plugins[moduleName].module;
|
return _plugins[moduleName].module;
|
||||||
|
|
||||||
var pluginData = {persistent: isPersistent, module: moduleObject};
|
var pluginData = {persistent: isPersistent, module: moduleObject};
|
||||||
moduleObject.store = moduleObject.store || {};
|
if (typeof moduleObject.store == 'undefined')
|
||||||
|
moduleObject.store = {};
|
||||||
|
|
||||||
_plugins[moduleName] = pluginData;
|
_plugins[moduleName] = pluginData;
|
||||||
|
|
||||||
if (isPersistent){
|
if (isPersistent){
|
||||||
if (!moduleObject.store){
|
moduleObject.store = persist(moduleName, moduleObject.store);
|
||||||
moduleObject.store = {};
|
|
||||||
}
|
|
||||||
var loadedStore = load(dataDir.canonicalPath + "/" + moduleName + "-store.json");
|
|
||||||
if (loadedStore){
|
|
||||||
for (var i in loadedStore){
|
|
||||||
moduleObject.store[i] = loadedStore[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return moduleObject;
|
return moduleObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.plugin = _plugin;
|
exports.plugin = _plugin;
|
||||||
exports.save = _save;
|
|
||||||
|
|
||||||
var scriptCraftDir = null;
|
var scriptCraftDir = null;
|
||||||
var pluginDir = null;
|
var pluginDir = null;
|
||||||
|
@ -65,7 +41,7 @@ exports.autoload = function(dir) {
|
||||||
dataDir = new File(dir, "data");
|
dataDir = new File(dir, "data");
|
||||||
|
|
||||||
var _canonize = function(file){
|
var _canonize = function(file){
|
||||||
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
return '' + file.canonicalPath.replaceAll("\\\\","/");
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
recursively walk the given directory and return a list of all .js files
|
recursively walk the given directory and return a list of all .js files
|
||||||
|
@ -78,9 +54,7 @@ exports.autoload = function(dir) {
|
||||||
if (file.isDirectory()){
|
if (file.isDirectory()){
|
||||||
_listSourceFiles(store,file);
|
_listSourceFiles(store,file);
|
||||||
}else{
|
}else{
|
||||||
if ((file.getCanonicalPath().endsWith(".js")
|
if ( file.canonicalPath.endsWith('.js') ){
|
||||||
|| file.getCanonicalPath().endsWith(".coffee"))
|
|
||||||
) {
|
|
||||||
store.push(file);
|
store.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,11 +71,11 @@ exports.autoload = function(dir) {
|
||||||
|
|
||||||
var len = sourceFiles.length;
|
var len = sourceFiles.length;
|
||||||
if (config.verbose)
|
if (config.verbose)
|
||||||
console.info(len + " scriptcraft plugins found.");
|
console.info(len + ' scriptcraft plugins found.');
|
||||||
for (var i = 0;i < len; i++){
|
for (var i = 0;i < len; i++){
|
||||||
var pluginPath = _canonize(sourceFiles[i]);
|
var pluginPath = _canonize(sourceFiles[i]);
|
||||||
if (config.verbose)
|
if (config.verbose)
|
||||||
console.info("Loading plugin: " + pluginPath);
|
console.info('Loading plugin: ' + pluginPath);
|
||||||
var module = {};
|
var module = {};
|
||||||
try {
|
try {
|
||||||
module = require(pluginPath);
|
module = require(pluginPath);
|
||||||
|
@ -119,13 +93,3 @@ exports.autoload = function(dir) {
|
||||||
_reload(pluginDir);
|
_reload(pluginDir);
|
||||||
};
|
};
|
||||||
|
|
||||||
addUnloadHandler(function(){
|
|
||||||
//
|
|
||||||
// save all plugins which have persistent data
|
|
||||||
//
|
|
||||||
for (var moduleName in _plugins){
|
|
||||||
var pluginData = _plugins[moduleName];
|
|
||||||
if (pluginData.persistent)
|
|
||||||
_save(pluginData.module.store, dataDir.canonicalPath + "/" + moduleName + "-store.json");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -187,11 +187,12 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
||||||
{
|
{
|
||||||
var file = resolveModuleToFile(path, parentFile);
|
var file = resolveModuleToFile(path, parentFile);
|
||||||
if (!file){
|
if (!file){
|
||||||
var errMsg = java.lang.String
|
var errMsg = '' + java.lang.String.format("require() failed to find matching file for module '%s' " +
|
||||||
.format("require() failed to find matching file for module '%s' " +
|
"in working directory '%s' ", [path, parentFile.canonicalPath]);
|
||||||
"while searching directory '%s' and paths %s.",
|
if (! ( (''+path).match(/^\./) )){
|
||||||
[path, parentFile.canonicalPath, JSON.stringify(modulePaths)]);
|
errMsg = errMsg + ' and not found in paths ' + JSON.stringify(modulePaths);
|
||||||
console.warn(errMsg);
|
}
|
||||||
|
logger.warning(errMsg);
|
||||||
throw new Error(errMsg);
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
var canonizedFilename = _canonize(file);
|
var canonizedFilename = _canonize(file);
|
||||||
|
@ -242,7 +243,7 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
||||||
.apply(moduleInfo.exports, /* this */
|
.apply(moduleInfo.exports, /* this */
|
||||||
parameters);
|
parameters);
|
||||||
} catch (e){
|
} catch (e){
|
||||||
console.error("Error:" + e + " while executing module " + canonizedFilename);
|
logger.severe('Error:' + e + ' while executing module ' + canonizedFilename);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
|
|
@ -422,7 +422,9 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
return ;
|
return ;
|
||||||
var File = java.io.File
|
var File = java.io.File
|
||||||
,FileReader = java.io.FileReader
|
,FileReader = java.io.FileReader
|
||||||
,BufferedReader = java.io.BufferedReader;
|
,BufferedReader = java.io.BufferedReader
|
||||||
|
,PrintWriter = java.io.PrintWriter
|
||||||
|
,FileWriter = java.io.FileWriter;
|
||||||
|
|
||||||
var _canonize = function(file){
|
var _canonize = function(file){
|
||||||
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
||||||
|
@ -432,6 +434,23 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
var jsPluginsRootDir = libDir.parentFile; // scriptcraft
|
var jsPluginsRootDir = libDir.parentFile; // scriptcraft
|
||||||
var jsPluginsRootDirName = _canonize(jsPluginsRootDir);
|
var jsPluginsRootDirName = _canonize(jsPluginsRootDir);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save a javascript object to a file (saves using JSON notation)
|
||||||
|
*/
|
||||||
|
var _save = function(object, filename){
|
||||||
|
var objectToStr = null;
|
||||||
|
try{
|
||||||
|
objectToStr = JSON.stringify(object,null,2);
|
||||||
|
}catch(e){
|
||||||
|
print("ERROR: " + e.getMessage() + " while saving " + filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var f = (filename instanceof File) ? filename : new File(filename);
|
||||||
|
var out = new PrintWriter(new FileWriter(f));
|
||||||
|
out.println( objectToStr );
|
||||||
|
out.close();
|
||||||
|
};
|
||||||
|
|
||||||
var _loaded = {};
|
var _loaded = {};
|
||||||
/*
|
/*
|
||||||
Load the contents of the file and evaluate as javascript
|
Load the contents of the file and evaluate as javascript
|
||||||
|
@ -487,7 +506,7 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
/*
|
/*
|
||||||
now that load is defined, use it to load a global config object
|
now that load is defined, use it to load a global config object
|
||||||
*/
|
*/
|
||||||
var config = _load(new File(jsPluginsRootDir, "data/global-config.json" ));
|
var config = _load(new File(jsPluginsRootDir, 'data/global-config.json' ));
|
||||||
if (!config)
|
if (!config)
|
||||||
config = {verbose: false};
|
config = {verbose: false};
|
||||||
global.config = config;
|
global.config = config;
|
||||||
|
@ -510,27 +529,6 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
global.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;
|
|
||||||
};
|
|
||||||
global.clearTimeout = function(bukkitTask){
|
|
||||||
bukkitTask.cancel();
|
|
||||||
};
|
|
||||||
|
|
||||||
global.setInterval = function(callback, intervalInMillis){
|
|
||||||
var delay = intervalInMillis/ 50;
|
|
||||||
var bukkitTask = server.scheduler.runTaskTimer(__plugin, callback, delay, delay);
|
|
||||||
return bukkitTask;
|
|
||||||
};
|
|
||||||
global.clearInterval = function(bukkitTask){
|
|
||||||
bukkitTask.cancel();
|
|
||||||
};
|
|
||||||
global.refresh = function(){
|
global.refresh = function(){
|
||||||
__plugin.pluginLoader.disablePlugin(__plugin);
|
__plugin.pluginLoader.disablePlugin(__plugin);
|
||||||
__plugin.pluginLoader.enablePlugin(__plugin);
|
__plugin.pluginLoader.enablePlugin(__plugin);
|
||||||
|
@ -547,6 +545,7 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
global.echo = _echo;
|
global.echo = _echo;
|
||||||
global.alert = _echo;
|
global.alert = _echo;
|
||||||
global.load = _load;
|
global.load = _load;
|
||||||
|
global.save = _save;
|
||||||
|
|
||||||
global.addUnloadHandler = _addUnloadHandler;
|
global.addUnloadHandler = _addUnloadHandler;
|
||||||
|
|
||||||
|
@ -556,21 +555,30 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
*/
|
*/
|
||||||
var modulePaths = [jsPluginsRootDirName + '/lib/',
|
var modulePaths = [jsPluginsRootDirName + '/lib/',
|
||||||
jsPluginsRootDirName + '/modules/'];
|
jsPluginsRootDirName + '/modules/'];
|
||||||
global.require = fnRequire(__plugin.logger, __engine, config.verbose, jsPluginsRootDirName, modulePaths);
|
global.require = fnRequire(__plugin.logger,
|
||||||
|
__engine,
|
||||||
|
config.verbose,
|
||||||
|
jsPluginsRootDirName,
|
||||||
|
modulePaths);
|
||||||
|
|
||||||
|
require('js-patch')(global);
|
||||||
global.console = require('console');
|
global.console = require('console');
|
||||||
|
/*
|
||||||
|
setup persistence
|
||||||
|
*/
|
||||||
|
require('persistence')(jsPluginsRootDir,global);
|
||||||
|
|
||||||
global.command = require('command').command;
|
global.command = require('command').command;
|
||||||
var plugins = require('plugin');
|
var plugins = require('plugin');
|
||||||
|
|
||||||
global.__onTabComplete = require('tabcomplete');
|
global.__onTabComplete = require('tabcomplete');
|
||||||
|
|
||||||
global.plugin = plugins.plugin;
|
global.plugin = plugins.plugin;
|
||||||
global.save = plugins.save;
|
|
||||||
|
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
events.on('server.PluginDisableEvent',function(l,e){
|
events.on('server.PluginDisableEvent',function(l,e){
|
||||||
// save config
|
// save config
|
||||||
plugins.save(global.config, new File(jsPluginsRootDir, "data/global-config.json" ));
|
save(global.config, new File(jsPluginsRootDir, "data/global-config.json" ));
|
||||||
|
|
||||||
_runUnloadHandlers();
|
_runUnloadHandlers();
|
||||||
org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin);
|
org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin);
|
||||||
|
@ -625,10 +633,12 @@ function __onEnable (__engine, __plugin, __script)
|
||||||
for (var i = 0; i < legacyDirs.length; i++){
|
for (var i = 0; i < legacyDirs.length; i++){
|
||||||
if (legacyDirs[i].exists() && legacyDirs[i].isDirectory()){
|
if (legacyDirs[i].exists() && legacyDirs[i].isDirectory()){
|
||||||
legacyExists = true;
|
legacyExists = true;
|
||||||
console.warn('Legacy ScriptCraft directory ' + legacyDirs[i].canonicalPath + ' was found. This directory is no longer used.');
|
console.warn('Legacy ScriptCraft directory %s was found. This directory is no longer used.',
|
||||||
|
legacyDirs[i].canonicalPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (legacyExists){
|
if (legacyExists){
|
||||||
console.info('Please note that the working directory for ' + __plugin + ' is ' + jsPluginsRootDir.canonicalPath);
|
console.info('Please note that the working directory for %s is %s',
|
||||||
|
__plugin, jsPluginsRootDir.canonicalPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,9 +77,3 @@ for (var method in formattingCodes){
|
||||||
return function(){return c+this;};
|
return function(){return c+this;};
|
||||||
}(formattingCodes[method]);
|
}(formattingCodes[method]);
|
||||||
}
|
}
|
||||||
// wph 20140105 trim not availabe in String on Mac OS.
|
|
||||||
if (!String.prototype.trim){
|
|
||||||
String.prototype.trim = function(){
|
|
||||||
return this.replace(/^\s+|\s+$/g,'');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ var classroom = plugin("classroom", {
|
||||||
allowScripting: function (/* boolean: true or false */ canScript, sender) {
|
allowScripting: function (/* boolean: true or false */ canScript, sender) {
|
||||||
if (typeof sender == 'undefined'){
|
if (typeof sender == 'undefined'){
|
||||||
console.log("Attempt to set classroom scripting without credentials");
|
console.log("Attempt to set classroom scripting without credentials");
|
||||||
|
console.log("classroom.allowScripting(boolean, sender)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!sender.op){
|
if (!sender.op){
|
||||||
|
|
|
@ -15,8 +15,20 @@ Once the game begins, guess a number by typing the `/` character
|
||||||
followed by a number between 1 and 10.
|
followed by a number between 1 and 10.
|
||||||
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
var sb = function(cmd){
|
||||||
|
org.bukkit.Bukkit.dispatchCommand(server.consoleSender, 'scoreboard ' + cmd)
|
||||||
|
};
|
||||||
|
|
||||||
exports.Game_NumberGuess = {
|
exports.Game_NumberGuess = {
|
||||||
start: function(sender) {
|
start: function(sender) {
|
||||||
|
|
||||||
|
var guesses = 0;
|
||||||
|
|
||||||
|
sb('objectives add NumberGuess dummy Guesses');
|
||||||
|
sb('players set ' + sender.name + ' NumberGuess ' + guesses);
|
||||||
|
sb('objectives setdisplay sidebar NumberGuess');
|
||||||
|
|
||||||
importPackage(org.bukkit.conversations);
|
importPackage(org.bukkit.conversations);
|
||||||
|
|
||||||
var number = Math.ceil(Math.random() * 10);
|
var number = Math.ceil(Math.random() * 10);
|
||||||
|
@ -38,6 +50,7 @@ exports.Game_NumberGuess = {
|
||||||
if (s == number){
|
if (s == number){
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
ctx.forWhom.sendRawMessage("You guessed Correct!");
|
ctx.forWhom.sendRawMessage("You guessed Correct!");
|
||||||
|
sb('objectives remove NumberGuess');
|
||||||
},100);
|
},100);
|
||||||
return null;
|
return null;
|
||||||
}else{
|
}else{
|
||||||
|
@ -45,6 +58,9 @@ exports.Game_NumberGuess = {
|
||||||
ctx.setSessionData("hint","too low\n");
|
ctx.setSessionData("hint","too low\n");
|
||||||
if (s > number)
|
if (s > number)
|
||||||
ctx.setSessionData("hint","too high\n");
|
ctx.setSessionData("hint","too high\n");
|
||||||
|
guesses++;
|
||||||
|
sb('players set ' + sender.name + ' NumberGuess ' + guesses);
|
||||||
|
|
||||||
return prompt;
|
return prompt;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
225
src/main/javascript/plugins/minigames/cow-clicker.js
Normal file
225
src/main/javascript/plugins/minigames/cow-clicker.js
Normal file
|
@ -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.
|
||||||
|
|
||||||
|
![cow clicker](img/cowclicker.png)
|
||||||
|
|
||||||
|
### 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);
|
||||||
|
});
|
||||||
|
|
35
src/main/javascript/plugins/spawn.js
Normal file
35
src/main/javascript/plugins/spawn.js
Normal file
|
@ -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);
|
|
@ -1,4 +1,4 @@
|
||||||
name: ScriptCraftPlugin
|
name: scriptcraft
|
||||||
main: net.walterhiggins.scriptcraft.ScriptCraftPlugin
|
main: net.walterhiggins.scriptcraft.ScriptCraftPlugin
|
||||||
version: [[version]]
|
version: [[version]]
|
||||||
commands:
|
commands:
|
||||||
|
|
Reference in a new issue