230 lines
5.0 KiB
JavaScript
230 lines
5.0 KiB
JavaScript
const {
|
|
getCollections,
|
|
getUnixTime
|
|
} = require("../utils/cookieEconomy");
|
|
|
|
const {
|
|
activateBoss,
|
|
failBoss,
|
|
cancelBossAndRefund
|
|
} = require("../utils/cookieBoss");
|
|
|
|
|
|
/*
|
|
* How often we check persistent boss timers.
|
|
*
|
|
* Discord timestamps handle the visible countdown,
|
|
* so checking once per minute is plenty.
|
|
*/
|
|
const CHECK_INTERVAL = 60 * 1000;
|
|
|
|
|
|
/*
|
|
* Your index.js automatically loads every file
|
|
* inside /handlers and passes the Discord client:
|
|
*
|
|
* require(`./handlers/${handler}`)(client)
|
|
*/
|
|
module.exports = (client) => {
|
|
|
|
/*
|
|
* Run shortly after startup.
|
|
*
|
|
* This catches boss events whose timers expired
|
|
* while ShaiBot was offline/restarting.
|
|
*/
|
|
setTimeout(() => {
|
|
processBossEvents(client);
|
|
}, 5000);
|
|
|
|
|
|
/*
|
|
* Persistent boss event watcher.
|
|
*/
|
|
setInterval(() => {
|
|
processBossEvents(client);
|
|
}, CHECK_INTERVAL);
|
|
|
|
|
|
console.log(
|
|
"[CookieBoss] Boss event watcher initialized"
|
|
);
|
|
};
|
|
|
|
|
|
/*
|
|
* Check all currently pending Cookie Boss events.
|
|
*/
|
|
async function processBossEvents(client) {
|
|
try {
|
|
const {
|
|
db
|
|
} = getCollections();
|
|
|
|
|
|
const events =
|
|
db.collection(
|
|
"items_events"
|
|
);
|
|
|
|
|
|
const now =
|
|
getUnixTime();
|
|
|
|
|
|
/*
|
|
* ==========================================
|
|
* JOINING PHASE
|
|
* ==========================================
|
|
*
|
|
* Recruitment lasts for 30 minutes.
|
|
*
|
|
* If 5+ players joined:
|
|
* start the battle automatically.
|
|
*
|
|
* If fewer than 5 joined:
|
|
* cancel the boss and refund everyone.
|
|
*/
|
|
|
|
const joiningEvents =
|
|
await events
|
|
.find({
|
|
eventType:
|
|
"CookieBoss",
|
|
|
|
state:
|
|
"Joining",
|
|
|
|
joinUntil: {
|
|
$lte: now
|
|
}
|
|
})
|
|
.toArray();
|
|
|
|
|
|
for (
|
|
const event
|
|
of joiningEvents
|
|
) {
|
|
const participantCount =
|
|
Object.keys(
|
|
event.participants ?? {}
|
|
).length;
|
|
|
|
|
|
console.log(
|
|
`[CookieBoss] Recruitment expired for ${event.eventId} ` +
|
|
`(${participantCount}/${event.minimumParticipants} players)`
|
|
);
|
|
|
|
|
|
/*
|
|
* Enough players joined.
|
|
*
|
|
* Start the fight automatically.
|
|
*/
|
|
if (
|
|
participantCount >=
|
|
event.minimumParticipants
|
|
) {
|
|
const started =
|
|
await activateBoss(
|
|
client,
|
|
event.eventId
|
|
);
|
|
|
|
|
|
if (started) {
|
|
console.log(
|
|
`[CookieBoss] Battle ${event.eventId} started automatically`
|
|
);
|
|
}
|
|
|
|
|
|
continue;
|
|
}
|
|
|
|
|
|
/*
|
|
* Not enough players.
|
|
*
|
|
* Nobody actually entered combat,
|
|
* so refund all committed Cookies.
|
|
*/
|
|
await cancelBossAndRefund(
|
|
client,
|
|
event.eventId
|
|
);
|
|
|
|
|
|
console.log(
|
|
`[CookieBoss] Battle ${event.eventId} cancelled and refunded`
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* ==========================================
|
|
* ACTIVE BATTLES
|
|
* ==========================================
|
|
*
|
|
* If the battle timer expires while the
|
|
* boss still has HP remaining, the raid fails.
|
|
*
|
|
* All Cookies held in the encounter escrow
|
|
* are transferred to the ShaiBot vault.
|
|
*/
|
|
|
|
const activeEvents =
|
|
await events
|
|
.find({
|
|
eventType:
|
|
"CookieBoss",
|
|
|
|
state:
|
|
"Active",
|
|
|
|
battleEndsAt: {
|
|
$lte: now
|
|
},
|
|
|
|
"boss.health": {
|
|
$gt: 0
|
|
}
|
|
})
|
|
.toArray();
|
|
|
|
|
|
for (
|
|
const event
|
|
of activeEvents
|
|
) {
|
|
console.log(
|
|
`[CookieBoss] Battle ${event.eventId} expired ` +
|
|
`with ${event.boss.health}/${event.boss.maxHealth} HP remaining`
|
|
);
|
|
|
|
|
|
await failBoss(
|
|
client,
|
|
event.eventId
|
|
);
|
|
|
|
|
|
console.log(
|
|
`[CookieBoss] Battle ${event.eventId} failed`
|
|
);
|
|
}
|
|
|
|
} catch (error) {
|
|
/*
|
|
* Never let an exception kill the interval.
|
|
*
|
|
* The next watcher tick will simply try again.
|
|
*/
|
|
console.error(
|
|
"[CookieBoss] Boss watcher error:",
|
|
error
|
|
);
|
|
}
|
|
} |