content/hifi-content/brosche/DomainContent/Hub/MoneyTree/ACmoneyTree.js
2022-02-13 21:50:01 +01:00

921 lines
No EOL
31 KiB
JavaScript

// ACmoneyTree.js
// Created by Mark Brosche on 10-18-2018
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/* global EventBridge Users AccountServices Agent Avatar EntityViewer */
Agent.isAvatar = true;
Avatar.skeletonModelURL = 'http://hifi-content.s3.amazonaws.com/ozan/dev/avatars/invisible_avatar/invisible_avatar.fst';
Avatar.displayName = "Money Tree Agent";
Avatar.position = {"x":-19.109256744384766,"y":-20.8349714279174805,"z":-11.181184768676758}; // Tree Position
var googleURL = "https://script.google.com/a/highfidelity.io/macros/s/AKfycbxvLCGJwYKGOlszXwm2m-Xa1U90RmnIEJiD6nD7Z8-1RlZaADY/exec";
var AVERAGE_INTERVAL = 2, // Two minutes
AVERAGE_HFC_AMOUNT = 10,
STANDARD_DEVIATION = 5,
SHOW_TIME_LENGTH = 60000, // One minute
RECIPIENT_MAX = 3,
MONEY_TREE_CHANNEL = "MoneyTreeChannel",
OPERATOR_CHANNEL = "OperatorChannel",
RECIPIENT_CHANNEL = "RecipientChannel",
GIVER_CHANNEL = "GiverChannel",
AC_SCRIPT_RUN = true,
SEARCH_CENTER = {x: -18.1834, y: -7.7738, z: -11.8755},
SEARCH_AREA= 1000;
var populationID,
marquisID,
marquisMessage = "",
targetGiver = [],
targetRecipients = [],
amount = null,
payOnce = false,
recipient,
userList= [],
coinSpawner = [],
coinSpawnTimeout = null,
userListGiverIndex = null,
operatorsPresent = [],
treePower = true,
tempList = [],
messageHandler,
powerButtonSpawner = [],
powerButtonMaterial = [],
octreeInterval = null,
responseTimeout = Number.MAX_VALUE,
randomIntervals = [120000];
var treeOperators = [
"markb",
"ryan",
"andy_batman",
"zfox",
"TheBanker",
"siphnos",
"JSON",
"WadeWatts",
"BenB",
"ephesos",
"pytho",
"diogenes",
"Zack_hifi",
"Mold",
"Zeenai",
"Serling",
"nvrndr",
"HiFiMicki",
"Jazmin"
];
var hiFiStaff = [
"b",
"joshuamdavis",
"bridies",
"jazmin",
"marko8904",
"mhard",
"theo",
"adamisawake",
"aitolda",
"alan_",
"alt.howard",
"amantley",
"amer",
"amukul",
"andrewNyan",
"andy_batman",
"antoninas",
"asbecker8",
"ashleigh_harris",
"becky",
"benb",
"bimyou",
"birarda",
"c",
"caitlyn",
"changX",
"cheetah_Pattern",
"clement",
"dantescalves",
"dback",
"diogenes",
"dogbones",
"emily",
"emily_sykes",
"emilythethird",
"firebird25",
"freidrica",
"goofygoober",
"hifidave",
"hifi_jamil",
"hifijazzy",
"hifimarko",
"hiFimicki",
"high.fidelity",
"howard.stearns",
"huffman",
"huffman2",
"hyperlogic",
"ingerjm0",
"jeffclinton",
"jess",
"jherico",
"john.highfidelity",
"json",
"jyoum",
"kayla_hf",
"kencooke",
"kkurian",
"lameboycool",
"leviathan",
"luiscuenca",
"markb",
"maspring",
"miladn",
"mold",
"misslivirose",
"nbaldassini",
"nik",
"nissim",
"nvrndr",
"ovohightower",
"philip",
"r3tk0n",
"realmisslivirose",
"rickcarr044",
"Roxie",
"sabrina",
"sam",
"samgondelman",
"sbbsteam",
"sean",
"seanjones2848",
"serling",
"sethalves",
"shanzam",
"simon_walton",
"sophocles",
"thebanker",
"thoys",
"wadewatts",
"wayne",
"yohighness",
"ypsilanti",
"zack_hifi",
"zappoMan",
"zfox",
"zfox1",
"zeenai",
"battery",
"conference2",
"conference3",
"demo1",
"demo2",
"langton",
"market",
"purchases",
"anton.von.trier",
"kitchen",
"mic1",
"mic2",
"ejahner",
"freyja",
"qligmaloney",
"usertest",
"highfidelity",
"ryan",
"skelina",
"siphnos",
"ephesos",
"pytho"
];
var bannedUsers = [
"shonna",
"victorialove",
"annabelle",
"dunechi1d",
"john.galt",
"garik",
"kalita",
"anna.belle1"
];
messageHandler = function(channel, message, senderUUID, localOnly) {
// Setup
if (channel !== MONEY_TREE_CHANNEL) {
return;
} else {
message = JSON.parse(message);
}
// Notify the chosen recipient
if (message.type === 'entering' && message.nodeID === senderUUID ) {
var avatarsInDomain = AvatarList.getAvatarIdentifiers();
var nameOnList = false;
var isBanned = false;
avatarsInDomain.forEach(function(nodeID){
if (treeOperators.indexOf(message.username) !== -1 &&
!operatorsPresent[operatorsPresent.map(function(e) { return e.username; }).indexOf(message.username)]) {
operatorsPresent.push({
username: message.username,
nodeID: message.nodeID
});
console.log(JSON.stringify("operators ", operatorsPresent));
bankerOverlay(message.nodeID, false);
updateMarquis();
}
// If the username or UUID is already on the list, do not add it to the list!
userList.forEach(function(index){
if (message.username.toLowerCase() === index.username ||
Uuid.isEqual(message.nodeID, index.nodeID)) {
nameOnList = true;
console.log(nameOnList, "is on the list already");
}
});
// if username is banned do not add them to the list.
bannedUsers.forEach(function(username){
if (message.username.toLowerCase() === username){
isBanned = true;
}
});
if (!nameOnList && !isBanned) {
console.log("nameonlist", nameOnList, " is banned: ", isBanned);
// Add name and nodeID to list
userList.push({
username: message.username.toLowerCase(),
nodeID: message.nodeID,
staff: false
});
// If user is staff, mark [].staff 'true'
hiFiStaff.forEach(function(username){
if (message.username === username){
userList[userList.map(function(e) { return e.username; }).indexOf(message.username)].staff = true;
}
});
// Update Signs
console.log("userslist", JSON.stringify(userList));
updateMarquis();
}
});
// Someone left the zone, remove them from the lists
} else if (message.type === 'leaving' && message.nodeID === senderUUID) {
leftZone(message.nodeID);
}
};
messageHandlerOperator = function(channel, message, senderUUID, localOnly) {
// Setup
if (channel !== OPERATOR_CHANNEL) {
return;
} else {
message = JSON.parse(message);
}
// Notify the chosen recipient
if (message.type === 'tree power' && senderUUID !== Avatar.sessionUUID ) {
if (operatorsPresent.length > 0){
treePower = message.state;
if (treePower === true) {
if (coinSpawnTimeout){
Script.clearTimeout(coinSpawnTimeout);
coinSpawnTimeout = false;
}
startTree();
updateMarquis("STARTING...");
} else {
if (coinSpawnTimeout){
Script.clearTimeout(coinSpawnTimeout);
coinSpawnTimeout = false;
}
updateMarquis("OUT OF ORDER");
}
}
// Someone entered the zone, add them to a list
}
};
messageHandlerRecipient = function(channel, message, senderUUID, localOnly) {
// Setup
if (channel !== RECIPIENT_CHANNEL) {
return;
} else {
message = JSON.parse(message);
}
// Notify the chosen recipient
if (message.type === 'accept' && senderUUID === recipient.nodeID) {
console.log("money accepted", JSON.stringify(recipient));
if (new Date().getTime() - responseTimeout < SHOW_TIME_LENGTH) {
sendInput(recipient.username, amount);
recipient = null;
targetRecipients = [];
responseTimeout = Number.MAX_VALUE;
}
// Receiver declines
} else if (message.type === 'decline' && senderUUID === recipient.nodeID) {
console.log("money declined");
recipient = null;
targetRecipients = [];
responseTimeout = Number.MAX_VALUE;
// Someone entered the zone, add them to a list
}
};
messageHandlerGiver = function(channel, message, senderUUID, localOnly) {
// Setup
if (channel !== GIVER_CHANNEL) {
return;
} else {
message = JSON.parse(message);
}
// Notify the chosen recipient
if (message.type === 'moneyGiven' && senderUUID === targetGiver.nodeID) {
console.log("money given");
recipient = targetRecipients[targetRecipients.map(function(e) { return e.nodeID; }).indexOf(message.recipientID)];
amount = randomizeHFC();
if (recipient && amount !== 0){
spawnReceiverMessage(amount);
updateMarquis("PLZ WAIT 4 $");
responseTimeout = new Date().getTime();
}
// Receiver accepts
}
};
function updateMarquis(displayText){
Entities.editEntity(populationID, {text: userList.length});
console.log(userList.length, "legnth, and content", JSON.stringify(userList));
marquisMessage = Entities.getEntityProperties(marquisID, ['text']);
if (!displayText){
if ((marquisMessage.text === "OUT OF ORDER" || marquisMessage.text === "BANKRUPT!") && !treePower){
return;
} else if (marquisMessage.text !== "OOH SHINY!" && userList.length < 3) {
Entities.editEntity(marquisID, {text: "MOAR PPL PLZ"});
} else if (marquisMessage.text !== "OOH SHINY!" && userList.length >= 3){
Entities.editEntity(marquisID, {text: "PREPARE 4 $"});
}
} else {
Entities.editEntity(marquisID, {text: displayText});
}
}
// This function is used to allow the AC script to see and change entities
// in the domain.
function allowEntityAccess() {
Entities.setPacketsPerSecond(6000);
EntityViewer.setPosition(SEARCH_CENTER);
EntityViewer.setCenterRadius(SEARCH_AREA);
// This should allow us to see nano-scale entities from great distances
EntityViewer.setVoxelSizeScale(Number.MAX_VALUE);
if (!octreeInterval) {
octreeInterval = Script.setInterval(function() {
EntityViewer.queryOctree();
}, 1000);
}
console.log("This AC script now has access to entities in this domain!");
Script.setTimeout(function(){
try {
if (Entities.getEntityProperties(Entities.findEntitiesByName("Money Tree Counter", SEARCH_CENTER, SEARCH_AREA)[0], ["id"]).id != undefined) {
populationID = Entities.getEntityProperties(Entities.findEntitiesByName("Money Tree Counter", SEARCH_CENTER, SEARCH_AREA)[0], ["id"]).id;
Entities.editEntity(populationID, {text: "--"});
marquisID = Entities.getEntityProperties(Entities.findEntitiesByName("Money Tree Status", SEARCH_CENTER, SEARCH_AREA)[0], ["id"]).id;
Entities.editEntity(marquisID, {text: "BOOTING UP"});
powerButtonSpawner = Entities.findEntitiesByName("Power Button Spawner", SEARCH_CENTER, SEARCH_AREA);
powerButtonSpawner.forEach(function(entityID){Entities.deleteEntity(entityID)});
powerButtonMaterial = Entities.findEntitiesByName("Power Button Material", SEARCH_CENTER, SEARCH_AREA);
powerButtonMaterial.forEach(function(entityID){Entities.deleteEntity(entityID)});
} else {
populationID = Entities.addEntity({
type: "Text",
dimensions: { x: 0.3, y: 0.1854, z: 0.01 },
lineHeight: 0.125,
text: "-",
textColor: {"red": 255, "green": 255, "blue": 255},
backgroundColor: {"red": 0, "green": 0, "blue": 0},
name: "Money Tree Counter",
position: {"x":-17.9620418548584,"y":-10.537128448486328,"z":-10.67333984375},
rotation: {"x":-0.16071832180023193,"y":0.6887953877449036,"z":0.1588284969329834,"w":0.6887840032577515},
visible: true,
collisionless: true,
userData: "{ \"grabbableKey\": { \"grabbable\": false, \"kinematic\": false } }"
});
marquisID = Entities.addEntity({
type: "Text",
dimensions: { x: 0.7585, y: 0.1695, z: 0.01 },
lineHeight: 0.115,
text: "STARTING...",
textColor: {"red": 255, "green": 255, "blue": 255},
backgroundColor: {"red": 0, "green": 0, "blue": 0},
name: "Money Tree Status",
position: {"x":-17.9667,"y":-10.5250,"z":-11.4147},
rotation: {"x":-0.15957793593406677,"y":0.6889334321022034,"z":0.1589823216199875,"w":0.6888881921768188},
visible: true,
collisionless: true,
userData: "{ \"grabbableKey\": { \"grabbable\": false, \"kinematic\": false } }"
});
counterID = Entities.getEntityProperties(populationID, ["id"]).id;
statusID = Entities.getEntityProperties(marquisID, ["id"]).id;
console.log("[MONEY TREE] created stuff", counterID, statusID);
}
} catch (e) {
console.log("[MONEY TREE] could not find or create anything", e);
}
Messages.subscribe(MONEY_TREE_CHANNEL);
Messages.subscribe(OPERATOR_CHANNEL);
Messages.subscribe(GIVER_CHANNEL);
Messages.subscribe(RECIPIENT_CHANNEL);
Messages.messageReceived.connect(messageHandler);
Messages.messageReceived.connect(messageHandlerOperator);
Messages.messageReceived.connect(messageHandlerRecipient);
Messages.messageReceived.connect(messageHandlerGiver);
startTree();
}, 10000);
}
// This function checks to make sure that the entity server exists
// and that the AC script has Rez permissions.
// If one or both of those things is false, we'll check again in 5 seconds.
function maybeAllowEntityAccess() {
console.log("Attempting to give this AC script entity access...");
if (Entities.serversExist() && Entities.canRez()) {
allowEntityAccess();
} else {
if (!Entities.canRez()) {
console.log("This AC script doesn't have rez permissions!");
}
Script.setTimeout(maybeAllowEntityAccess, 5000);
}
}
// This function will be called on startup.
function startup() {
maybeAllowEntityAccess();
}
function bankerOverlay(uuid, remove){
if (remove) {
try {
var powerButtonSpawner = Entities.findEntitiesByName("Power Button Spawner", SEARCH_CENTER, SEARCH_AREA);
powerButtonSpawner.forEach(function(entityID){
var entityData = Entities.getEntityProperties(entityID, ['userData']);
userData = JSON.parse(entityData.userData);
var validID = userData.bankerID;
if (validID === uuid) {
Entities.deleteEntity(entityID);
}
});
var powerButtonMaterial = Entities.findEntitiesByName("Power Button Material", SEARCH_CENTER, SEARCH_AREA);
powerButtonMaterial.forEach(function(entityID){
var entityData2 = Entities.getEntityProperties(entityID, ['userData']);
userData = JSON.parse(entityData2.userData);
var validID2 = userData.bankerID;
if (validID2 === uuid) {
Entities.deleteEntity(entityID);
}
});
} catch (e){
console.log("error removing overlay", e);
}
} else {
var userData = { bankerID: uuid, power: treePower };
powerButtonSpawner = Entities.addEntity({
type: "Box",
dimensions: { x: 0.5, y: 0.5, z: 0.5 },
name: "Power Button Spawner",
script: "https://hifi-content.s3.amazonaws.com/brosche/DomainContent/Hub/MoneyTree/moneyTreeBankerClient.js",
userData: JSON.stringify(userData),
position: { x: -16.9779, y: -9.132, z: -10.7944 },
visible: false,
collisionless: true
});
}
}
// If someone leaves the domain from within the tree zone,
function leftZone(uuid){
var isOperator = operatorsPresent[operatorsPresent.map(function(e) { return e.nodeID; }).indexOf(uuid)];
var isUser = userList[userList.map(function(e) { return e.nodeID; }).indexOf(uuid)];
if (isOperator && operatorsPresent.indexOf(isOperator) !== -1) {
console.log("banker left zone", isOperator.username);
bankerOverlay(uuid, true);
operatorsPresent.splice(operatorsPresent.indexOf(isOperator),1)[0];
}
if (isUser && userList.indexOf(isUser) !== -1){
console.log("user left zone", isUser.username)
userList.splice(userList.indexOf(isUser), 1)[0];
}
updateMarquis();
}
function spawnReceiverMessage(amount){
print("[MONEY TREE] spawing reciever message", JSON.stringify(recipient));
if (recipient) {
Messages.sendMessage(OPERATOR_CHANNEL, JSON.stringify({
type: "given",
receiver: recipient.username
}));
var userData = {
receiverID: recipient.nodeID,
amount: amount
};
var avatar = AvatarList.getAvatar(recipient.nodeID);
Entities.addEntity({
type: "Box",
dimensions: { x: 0.5, y: 0.5, z: 0.5 },
name: "Tree Gift Receipt",
script: "https://hifi-content.s3.amazonaws.com/brosche/DomainContent/Hub/MoneyTree/moneyTreeReceiverClient.js",
userData: JSON.stringify(userData),
lifetime: 5,
position: Vec3.sum(avatar.position, Vec3.multiplyQbyV(avatar.orientation, { x: -2.5, y: 0, z: -5 })),
visible: false,
collisionless: true,
parentID: recipient
});
try {
Entities.addEntity({
lifetime: 5,
collidesWith: "",
collisionMask: 0,
collisionless: true,
position: Vec3.sum(avatar.position, Vec3.multiplyQbyV(avatar.orientation, { x: 0, y: 0, z: -1 })),
dimensions: {
x: 0.15,
y: 0.15,
z: 0.15
},
isEmitting: true,
name: "Coin Particle",
type: "ParticleEffect",
userData: "{\"grabbableKey\":{\"grabbable\":false}}",
lifespan: 0.5,
maxParticles: 10,
textures: "https://hifi-content.s3.amazonaws.com/Experiences/Releases/events/lastAvatarStandingTrivia/2019-01-07_10-45-00/entities/pictures/coin.png",
emitRate: 10,
emitSpeed: 1.5,
speedSpread: 2,
emitDimensions: {
x: 0,
y: 0,
z: 0
},
emitOrientation: {
x: -0.707,
y: 0,
z: 0,
w: 0.707
},
emitterShouldTrail: false,
particleRadius: 0.15,
radiusSpread: 0,
radiusStart: 0,
radiusFinish: 0.15,
color:{
red:255,
blue:255,
green:255
},
colorSpread:{
red:0,
blue:0,
green:0
},
colorStart:{
red:255,
blue:255,
green:255
},
colorFinish:{
red:255,
blue:255,
green:255
},
emitAcceleration:{
x:0,
y:-10,
z:1},
accelerationSpread:{
x:5,
y:3,
z:5
},
alpha: 1,
alphaSpread: 0,
alphaStart: 1,
alphaFinish: 1,
particleSpin: 0,
spinSpread: 0,
spinStart: 0,
spinFinish: 0,
rotateWithEntity: true,
polarStart: 0,
polarFinish: 0,
azimuthStart: -2.9321532249450684,
azimuthFinish: 0.5235987901687622
});
} catch (e) {
print("[MONEY TREE] error spawning coin particle", e);
}
}
}
function randomizeHFC(){
var funds = true;
var rand = gaussian(AVERAGE_HFC_AMOUNT, STANDARD_DEVIATION);
var listLength =Math.sqrt(userList.length);
var amount = Math.ceil(rand*listLength) - Math.ceil(rand*listLength) % 5;
if (!funds){
updateMarquis("BANKRUPT!");
Script.clearTimeout(coinSpawnTimeout);
coinSpawnTimeout = false;
treePower = false;
Messages.sendMessage(OPERATOR_CHANNEL, JSON.stringify({
type: "tree power",
state: treePower
}));
return 0;
}
if (amount >= 50){
amount = 50;
} else if (amount <= 5){
amount = 5;
}
return amount;
}
function generateRandomIntervals(){
for (var i = 0; i < 10; i++){
var interval = gaussian(AVERAGE_INTERVAL, 1) * SHOW_TIME_LENGTH;
randomIntervals.push(
interval > SHOW_TIME_LENGTH ? interval : SHOW_TIME_LENGTH
);
}
}
function createCoinSpawner() {
if (targetRecipients[0] == null){
return;
} else if (targetRecipients.length < 2){
return;
} else {
Messages.sendMessage(OPERATOR_CHANNEL, JSON.stringify({
type: "coins",
giver: targetGiver.username
}));
updateMarquis("OOH SHINY!");
for (var i = 0; i < targetRecipients.length; i++){
var avatar = AvatarList.getAvatar(targetRecipients[i].nodeID);
var sum = Vec3.sum(avatar.position, Vec3.UP);
var userData = {
giverID: targetGiver.nodeID
};
coinSpawner[i] = Entities.addEntity({
type: "Box",
dimensions: { x: 0.5, y: 0.5, z: 0.5 },
name: "Money Tree Gift",
script: "https://hifi-content.s3.amazonaws.com/brosche/DomainContent/Hub/MoneyTree/moneyTreeClient.js",
userData: JSON.stringify(userData),
lifetime: 60,
position: sum,
visible: false,
collisionless: true,
parentID: avatar.sessionUUID
});
}
}
}
function pickAGiver(){
userListGiverIndex = randInt(0, userList.length-1);
if (userListGiverIndex < 0){
return;
} else {
if (targetGiver){
if (userList[userListGiverIndex].username === ""){
userList.splice(userListGiverIndex, 1)[0];
if (userListGiverIndex >= userList.length){
userListGiverIndex = randInt(0, userList.length-1);
}
}
if (targetGiver.username !== userList[userListGiverIndex].username){
targetGiver = userList[userListGiverIndex];
} else {
userListGiverIndex = randInt(0, userList.length-1);
targetGiver = userList[userListGiverIndex];
}
} else {
targetGiver = userList[userListGiverIndex];
}
}
console.log(" giver is", targetGiver.username);
}
function pickRecipients(){
targetRecipients = [];
tempList = [];
tempList = userList.slice();
tempList.splice(userListGiverIndex, 1)[0];
for (var i = 0; i < tempList.length; i++) {
if (tempList[i].staff === true) {
tempList.splice(i,1)[0];
i--;
}
}
if (tempList.length < 2) {
Entities.editEntity(marquisID, {text: "MOAR PPL PLZ"});
return;
}
var recipientCount = (tempList.length > RECIPIENT_MAX) ? RECIPIENT_MAX : tempList.length;
for (var i = 0; i < recipientCount; i++){
var index = randInt(0, tempList.length-1);
targetRecipients.push(tempList.splice(index-i, 1)[0]);
}
console.log("recipients: ", JSON.stringify(targetRecipients));
}
function randFloat(low, high) {
return low + Math.random() * (high - low);
}
function randInt(low, high) {
return Math.floor(randFloat(low, high));
}
// returns a gaussian random function with the given mean and stdev.
function gaussian(mean, stdev) {
var y2;
var useLast = false;
var y1;
if (useLast) {
y1 = y2;
useLast = false;
} else {
var x1, x2, w;
do {
x1 = 2.0 * Math.random() - 1.0;
x2 = 2.0 * Math.random() - 1.0;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0);
w = Math.sqrt((-2.0 * Math.log(w))/w);
y1 = x1 * w;
y2 = x2 * w;
useLast = true;
}
var retval = mean + stdev * y1;
if (retval > 0) {
return retval;
}
return -retval;
}
function sendInput(recipientUsername, amount) {
var paramString = encodeURLParams({
date: new Date().toLocaleString(),
recipientUsername: recipientUsername,
amount: amount
});
var request = new XMLHttpRequest();
request.open('GET', googleURL + "?" + paramString);
request.timeout = 10000;
request.send();
}
function encodeURLParams(params) {
var paramPairs = [];
for (var key in params) {
paramPairs.push(key + "=" + params[key]);
}
return paramPairs.join("&");
}
function cleanUpEntities(){
try {
var avatarsInDomain = AvatarList.getAvatarIdentifiers();
operatorsPresent.forEach(function(index){
var count = 0;
avatarsInDomain.forEach(function(nodeID){
if(index.nodeID === nodeID){
count += 1;
}
});
if (count < 1) {
bankerOverlay(index, true);
operatorsPresent.splice(operatorsPresent.indexOf(index),1)[0];
}
});
userList.forEach(function(index){
var count = 0;
avatarsInDomain.forEach(function(nodeID){
if(index.nodeID === nodeID){
count += 1;
}
});
if (count < 1) {
userList.splice(userList.indexOf(index),1)[0];
}
});
var extraCoins = Entities.findEntitiesByName("Money Tree Gift", SEARCH_CENTER, SEARCH_AREA);
if (extraCoins.length > 0){
extraCoins.forEach(function(entityID){
Entities.deleteEntity(entityID);
});
extraCoins = [];
}
var extraButtons = Entities.findEntitiesByName("Power Button Spawner", SEARCH_CENTER, SEARCH_AREA);
if (extraButtons.length > 0 && operatorsPresent.length === 0){
extraButtons.forEach(function(entityID){
Entities.deleteEntity(entityID);
});
extraButtons = [];
}
var extraButtons = Entities.findEntitiesByName("Power Button Material", SEARCH_CENTER, SEARCH_AREA);
if (extraButtons.length > 0 && operatorsPresent.length === 0){
extraButtons.forEach(function(entityID){
Entities.deleteEntity(entityID);
});
extraButtons = [];
}
updateMarquis();
} catch (e) {
print("[MONEY TREE] entity sweep failed.");
return;
}
}
function startTree(){
console.log("The next selection begins in ", (randomIntervals[randomIntervals.length-1]/1000).toFixed(0));
var message = JSON.stringify("The next selection begins in " +
(randomIntervals[randomIntervals.length-1]/1000).toFixed(0) + " seconds");
Messages.sendMessage(OPERATOR_CHANNEL, JSON.stringify({
type: "time",
message: message
}));
coinSpawnTimeout = Script.setTimeout(function(){
cleanUpEntities();
if(randomIntervals.length < 1){
generateRandomIntervals();
}
if (userList.length >= RECIPIENT_MAX){
pickAGiver();
pickRecipients();
if (targetRecipients.length > 1) {
createCoinSpawner();
}
} else {
updateMarquis("MOAR PPL PLZ");
}
startTree();
}, randomIntervals.pop());
}
function appEnding() {
cleanUpEntities();
if (coinSpawnTimeout){
Script.clearTimeout(coinSpawnTimeout);
coinSpawnTimeout = false;
}
if (octreeInterval){
Script.clearInterval(octreeInterval);
octreeInterval = false;
}
Messages.unsubscribe(MONEY_TREE_CHANNEL);
Messages.unsubscribe(OPERATOR_CHANNEL);
Messages.unsubscribe(GIVER_CHANNEL);
Messages.unsubscribe(RECIPIENT_CHANNEL);
Messages.messageReceived.disconnect(messageHandler);
Messages.messageReceived.disconnect(messageHandlerOperator);
Messages.messageReceived.disconnect(messageHandlerRecipient);
Messages.messageReceived.disconnect(messageHandlerGiver);
}
AvatarList.avatarRemovedEvent.connect(leftZone);
Script.scriptEnding.connect(appEnding);
startup();