@@ -97,7 +98,7 @@
{{ w.description }} They produce {{ w.rate }} data per second.
-
+
@@ -111,7 +112,7 @@
{{ u.description }}
-
+
@@ -191,6 +192,9 @@
+
+
+
diff --git a/js/achievements.js b/js/achievements.js
index 27ec3f0..8879c69 100644
--- a/js/achievements.js
+++ b/js/achievements.js
@@ -74,7 +74,7 @@ var achievements =
achievements[type][subtype] >= achievements.list[i].threshold
)
{
- console.log(achievements.list[i].threshold, achievements[type][subtype]);
+ //console.log(achievements.list[i].threshold, achievements[type][subtype]);
achievements.list[i].completed = true;
achievements.displayAchievement(i);
diff --git a/js/game.js b/js/game.js
index f499add..d894d5c 100644
--- a/js/game.js
+++ b/js/game.js
@@ -1,203 +1,25 @@
'use strict';
(function() {
- var loadFile = function(filename) {
- var res;
- $.ajax({
- async: false,
- url : filename,
- success : function(data) {
- res = data;
- }
- });
- return res;
- }
+ var lab = GameObjects.lab;
+ var research = GameObjects.research;
+ var workers = GameObjects.workers;
+ var upgrades = GameObjects.upgrades;
- var showModal = function(title, text) {
- var $modal = $('#infoBox');
- $modal.find('#infoBoxLabel').html(title);
- $modal.find('.modal-body').html(text);
- $modal.modal({show: true});
- };
-
- var lab = {
- name: 'My Awesome Lab',
- detector: {
- rate: 1
- },
- factor: {
- rate: 5
- },
- data: 0,
- reputation: 0,
- money: 0,
- getGrant: function () {
- var addition = this.reputation * this.factor.rate; // TODO: adjust factor
- this.money += addition;
- showUpdateValue("#update-funding", formatNiceNumber(addition));
- achievements.update('count', 'money', addition);
- },
- acquire: function(amount) {
- this.data += amount;
- achievements.update('count', 'data', amount);
- showUpdateValue("#update-data", formatNiceNumber(amount));
- },
- research: function(cost, reputation) {
- if (this.data >= cost) {
- this.data -= cost;
- this.reputation += reputation;
- achievements.update('count', 'reputation', reputation);
- showUpdateValue("#update-data", formatNiceNumber(-cost));
- showUpdateValue("#update-reputation", formatNiceNumber(reputation));
- return true;
- }
- return false;
- },
- buy: function(cost) {
- if (this.money >= cost) {
- this.money -= cost;
- showUpdateValue("#update-funding", formatNiceNumber(-cost));
- return true;
- }
- return false;
- },
- sell: function(cost) {
- this.money += cost;
- }
- };
-
- var research = loadFile('json/research.json');
achievements.addResearch(research);
- research.map(function(item) {
- item.level = 0;
- item.is_visible = function() {
- return this.level > 0 || lab.data >= this.cost * .7;
- };
- item.is_available = function() {
- return lab.data >= this.cost;
- };
- item.research = function() {
- if (lab.research(this.cost, this.reputation)) {
- achievements.update('count', 'dataSpent', this.cost);
- this.level++;
- this.cost = Math.round(this.cost * this.cost_increase);
- achievements.update('research', this.name, 1);
- }
- };
- item.getInfo = function() {
- if (!this._info) {
- this._info = loadFile(this.info);
- }
- return this._info;
- },
- item.showInfo = function() {
- showModal(this.name, this.getInfo());
- };
- });
-
- var workers = loadFile('json/workers.json');
achievements.addWorkers(workers);
- workers.map(function(worker) {
- worker.hired = 0;
- worker.is_visible = function() {
- return this.hired > 0 || lab.money >= this.cost * .7;
- };
- worker.is_available = function() {
- return lab.money >= this.cost;
- };
- worker.hire = function() {
- if (lab.buy(this.cost)) {
- achievements.update('count', 'moneyWorkers', this.cost);
- this.hired++;
- this.cost = Math.round(this.cost * this.cost_increase);
- achievements.update('workers', this.name, 1);
- achievements.update('count', 'workers', 1);
- }
- };
- });
-
- var upgrades = loadFile('json/upgrades.json');
- upgrades.map(function(upgrade) {
- upgrade.getReceiver = function() {
- if (this.type === "detector") {
- return lab.detector;
- } else if (this.type === "reputation"){
- return lab.factor;
- }
- else {
- var context;
- if (this.type === "research") { context = research; }
- else if (this.type === "hr") { context = workers; }
- else { return null; }
- for (var i = 0; i < context.length; i++) {
- if (context[i].name === this.receiver) {
- return context[i];
- }
- }
- return null;
- }
- };
- upgrade.hasReceiver = function() {
- if (this.type === "detector") {
- return true;
- }
- if (this.type === "reputation") {
- return true;
- }
- var rec = this.getReceiver();
- if (this.type === "research") {
- return rec.level > 0;
- } else if (this.type === "hr") {
- return rec.hired > 0;
- }
- return false;
- };
- upgrade.is_visible = function() {
- return !this.used && this.hasReceiver() && lab.money >= this.cost * .7;
- };
- upgrade.is_available = function() {
- return !this.used && this.hasReceiver() && lab.money >= this.cost;
- };
- upgrade.buy = function() {
- if (!this.used && lab.buy(this.cost)) {
- achievements.update('count', 'moneyUpgrades', this.cost);
- this.used = true;
- var rec = this.getReceiver();
- if (rec) {
- rec[this.property] = rec[this.property] * this.factor + this.constant;
- }
- }
- };
- });
-
+
var app = angular.module('particleClicker', []);
+ app.filter('niceNumber', ['$filter', function($filter) {
+ return Helpers.formatNumberPostfix;
+ }]);
+
app.filter('currency', ['$filter', function($filter) {
return function(input) {
return 'JTN ' + $filter('niceNumber')(input);
};
}]);
-
- function formatNiceNumber(number) {
- var abs = Math.abs(number);
- if (abs >= Math.pow(10, 12)) {
- number = (number / Math.pow(10, 12)).toFixed(1) + "T";
- } else if (abs >= Math.pow(10, 9)) {
- number = (number / Math.pow(10, 9)).toFixed(1) + "B";
- } else if (abs >= Math.pow(10, 6)) {
- number = (number / Math.pow(10, 6)).toFixed(1) + "M";
- } else if (abs >= Math.pow(10, 3)) {
- number = (number / Math.pow(10, 3)).toFixed(1) + "k";
- } else {
- number = number.toFixed(0);
- }
- return number;
- }
-
- app.filter('niceNumber', ['$filter', function($filter) {
- return formatNiceNumber;
- }]);
-
app.filter('reverse', ['$filter', function($filter) {
return function(items) {
return items.slice().reverse();
@@ -209,6 +31,8 @@
lab.acquire(lab.detector.rate);
detector.addEvent();
achievements.update('count', 'clicks', 1);
+ achievements.update('count', 'data', lab.detector.rate);
+ UI.showUpdateValue("#update-data", lab.detector.rate);
return false;
};
});
@@ -217,12 +41,14 @@
this.lab = lab;
this.showDetectorInfo = function() {
if (!this._detectorInfo) {
- this._detectorInfo = loadFile('html/detector.html');
+ this._detectorInfo = Helpers.loadFile('html/detector.html');
}
- showModal('Detector', this._detectorInfo);
+ UI.showModal('Detector', this._detectorInfo);
};
$interval(function() { // one tick
- lab.getGrant();
+ var grant = lab.getGrant();
+ achievements.update('count', 'money', grant);
+ UI.showUpdateValue("#update-funding", grant);
var sum = 0;
for (var i = 0; i < workers.length; i++) {
sum += workers[i].hired * workers[i].rate;
@@ -234,14 +60,38 @@
app.controller('ResearchController', function() {
this.research = research;
+ this.doResearch = function(item) {
+ var cost = item.research();
+ if (cost > 0) {
+ achievements.update('count', 'reputation', item.reputation);
+ achievements.update('count', 'dataSpent', cost);
+ achievements.update('research', item.name, 1);
+ UI.showUpdateValue("#update-data", -cost);
+ UI.showUpdateValue("#update-reputation", item.reputation);
+ }
+ };
});
app.controller('HRController', function() {
this.workers = workers;
+ this.hire = function(worker) {
+ var cost = worker.hire();
+ if (cost > 0) {
+ achievements.update('count', 'moneyWorkers', cost);
+ achievements.update('workers', worker.name, 1);
+ achievements.update('count', 'workers', 1);
+ UI.showUpdateValue("#update-funding", cost);
+ }
+ };
});
app.controller('UpgradesController', function() {
this.upgrades = upgrades;
+ this.upgrade = function(upgrade) {
+ if (upgrade.buy()) {
+ achievements.update('count', 'moneyUpgrades', upgrade.cost);
+ }
+ }
});
app.controller('AchievementsController', function() {
@@ -249,5 +99,11 @@
this.achievementsAll = achievements.list;
});
- achievements.setList(loadFile('json/achievements.json'));
+ achievements.setList(Helpers.loadFile('json/achievements.json'));
+
+ // Activate auto-saving every 10 seconds
+ setInterval(function () {
+ GameObjects.saveAll();
+ console.log('The game has been saved.');
+ }, 10000);
})();
diff --git a/js/gameobjects.js b/js/gameobjects.js
new file mode 100644
index 0000000..c0c8556
--- /dev/null
+++ b/js/gameobjects.js
@@ -0,0 +1,187 @@
+'use strict';
+
+/** Define all objects used in the game.
+ * They can be either loaded from localStorage or from JSON in case nothing is
+ * found in the localStorage.
+ */
+var GameObjects = (function() {
+ /** Lab
+ */
+ var labPrototype = {
+ name: 'My Awesome Lab',
+ detector: {
+ rate: 1
+ },
+ factor: {
+ rate: 5
+ },
+ data: 0,
+ reputation: 0,
+ money: 0,
+ getGrant: function () {
+ var addition = this.reputation * this.factor.rate;
+ this.money += addition;
+ return addition;
+ },
+ acquire: function(amount) {
+ this.data += amount;
+ },
+ research: function(cost, reputation) {
+ if (this.data >= cost) {
+ this.data -= cost;
+ this.reputation += reputation;
+ return true;
+ }
+ return false;
+ },
+ buy: function(cost) {
+ if (this.money >= cost) {
+ this.money -= cost;
+ return true;
+ }
+ return false;
+ },
+ sell: function(cost) {
+ this.money += cost;
+ }
+ };
+ var lab = $.extend({}, labPrototype, ObjectStorage.load('lab'));
+
+ /** Research
+ */
+ var researchPrototype = {
+ level: 0,
+ is_visible: function() {
+ return this.level > 0 || lab.data >= this.cost * .7;
+ },
+ is_available: function() {
+ return lab.data >= this.cost;
+ },
+ research: function() {
+ if (lab.research(this.cost, this.reputation)) {
+ this.level++;
+ var oldCost = this.cost;
+ this.cost = Math.round(this.cost * this.cost_increase);
+ return oldCost;
+ }
+ return -1;
+ },
+ getInfo: function() {
+ if (!this._info) {
+ this._info = Helpers.loadFile(this.info);
+ }
+ return this._info;
+ },
+ showInfo: function() {
+ Helpers.showModal(this.name, this.getInfo());
+ }
+ };
+ var research = $.extend([], Helpers.loadFile('json/research.json'),
+ ObjectStorage.load('research'));
+ research = research.map(function(item) {
+ return $.extend({}, researchPrototype, item);
+ });
+
+
+ /** Workers
+ */
+ var workersPrototype = {
+ hired: 0,
+ is_visible: function() {
+ return this.hired > 0 || lab.money >= this.cost * .7;
+ },
+ is_available: function() {
+ return lab.money >= this.cost;
+ },
+ hire: function() {
+ if (lab.buy(this.cost)) {
+ this.hired++;
+ var cost = this.cost;
+ this.cost = Math.round(this.cost * this.cost_increase);
+ return cost;
+ }
+ return -1;
+ }
+ };
+ var workers = $.extend([], Helpers.loadFile('json/workers.json'),
+ ObjectStorage.load('workers'));
+ workers = workers.map(function(worker) {
+ return $.extend({}, workersPrototype, worker);
+ });
+
+
+ /** Upgrades
+ */
+ var upgradesPrototype = {
+ getReceiver: function() {
+ if (this.type === "detector") {
+ return lab.detector;
+ } else if (this.type === "reputation"){
+ return lab.factor;
+ } else {
+ var context;
+ if (this.type === "research") { context = research; }
+ else if (this.type === "hr") { context = workers; }
+ else { return null; }
+ for (var i = 0; i < context.length; i++) {
+ if (context[i].name === this.receiver) {
+ return context[i];
+ }
+ }
+ return null;
+ }
+ },
+ hasReceiver: function() {
+ if (this.type === "detector" || this.type === "reputation") {
+ return true;
+ }
+ var rec = this.getReceiver();
+ if (this.type === "research") {
+ return rec.level > 0;
+ } else if (this.type === "hr") {
+ return rec.hired > 0;
+ }
+ return false;
+ },
+ is_visible: function() {
+ return !this.used && this.hasReceiver() && lab.money >= this.cost * .7;
+ },
+ is_available: function() {
+ return !this.used && this.hasReceiver() && lab.money >= this.cost;
+ },
+ buy: function() {
+ if (!this.used && lab.buy(this.cost)) {
+ this.used = true;
+ var rec = this.getReceiver();
+ if (rec) {
+ rec[this.property] = rec[this.property] * this.factor + this.constant;
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+ var upgrades = $.extend([], Helpers.loadFile('json/upgrades.json'),
+ ObjectStorage.load('upgrades'));
+ upgrades = upgrades.map(function(upgrade) {
+ return $.extend({}, upgradesPrototype, upgrade);
+ });
+
+
+ /** Save all the game objects at once.
+ */
+ var saveAll = function() {
+ ObjectStorage.save('lab', lab);
+ ObjectStorage.save('research', research);
+ ObjectStorage.save('workers', workers);
+ ObjectStorage.save('upgrades', upgrades);
+ };
+
+ return {
+ lab: lab,
+ research: research,
+ workers: workers,
+ upgrades: upgrades,
+ saveAll: saveAll
+ }
+})();
diff --git a/js/helpers.js b/js/helpers.js
new file mode 100644
index 0000000..8aad0bc
--- /dev/null
+++ b/js/helpers.js
@@ -0,0 +1,42 @@
+'use strict';
+
+/** Define some useful helpers that are used throughout the game.
+ */
+var Helpers = (function() {
+ /** Load a file (usually JSON).
+ */
+ var loadFile = function(filename) {
+ var res;
+ $.ajax({
+ async: false,
+ url : filename,
+ success : function(data) {
+ res = data;
+ }
+ });
+ return res;
+ };
+
+ /** Format a number with proper postfix.
+ */
+ var formatNumberPostfix = function(number) {
+ var abs = Math.abs(number);
+ if (abs >= Math.pow(10, 12)) {
+ number = (number / Math.pow(10, 12)).toFixed(1) + "T";
+ } else if (abs >= Math.pow(10, 9)) {
+ number = (number / Math.pow(10, 9)).toFixed(1) + "B";
+ } else if (abs >= Math.pow(10, 6)) {
+ number = (number / Math.pow(10, 6)).toFixed(1) + "M";
+ } else if (abs >= Math.pow(10, 3)) {
+ number = (number / Math.pow(10, 3)).toFixed(1) + "k";
+ } else {
+ number = number.toFixed(0);
+ }
+ return number;
+ }
+
+ return {
+ loadFile: loadFile,
+ formatNumberPostfix: formatNumberPostfix
+ };
+})();
diff --git a/js/storage.js b/js/storage.js
index d086da9..8057188 100644
--- a/js/storage.js
+++ b/js/storage.js
@@ -12,6 +12,9 @@ var ObjectStorage = (function() {
},
load: function(key) {
return JSON.parse(_s.getItem(key));
+ },
+ clear: function() {
+ _s.clear();
}
};
} catch (e) {
@@ -19,7 +22,8 @@ var ObjectStorage = (function() {
+ ' If you refresh the page, all progress will be lost');
return {
save: function(key, item) {},
- load: function(key) { return null; }
+ load: function(key) { return null; },
+ clear: function() {}
};
};
-});
+})();
diff --git a/js/ui.js b/js/ui.js
index 3745b7d..56f85db 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -1,13 +1,64 @@
-$(function() {
- var h = $(window).height();
- $('.scrollable').height(h - 50 + 'px');
+'use strict';
- $(window).resize(function() {
+/** Define UI specific stuff.
+ */
+var UI = (function () {
+ /** Resize the scrollable containers and make sure they are resized whenever
+ * the window is resized. */
+ $(function() {
var h = $(window).height();
$('.scrollable').height(h - 50 + 'px');
+
+ $(window).resize(function() {
+ var h = $(window).height();
+ $('.scrollable').height(h - 50 + 'px');
+ });
});
-});
+ /** Show a bootstrap modal with dynamic content. */
+ var showModal = function(title, text) {
+ var $modal = $('#infoBox');
+ $modal.find('#infoBoxLabel').html(title);
+ $modal.find('.modal-body').html(text);
+ $modal.modal({show: true});
+ };
+
+ var showUpdateValue = function(ident, num) {
+ var formatted = Helpers.formatNumberPostfix(num);
+ if (num != 0) {
+ var insert;
+ if (num > 0) {
+ insert = $("
")
+ .attr("class", "update-plus")
+ .html("+" + num);
+ } else {
+ insert = $("
")
+ .attr("class", "update-minus")
+ .html(num);
+ }
+ showUpdate(ident, insert);
+ }
+ }
+
+ var showUpdate = function(ident, insert) {
+ var elem = $(ident);
+ elem.append(insert);
+ insert.animate({
+ "bottom":"+=30px",
+ "opacity": 0
+ }, { duration: 500, complete: function() {
+ $(this).remove();
+ }});
+ }
+
+ return {
+ showModal: showModal,
+ showUpdateValue: showUpdateValue
+ }
+})();
+
+
+// I don't know what this is for, so I leave it here for the moment...
(function() {
var hidden = "hidden";
@@ -41,30 +92,3 @@ $(function() {
detector.visible = !this[hidden];
}
})();
-
-function showUpdateValue(ident, num) {
- if (num != 0) {
- if (num > 0) {
- insert = $("
")
- .attr("class", "update-plus")
- .html("+" + num);
- } else {
- insert = $("
")
- .attr("class", "update-minus")
- .html(num);
- }
- showUpdate(ident, insert);
- }
-}
-
-function showUpdate(ident, insert) {
- elem = $(ident);
- elem.append(insert);
- insert.animate({
- "bottom":"+=30px",
- "opacity": 0
- }, { duration: 500, complete: function() {
- $(this).remove();
- }});
-}
-