Oh the complexity of it all!
In Part 8, there’s a bit more new JavaScript introduced, but there’s also a bunch more ScriptCraft/CanaryMod introduced. These things get complicated fast, but I wanted to show what’s possible and some of how I got there.
I think the end result is pretty cool: it’s an egg hunt! But you don’t have to go looking for the chickens. This egg hunt comes complete with a bunch of chickens that are ready to lay eggs within seconds.
The Video
egghunt.js
/*global require, command, server, Packages, echo, setTimeout, plugin*/
var utils = require("utils"),
items = require("items"),
events = require("events"),
Canary = Packages.net.canarymod.Canary,
CHICKEN = Packages.net.canarymod.api.entity.EntityType.CHICKEN,
Location = Packages.net.canarymod.api.world.position.Location;
var gameData,
chickens,
itemPickupListener,
GAME_LENGTH = 10, // Number of seconds
CHICKEN_COUNT = 20,
CHICKEN_LOCATION_VARIATION = 10, // Number of blocks
EGG_TIMER = 60; // Time in ticks (20 per second)
function execCommand( command ){
server.executeVanillaCommand(server, command);
}
function setupScoreboard() {
execCommand("scoreboard objectives add egghunt dummy Egg Hunt");
execCommand("scoreboard objectives setdisplay sidebar egghunt");
execCommand("scoreboard teams add red");
execCommand("scoreboard teams add yellow");
gameData = {
scores: {},
playerTeams: {},
teamScores: {
red: 0,
yellow: 0
},
mvpScore: 0,
mvp: "no one!"
};
}
function setupTeams() {
utils.players(function (player) {
var loc = player.location;
loc.y -= 1;
var block = utils.blockAt(loc);
if (block.type.machineName !== "minecraft:wool") {
echo(player, "You are not playing egghunt because you are not on wool");
return;
}
var color = block.getPropertyForName("color"),
woolColor = block.getValue(color).toString().toLowerCase();
gameData.scores[player.name] = 0;
gameData.playerTeams[player.name] = woolColor;
echo(player, "You are on the " + woolColor + " team");
});
}
function spawnChickens(location) {
var entityFactory = Canary.factory().entityFactory;
chickens = [];
for (var i = 0; i < CHICKEN_COUNT; i++) {
var newLoc = location.clone();
newLoc.x += Math.floor(Math.random() * CHICKEN_LOCATION_VARIATION - CHICKEN_LOCATION_VARIATION / 2);
newLoc.z += Math.floor(Math.random() * CHICKEN_LOCATION_VARIATION - CHICKEN_LOCATION_VARIATION / 2);
var chicken = entityFactory.newEntity(CHICKEN, newLoc);
chicken.setTimeUntilNextEgg(Math.floor(Math.random() * EGG_TIMER));
chickens.push(chicken);
chicken.spawn();
}
}
function cleanupEggs() {
utils.players(function (player) {
if (gameData.scores[player.name] !== undefined) {
while (player.inventory.hasItem(items.egg())) {
player.inventory.removeItem(items.egg());
}
}
});
}
function itemPickupHook(event) {
var entityItem = event.getItem(),
item = entityItem.getItem();
if (item.displayName === "Egg") {
var playerName = event.getPlayer().name,
scores = gameData.scores;
if (scores[playerName] !== undefined) {
scores[playerName] += 1;
var score = scores[playerName];
if (score > gameData.mvpScore) {
gameData.mvp = playerName;
gameData.mvpScore = score;
}
gameData.teamScores[gameData.playerTeams[playerName]] += 1;
execCommand("scoreboard players set " + playerName + " egghunt " + score);
}
}
}
function finishGame() {
if (chickens) {
utils.foreach(chickens, function (chicken) {
chicken.destroy();
});
chickens = null;
}
if (itemPickupListener) {
itemPickupListener.unregister();
itemPickupListener = null;
}
execCommand("scoreboard objectives remove egghunt");
execCommand("scoreboard teams remove red");
execCommand("scoreboard teams remove yellow");
var redScore = gameData.teamScores.red,
yellowScore = gameData.teamScores.yellow;
if (redScore > yellowScore) {
server.broadcastMessage("Red has triumphed over yellow!");
server.broadcastMessage(redScore + " to " + yellowScore);
} else if (redScore === yellowScore) {
server.broadcastMessage("It's a tie! " + redScore + " all!");
} else {
server.broadcastMessage("Yellow has vanquished red!");
server.broadcastMessage(yellowScore + " to " + redScore);
}
server.broadcastMessage("The MVP was " + gameData.mvp + " with " + gameData.mvpScore + " eggs!");
var scores = gameData.scores;
utils.players(function (player) {
if (scores[player.name] !== undefined) {
echo(player, "You found " + scores[player.name] + " eggs");
}
});
cleanupEggs();
gameData = null;
}
var egghunt = plugin("egghunt", {
store: {}
}, true);
command("egghunt", function (parameters, player) {
if (parameters[0] === "save") {
egghunt.store.chickenspot = player.location.toString();
echo(player, "Location saved!");
return;
}
if (gameData) {
echo(player, "Egghunt already in progress!");
return;
}
server.broadcastMessage("Starting an egghunt");
setTimeout(finishGame, GAME_LENGTH * 1000);
setupScoreboard();
setupTeams();
cleanupEggs();
var location = player.location;
if (egghunt.store.chickenspot) {
location = Location.fromString(egghunt.store.chickenspot);
}
spawnChickens(location);
itemPickupListener = events.itemPickup(itemPickupHook);
});
Where To Go From Here
See if there are some changes you might want to make to the egg hunt minigame.