dadish 2, fbwg3, and progress knight quest

This commit is contained in:
BluePotato102
2023-12-10 09:44:43 -06:00
parent 6b3eacdd04
commit ec387d014c
70 changed files with 5397 additions and 3 deletions
@@ -0,0 +1,147 @@
(function (workerScript) {
if (!/MSIE 10/i.test (navigator.userAgent)) {
try {
var blob = new Blob (["\
var fakeIdToId = {};\
onmessage = function (event) {\
var data = event.data,\
name = data.name,\
fakeId = data.fakeId,\
time;\
if(data.hasOwnProperty('time')) {\
time = data.time;\
}\
switch (name) {\
case 'setInterval':\
fakeIdToId[fakeId] = setInterval(function () {\
postMessage({fakeId: fakeId});\
}, time);\
break;\
case 'clearInterval':\
if (fakeIdToId.hasOwnProperty (fakeId)) {\
clearInterval(fakeIdToId[fakeId]);\
delete fakeIdToId[fakeId];\
}\
break;\
case 'setTimeout':\
fakeIdToId[fakeId] = setTimeout(function () {\
postMessage({fakeId: fakeId});\
if (fakeIdToId.hasOwnProperty (fakeId)) {\
delete fakeIdToId[fakeId];\
}\
}, time);\
break;\
case 'clearTimeout':\
if (fakeIdToId.hasOwnProperty (fakeId)) {\
clearTimeout(fakeIdToId[fakeId]);\
delete fakeIdToId[fakeId];\
}\
break;\
}\
}\
"]);
// Obtain a blob URL reference to our worker 'file'.
workerScript = window.URL.createObjectURL(blob);
} catch (error) {
/* Blob is not supported, use external script instead */
}
}
var worker,
fakeIdToCallback = {},
lastFakeId = 0,
maxFakeId = 0x7FFFFFFF, // 2 ^ 31 - 1, 31 bit, positive values of signed 32 bit integer
logPrefix = 'HackTimer.js by turuslan: ';
if (typeof (Worker) !== 'undefined') {
function getFakeId () {
do {
if (lastFakeId == maxFakeId) {
lastFakeId = 0;
} else {
lastFakeId ++;
}
} while (fakeIdToCallback.hasOwnProperty (lastFakeId));
return lastFakeId;
}
try {
worker = new Worker (workerScript);
window.setInterval = function (callback, time /* , parameters */) {
var fakeId = getFakeId ();
fakeIdToCallback[fakeId] = {
callback: callback,
parameters: Array.prototype.slice.call(arguments, 2)
};
worker.postMessage ({
name: 'setInterval',
fakeId: fakeId,
time: time
});
return fakeId;
};
window.clearInterval = function (fakeId) {
if (fakeIdToCallback.hasOwnProperty(fakeId)) {
delete fakeIdToCallback[fakeId];
worker.postMessage ({
name: 'clearInterval',
fakeId: fakeId
});
}
};
window.setTimeout = function (callback, time /* , parameters */) {
var fakeId = getFakeId ();
fakeIdToCallback[fakeId] = {
callback: callback,
parameters: Array.prototype.slice.call(arguments, 2),
isTimeout: true
};
worker.postMessage ({
name: 'setTimeout',
fakeId: fakeId,
time: time
});
return fakeId;
};
window.clearTimeout = function (fakeId) {
if (fakeIdToCallback.hasOwnProperty(fakeId)) {
delete fakeIdToCallback[fakeId];
worker.postMessage ({
name: 'clearTimeout',
fakeId: fakeId
});
}
};
worker.onmessage = function (event) {
var data = event.data,
fakeId = data.fakeId,
request,
parameters,
callback;
if (fakeIdToCallback.hasOwnProperty(fakeId)) {
request = fakeIdToCallback[fakeId];
callback = request.callback;
parameters = request.parameters;
if (request.hasOwnProperty ('isTimeout') && request.isTimeout) {
delete fakeIdToCallback[fakeId];
}
}
if (typeof (callback) === 'string') {
try {
callback = new Function (callback);
} catch (error) {
console.log (logPrefix + 'Error parsing callback code string: ', error);
}
}
if (typeof (callback) === 'function') {
callback.apply (window, parameters);
}
};
worker.onerror = function (event) {
console.log (event);
};
} catch (error) {
console.log (logPrefix + 'Initialisation failed');
console.error (error);
}
} else {
console.log (logPrefix + 'Initialisation failed - HTML5 Web Worker is not supported');
}
}) ('HackTimerWorker.js');
+175
View File
@@ -0,0 +1,175 @@
/*
Task is a base class combining core functionality used in jobs and skills.
A task object stores: name, level, max level ever achieved,
current experience (e.g. experience accumulated inside the current task level),
and an array of experience multipliplying effects from items and skills.
*/
class Task {
constructor(baseData) {
this.baseData = baseData
this.name = baseData.name
this.level = 0
this.maxLevel = 0
this.xp = 0
this.xpMultipliers = [
]
}
getMaxXp() {
var maxXp = Math.round(this.baseData.maxXp * (this.level + 1) * Math.pow(1.01, this.level))
return maxXp
}
getXpLeft() {
return Math.round(this.getMaxXp() - this.xp)
}
getMaxLevelMultiplier() {
var maxLevelMultiplier = 1 + this.maxLevel / 10
return maxLevelMultiplier
}
getXpGain() {
return applyMultipliers(10, this.xpMultipliers)
}
increaseXp() {
this.xp += applySpeed(this.getXpGain())
if (this.xp >= this.getMaxXp()) {
var excess = this.xp - this.getMaxXp()
while (excess >= 0) {
this.level += 1
excess -= this.getMaxXp()
}
this.xp = this.getMaxXp() + excess
}
}
}
class Job extends Task {
constructor(baseData) {
super(baseData)
this.incomeMultipliers = [
]
}
getLevelMultiplier() {
var levelMultiplier = 1 + Math.log10(this.level + 1)
return levelMultiplier
}
getIncome() {
return applyMultipliers(this.baseData.income, this.incomeMultipliers)
}
}
class Skill extends Task {
constructor(baseData) {
super(baseData)
}
getEffect() {
var effect = 1 + this.baseData.effect * this.level
return effect
}
getEffectDescription() {
var description = this.baseData.description
var text = "x" + String(this.getEffect().toFixed(2)) + " " + description
return text
}
}
class Item {
constructor(baseData) {
this.baseData = baseData
this.name = baseData.name
this.expenseMultipliers = [
]
}
getEffect() {
if (gameData.currentProperty != this && !gameData.currentMisc.includes(this)) return 1
var effect = this.baseData.effect
return effect
}
getEffectDescription() {
var description = this.baseData.description
if (itemCategories["Properties"].includes(this.name)) description = "Happiness"
var text = "x" + this.baseData.effect.toFixed(1) + " " + description
return text
}
getExpense() {
return applyMultipliers(this.baseData.expense, this.expenseMultipliers)
}
}
class Requirement {
constructor(elements, requirements) {
this.elements = elements
this.requirements = requirements
this.completed = false
}
isCompleted() {
if (this.completed) {return true}
for (var requirement of this.requirements) {
if (!this.getCondition(requirement)) {
return false
}
}
this.completed = true
return true
}
}
class TaskRequirement extends Requirement {
constructor(elements, requirements) {
super(elements, requirements)
this.type = "task"
}
getCondition(requirement) {
return gameData.taskData[requirement.task].level >= requirement.requirement
}
}
class CoinRequirement extends Requirement {
constructor(elements, requirements) {
super(elements, requirements)
this.type = "coins"
}
getCondition(requirement) {
return gameData.coins >= requirement.requirement
}
}
class AgeRequirement extends Requirement {
constructor(elements, requirements) {
super(elements, requirements)
this.type = "age"
}
getCondition(requirement) {
return daysToYears(gameData.days) >= requirement.requirement
}
}
class EvilRequirement extends Requirement {
constructor(elements, requirements) {
super(elements, requirements)
this.type = "evil"
}
getCondition(requirement) {
return gameData.evil >= requirement.requirement
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
/*
* Contains object definitions for Town Buildings.
* Provides container object to allow easy tracking of new buildings
* and automates some linking of new buildings to game logic.
*/
var o_townBuildingsContainer = {
o_woodenHut: {
name: "Wooden Hut",
id: "woodenHut",
count: 0,
baseCost: 100000000001, //treat as const
costOfNextBuilding: 100000000001,
costGrowthFactor: 1.01,
role: ["Housing"],
handleClick: function(eventObject) {
if(gameData.coins >= this.costOfNextBuilding) {
gameData.coins -= this.costOfNextBuilding;
console.log(`Inside handleClick(). This.count: ${this.count}`);
this.count += 1;
console.log(`Post-increment. This.count: ${this.count}`);
this.costOfNextBuilding *= this.costGrowthFactor;
}
updateTooltip(eventObject);
},
},
o_farm: {
name: "Farm",
id: "farm",
count: 0,
baseCost: 1000000000001, //treat as const
costOfNextBuilding: 1000000000001,
costGrowthFactor: 1.05,
role: ["Food", "Income", "Prestige", "Nobility xp"],
xpMultiplier: 1.10,
income: 150, //1s 50c
handleClick: function(eventObject) {
if(gameData.coins >= this.costOfNextBuilding) {
gameData.coins -= this.costOfNextBuilding;
this.count++;
this.costOfNextBuilding *= this.costGrowthFactor;
}
//global function, lives in townFunctions.js
gameData.rawTownIncome = updateRawTownIncome();
updateTooltip(eventObject);
},
getExperienceMultiplier: function() {
return this.count * this.xpMultiplier;
},
getIncome: function() {
return this.income * this.count;
},
},
o_grainShed: {
name: "Grain Shed",
id: "grainShed",
count: 0,
baseCost: 100000000001, //treat as const
costOfNextBuilding: 100000000001,
costGrowthFactor: 1.07,
role: ["Food", "Income Boost"],
targets: ["Farm"],
incomeMultiplier: 1.06,
handleClick: function(eventObject) {
if(gameData.coins >= this.costOfNextBuilding) {
gameData.coins -= this.costOfNextBuilding;
this.count++;
this.costOfNextBuilding *= this.costGrowthFactor;
}
//global function, lives in townFunctions.js
gameData.rawTownIncome = updateRawTownIncome();
updateTooltip(eventObject);
},
calculateMultiplier: function() {
return Math.pow(this.incomeMultiplier, this.count);
}
},
} // container
@@ -0,0 +1,130 @@
/*
Contains global functions related to Town features
*/
// Purpose: calculate the amount of money a player makes from their town buildings.
//
// How: iterate through town building container. If 'income' is a property, multiply
// the income * count and add it to the total income variable. Return the total income
// variable.
function updateRawTownIncome() {
//console.log("testing updateRawTownIncome function. We are inside the function now.");
var totalIncome = 0;
//console.log("totalIncome: " + totalIncome);
//console.log("Starting for loop...");
for(building in o_townBuildingsContainer) {
//console.log("key: " + building);
//building represents the key, so we use it to get a reference to the actual object
var o_building = o_townBuildingsContainer[building];
//console.log("value: " + o_building);
if('income' in o_building) {
//console.log("Income is detected in " + o_building.name + " building.");
/*
* Description: if a building might have its income boosted by other buildings,
* we iterate through all buildings to calculate the total income multiplier from all
* buildings that boost it.
*
* We also do a few checks to make sure the properties we rely on are defined.
*
* This may become a performance bottleneck with large numbers of buildings
* due to nested for loops and their O(n^2) behavior.
*/
if(o_building.name === "Farm") {
var multiplier = 1.0;
for(building2 in o_townBuildingsContainer) {
var o_building2 = o_townBuildingsContainer[building2];
if(('role' in o_building2) && (o_building2.role.includes("Income Boost"))){
if (o_building2.targets !== undefined && o_building2.targets.includes("Farm")) {
multiplier *= o_building2.calculateMultiplier();
}
}
}
totalIncome += (o_building.getIncome() * multiplier);
} else {
totalIncome += (o_building.getIncome());
}
//console.log("Income from " + o_building.name + " added to total. New total income: " + totalIncome);
}
}
//console.log("For loop complete. totalIncome = " + totalIncome);
return totalIncome;
}
/*
* Description: saves select building object properties into a saveObject
* and writes that saveObject into gameData.townData. This function is
* called right before gameData is saved to localStorage.
*/
function saveTownState() {
if(enableVerboseLogging == 1) console.log("saving town state...");
for(building in o_townBuildingsContainer) {
if(enableVerboseLogging == 1) console.log("key: " + building);
var o_building = o_townBuildingsContainer[building];
if(enableVerboseLogging == 1) console.log("value: " + o_building);
var saveObject = {
name: o_building.name,
count: o_building.count,
costOfNextBuilding: o_building.costOfNextBuilding,
};
if(saveObject !== undefined) {
if(enableVerboseLogging == 1) console.log("This is the save object we created: " + saveObject);
gameData.townData[saveObject.name] = saveObject;
}
}
}
function loadTownState() {
for(building in o_townBuildingsContainer) {
var o_building = o_townBuildingsContainer[building];
if(o_building.name in gameData.townData) {
var savedBuilding = gameData.townData[o_building.name];
o_building.count = savedBuilding.count;
o_building.costOfNextBuilding = savedBuilding.costOfNextBuilding;
}
}
}
function destroyTownWhileEmbracingEvil() {
//reset values in o_townBuildingContainer to their base values
//reset values in gameData.townData, if it is not null, to their base values
if(gameData.townData) {
for(building in o_townBuildingsContainer) {
var o_building = o_townBuildingsContainer[building];
if(o_building.name in gameData.townData) {
var savedBuilding = gameData.townData[o_building.name];
savedBuilding.count = o_building.count = 0;
o_building.costOfNextBuilding = savedBuilding.costOfNextBuilding = o_building.baseCost;
}
}
gameData.rawTownIncome = 0;
}
}
function testSuccessOfTownDestruction() {
for(building in o_townBuildingsContainer) {
var o_building = o_townBuildingsContainer[building];
if(o_building.name in gameData.townData) {
var savedBuilding = gameData.townData[o_building.name];
if(enableVerboseLogging == 1) {
console.log(`Type of Saved Count: ${typeof savedBuilding.count}`);
console.log(`${o_building.name} Saved count: ${savedBuilding.count}`);
console.log(`${o_building.name} Saved cost: ${savedBuilding.costOfNextBuilding}`);
console.log(`${o_building.name} Working count: ${o_building.count}`);
console.log(`${o_building.name} Working cost: ${o_building.costOfNextBuilding}`);
}
savedBuilding.count = o_building.count = 0;
}
}
}
// temporary brute-force function to limit Town income until it is modulated by future feature interaction.
// the kingdom has spoken.
function regulateGrainMarkets() {
if(gameData.rawTownIncome > 1000000000) { //1000 platinum
gameData.rawTownIncome = 1000000000;
}
}
setInterval(regulateGrainMarkets, 15000);
@@ -0,0 +1,40 @@
function updateTooltip(eventObject) {
//eventObject.currentTarget.id = the button's building id, like "woodenHut"
// So tooltip ID is merely a template string `tooltip-${eventObject.currentTarget.id}
let tooltipId = `tooltip-${eventObject.currentTarget.id}`;
//console.log("Print all function args: " + arguments[0] + arguments[1]);
//console.log("Tooltip ID: " + tooltipId);
var tooltipElement = document.querySelector("#" + tooltipId);
//console.log("Grabbed the tooltip element whose text we're updating!");
//console.log(tooltipElement);
//console.log("Here's the text content: ");
//console.log(tooltipElement.textContent);
//console.log("Typeof text content: " + typeof tooltipElement.textContent);
let originalText = tooltipElement.textContent;
//hard code new cost for wooden hut, for now
//in future, will grab building cost based off of tooltipId
//let newBuildingCost = o_townBuildingsContainer.o_woodenHut.costOfNextBuilding;
let newBuildingCost = o_townBuildingsContainer[`o_${eventObject.currentTarget.id}`].costOfNextBuilding;
/* TEST getNested function from townFunctions.js */
/* const test = o_townBuildingsContainer;
console.log("***** testing getNested() *******");
console.log(getNested(test, 'o_woodenHut', 'id'));
console.log(test[`o_${eventObject.currentTarget.id}`]); */
//console.log(`New building cost: ${newBuildingCost}`);
//console.log(`Searching ${tooltipId} for the span that wraps building cost...`);
let buildingID = tooltipId.replace('tooltip-', '');
let coinSpanId = `#coins-${buildingID}`;
//console.log(`Coin span id: ${coinSpanId}`);
let coinSpan = document.querySelector(coinSpanId);
//console.log(`Coin span element: ${coinSpan}`);
//console.log(`Coin span text content: ${coinSpan.textContent}`);
//console.log("Replacing coin value with formatted building cost...");
formatCoins(newBuildingCost, coinSpan);
}