Implemented Capture The Flag
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
"filename": "capture_the_flag.png",
|
||||
"description": "This badge is stolen by successful attacks. It is automatically set as your active badge, and you can't change it until it is lost; it also sets your name to yellow, so everyone knows you have it. Only one exists.",
|
||||
"visible": true,
|
||||
"unlockable": null
|
||||
"unlockable": false
|
||||
},
|
||||
"Combat Master": {
|
||||
"filename": "combat_master.png",
|
||||
|
||||
@@ -70,6 +70,16 @@ const selectActiveBadge = (connection) => (req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
//if Capture The Flag is active, don't change the active badge; return badges owned
|
||||
if (owned["Capture The Flag"]) {
|
||||
getBadgesOwned(connection, req.body.id, (err, results) => {
|
||||
if (err) throw err;
|
||||
res.status(200).json(results);
|
||||
res.end();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
//zero out the user's selection
|
||||
let query = 'UPDATE badges SET active = FALSE WHERE accountId = ?;';
|
||||
connection.query(query, [req.body.id], (err) => {
|
||||
@@ -108,6 +118,33 @@ const rewardBadge = (connection, id, badgeName, cb) => {
|
||||
});
|
||||
};
|
||||
|
||||
const captureTheFlag = (connection, attackerId, defenderId, skip, cb) => {
|
||||
//if this is a no-op
|
||||
if (skip) {
|
||||
return cb(false);
|
||||
}
|
||||
|
||||
//check to see if the flag belongs to the defender
|
||||
let query = 'SELECT * FROM badges WHERE accountId = ? AND name = "Capture The Flag" LIMIT 1;';
|
||||
connection.query(query, [defenderId], (err, results) => {
|
||||
if (err) throw err;
|
||||
|
||||
//does the defender have this badge? If not, return
|
||||
if (results.length === 0) {
|
||||
return cb(false);
|
||||
}
|
||||
|
||||
//move the badge between accounts
|
||||
let query = 'INSERT INTO badges (id, accountId, name, active) VALUES (?, ?, "Capture The Flag", FALSE) ON DUPLICATE KEY UPDATE accountId = VALUES(accountId), active = FALSE;';
|
||||
connection.query(query, [results[0].id, attackerId], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
log('Badge moved', attackerId, defenderId);
|
||||
cb(true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const runBadgeTicks = (connection) => {
|
||||
//Combat Master
|
||||
let combatMasterBadgeTickJob = new CronJob('0 * * * * *', () => { //once a minute - combats aren't that fast
|
||||
@@ -187,5 +224,6 @@ module.exports = {
|
||||
ownedRequest: ownedRequest,
|
||||
selectActiveBadge: selectActiveBadge,
|
||||
rewardBadge: rewardBadge,
|
||||
captureTheFlag: captureTheFlag,
|
||||
runBadgeTicks: runBadgeTicks
|
||||
};
|
||||
+28
-24
@@ -9,6 +9,7 @@ let { logDiagnostics } = require('./diagnostics.js');
|
||||
let { log } = require('../common/utilities.js');
|
||||
|
||||
let { getEquipmentStatistics, isAttacking, logActivity } = require('./utilities.js');
|
||||
let { captureTheFlag } = require('./badges.js');
|
||||
|
||||
const attackRequest = (connection) => (req, res) => {
|
||||
//verify the attacker's credentials (only the attacker can launch an attack)
|
||||
@@ -234,39 +235,42 @@ const runCombatTick = (connection) => {
|
||||
let spoilsGold = Math.floor(results[0].gold * (victor === 'attacker' ? 0.1 : 0.02));
|
||||
let attackerCasualties = Math.floor((pendingCombat.attackingUnits >= 10 ? pendingCombat.attackingUnits : 0) * (victor === 'attacker' ? Math.random() / 5 : Math.random() / 2));
|
||||
|
||||
//save the combat
|
||||
let query = 'INSERT INTO pastCombat (eventTime, attackerId, defenderId, attackingUnits, defendingUnits, undefended, victor, spoilsGold, attackerCasualties) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);';
|
||||
connection.query(query, [pendingCombat.eventTime, pendingCombat.attackerId, pendingCombat.defenderId, pendingCombat.attackingUnits, defendingUnits, undefended, victor, spoilsGold, attackerCasualties], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
//update the attacker profile
|
||||
let query = 'UPDATE profiles SET gold = gold + ?, soldiers = soldiers - ? WHERE accountId = ?;';
|
||||
connection.query(query, [spoilsGold, attackerCasualties, pendingCombat.attackerId], (err) => {
|
||||
//capture the flag logic
|
||||
captureTheFlag(connection, pendingCombat.attackerId, pendingCombat.defenderId, victor !== 'attacker', (flagCaptured) => {
|
||||
//save the combat
|
||||
let query = 'INSERT INTO pastCombat (eventTime, attackerId, defenderId, attackingUnits, defendingUnits, undefended, victor, spoilsGold, attackerCasualties, flagCaptured) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);';
|
||||
connection.query(query, [pendingCombat.eventTime, pendingCombat.attackerId, pendingCombat.defenderId, pendingCombat.attackingUnits, defendingUnits, undefended, victor, spoilsGold, attackerCasualties, flagCaptured], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
//update the defender profile
|
||||
let query = 'UPDATE profiles SET gold = gold - ? WHERE accountId = ?;';
|
||||
connection.query(query, [spoilsGold, pendingCombat.defenderId], (err) => {
|
||||
//update the attacker profile
|
||||
let query = 'UPDATE profiles SET gold = gold + ?, soldiers = soldiers - ? WHERE accountId = ?;';
|
||||
connection.query(query, [spoilsGold, attackerCasualties, pendingCombat.attackerId], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
//remove used consumables (moved because callback hell is rediculous)
|
||||
removeConsumables(connection, attackerConsumables, pendingCombat.attackingUnits);
|
||||
removeConsumables(connection, defenderConsumables, defendingUnits);
|
||||
|
||||
//delete the pending combat
|
||||
let query = 'DELETE FROM pendingCombat WHERE id = ?;';
|
||||
connection.query(query, [pendingCombat.id], (err) => {
|
||||
//update the defender profile
|
||||
let query = 'UPDATE profiles SET gold = gold - ? WHERE accountId = ?;';
|
||||
connection.query(query, [spoilsGold, pendingCombat.defenderId], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
log('Combat executed', pendingCombat.attackerId, pendingCombat.defenderId, victor, spoilsGold);
|
||||
logDiagnostics(connection, 'death', attackerCasualties);
|
||||
//remove used consumables (moved because callback hell is rediculous)
|
||||
removeConsumables(connection, attackerConsumables, pendingCombat.attackingUnits);
|
||||
removeConsumables(connection, defenderConsumables, defendingUnits);
|
||||
|
||||
//clean the database
|
||||
let query = 'DELETE FROM equipment WHERE quantity <= 0;';
|
||||
connection.query(query, (err) => {
|
||||
//delete the pending combat
|
||||
let query = 'DELETE FROM pendingCombat WHERE id = ?;';
|
||||
connection.query(query, [pendingCombat.id], (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
log('Cleaned database', 'Combat consumables');
|
||||
log('Combat executed', pendingCombat.attackerId, pendingCombat.defenderId, victor, spoilsGold);
|
||||
logDiagnostics(connection, 'death', attackerCasualties);
|
||||
|
||||
//clean the database
|
||||
let query = 'DELETE FROM equipment WHERE quantity <= 0;';
|
||||
connection.query(query, (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
log('Cleaned database', 'Combat consumables');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,6 +46,12 @@ const getBadgesOwned = (connection, id, cb) => {
|
||||
ret[results[key].name] = { active: results[key].active };
|
||||
});
|
||||
|
||||
//NOTE: check for "Capture The Flag" badge, force it to be the active badge
|
||||
if ("Capture The Flag" in ret) {
|
||||
Object.keys(ret).map((key) => ret[key].active = false);
|
||||
ret["Capture The Flag"].active = true;
|
||||
}
|
||||
|
||||
return cb(undefined, { 'owned': ret });
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user