Parcourir la source

Change everything to use a dictionary of costs, rather than just numbers

This has broken quite a bit, since many parts of the game expect a scalar instead of
a whole object. I have also been deep freezing constant configuration data and, generally,
trying to make as much immutable as possible
tags/v0.0.6
Fen Dweller il y a 5 ans
Parent
révision
5738659d8e
Aucune clé connue n'a été trouvée dans la base pour cette signature ID de la clé GPG: E80B35A6F11C3656
4 fichiers modifiés avec 196 ajouts et 69 suppressions
  1. +125
    -41
      constants.js
  2. +47
    -28
      gorge.js
  3. +3
    -0
      numbers.js
  4. +21
    -0
      util.js

+ 125
- 41
constants.js Voir le fichier

@@ -2,168 +2,249 @@

const resourceTypes = {
"food": {
name: "Food"
name: "food"
}
}

deepFreeze(resourceTypes);

const buildings = {
"micro": {
"name": "Micro",
"plural": "Micros",
"desc": "A tasty, squirmy treat.",
"cost": 1e1,
"prod": 1e-1 / 1,
"cost": {
"food": 1e1
},
"prod": {
"food": 1e-1 / 1
},
"icon": "fa-universal-access"
},
"anthro": {
"name": "Anthro",
"plural": "Anthros",
"desc": "Something more substantial to sate your hunger.",
"cost": 1e2,
"prod": 1e0 / 1.1,
"cost": {
"food": 1e2
},
"prod": {
"food": 1e0 / 1.1
},
"icon": "fa-male"
},
"car": {
"name": "Car",
"plural": "Cars",
"desc": "Crunchy shell, tasty center.",
"cost": 1.2e3,
"prod": 1e1 / 1.2,
"cost": {
"food": 1.2e3
},
"prod": {
"food": 1e1 / 1.2
},
"icon": "fa-car"
},
"bus": {
"name": "Bus",
"plural": "Buses",
"desc": "Probably the worst place to be when a macro is aroud.",
"cost": 1.4e4,
"prod": 1e2 / 1.3,
"cost": {
"food": 1.4e4
},
"prod": {
"food": 1e2 / 1.3
},
"icon": "fa-bus"
},
"house": {
"name": "House",
"plural": "Houses",
"desc": "Home sweet home - but it doesn't taste sweet?",
"cost": 1.6e5,
"prod": 1e3 / 1.4,
"cost": {
"food": 1.6e5
},
"prod": {
"food": 1e3 / 1.4
},
"icon": "fa-home"
},
"apartment": {
"name": "Apartment",
"plural": "Apartments",
"desc": "More snacks, less packaging.",
"cost": 1.8e6,
"prod": 1e4 / 1.5,
"cost": {
"food": 1.8e6
},
"prod": {
"food": 1e4 / 1.5
},
"icon": "fa-building"
},
"block": {
"name": "Block",
"plural": "Blocks",
"desc": "A whole pile of buildings.",
"cost": 2e7,
"prod": 1e5 / 1.6,
"cost": {
"food": 2e7
},
"prod": {
"food": 1e5 / 1.6
},
"icon": "fa-warehouse"
},
"town": {
"name": "Town",
"plural": "Towns",
"desc": "'Tourist trap' has never been this literal.",
"cost": 2.2e8,
"prod": 1e6 / 1.7,
"cost": {
"food": 2.2e8
},
"prod": {
"food": 1e6 / 1.7
},
"icon": "fa-store"
},
"city": {
"name": "City",
"plural": "Cities",
"desc": "Please no sitty on our city.",
"cost": 2.4e9,
"prod": 1e7 / 1.8,
"cost": {
"food": 2.4e9
},
"prod": {
"food": 1e7 / 1.8
},
"icon": "fa-city"
},
"metro": {
"name": "Metropolis",
"plural": "Metropolises",
"desc": "A big ol' city. Tasty, too.",
"cost": 2.6e10,
"prod": 1e8 / 1.9,
"cost": {
"food": 2.6e10
},
"prod": {
"food": 1e8 / 1.9
},
"icon": "fa-landmark"
},
"county": {
"name": "County",
"plural": "Counties",
"desc": "Why salt the land when you can slurp it?",
"cost": 2.8e11,
"prod": 1e9 / 2,
"cost": {
"food": 2.8e11
},
"prod": {
"food": 1e9 / 2
},
"icon": "fa-map"
},
"state": {
"name": "State",
"plural": "States",
"desc": "The United States is made up of...43 states - no, 42...",
"cost": 3e12,
"prod": 1e10 / 2.1,
"cost": {
"food": 3e12
},
"prod": {
"food": 1e10 / 2.1
},
"icon": "fa-map-signs"
},
"country": {
"name": "Country",
"plural": "Countries",
"desc": "One nation, under paw.",
"cost": 3.2e13,
"prod": 1e11 / 2.2,
"cost": {
"food": 3.2e13
},
"prod": {
"food": 1e11 / 2.2
},
"icon": "fa-flag"
},
"continent": {
"name": "Continent",
"plural": "Continents",
"desc": "Earth-shattering appetite!",
"cost": 3.4e14,
"prod": 1e12 / 2.3,
"cost": {
"food": 3.4e14
},
"prod": {
"food": 1e12 / 2.3
},
"icon": "fa-mountain"
},
"planet": {
"name": "Planet",
"plural": "Planets",
"desc": "Earth appetite!",
"cost": 3.6e15,
"prod": 1e13 / 2.4,
"cost": {
"food": 3.6e15
},
"prod": {
"food": 1e13 / 2.4
},
"icon": "fa-globe-europe"
},
"solar-system": {
"name": "Solar System",
"plural": "Solar Systems",
"desc": "Earths appetite!",
"cost": 3.8e16,
"prod": 1e14 / 2.5,
"cost": {
"food": 3.8e16
},
"prod": {
"food": 1e14 / 2.5
},
"icon": "fa-meteor"
},
"galaxy": {
"name": "Galaxy",
"plural": "Galaxies",
"desc": "In a galaxy far, far down your gullet...",
"cost": 4.0e17,
"prod": 1e15 / 2.6,
"cost": {
"food": 4.0e17
},
"prod": {
"food": 1e15 / 2.6
},
"icon": "fa-sun"
},
"universe": {
"name": "Universe",
"plural": "Universes",
"desc": "Into the you-verse.",
"cost": 4.2e18,
"prod": 1e16 / 2.7,
"cost": {
"food": 4.2e18
},
"prod": {
"food": 1e16 / 2.7
},
"icon": "fa-asterisk"
},
"multiverse": {
"name": "Multiverse",
"plural": "Multiverses",
"desc": "This is getting very silly.",
"cost": 4.4e19,
"prod": 1e17 / 2.8,
"cost": {
"food": 4.4e19
},
"prod": {
"food": 1e17 / 2.8
},
"icon": "fa-infinity"
}
}

deepFreeze(buildings);

const effect_types = {
"prod": {
"apply": function (effect, productivity) {
return productivity * effect.amount;
scaleCost(productivity, effect);
},
"desc": function (effect) {
return round(effect.amount, 2) + "x food production from " + buildings[effect.target].plural;
@@ -171,7 +252,7 @@ const effect_types = {
},
"prod-all": {
"apply": function (effect, productivity) {
return productivity * effect.amount;
scaleCost(productivity, effect);
},
"desc": function (effect) {
return round((effect.amount - 1) * 100) + "% increase to food production";
@@ -208,6 +289,8 @@ const effect_types = {
}
}

deepFreeze(effect_types);

let upgrades = {

}
@@ -219,6 +302,7 @@ function createTemplateUpgrades() {
createHelperUpgrades();
createClickVictimUpgrades();
createPowerupFreqUpgrades();
deepFreeze(upgrades);
}

const prodUpgradeCounts = [1, 5, 10, 25, 50, 75, 100];


+ 47
- 28
gorge.js Voir le fichier

@@ -13,6 +13,7 @@ const resources = {};
let updateRate = 30;

const currentProductivity = {};

let clickBonus = 0;
let clickVictim = "micro";

@@ -66,7 +67,10 @@ function addPowerup(powerup) {
updateAll();
}

function applyGlobalProdBonuses(productivity) {
function getGlobalProdBonus() {

let productivity = 1;

for (let effect of effects["prod-all"]) {

if (ownedUpgrades[effect.parent]) {
@@ -78,10 +82,10 @@ function applyGlobalProdBonuses(productivity) {
}

function calculateProductivity() {
let productivity = 0;
let productivity = makeCost();

for (const [key, value] of Object.entries(belongings)) {
productivity += productivityOf(key);
productivity = addCost(productivity, productivityOf(key));
}

return productivity;
@@ -110,27 +114,42 @@ function productivityMultiplierOf(type) {
}

function productivityOf(type) {
let baseProd = buildings[type].prod;
let baseProd = makeCost(buildings[type].prod);

let prod = baseProd * productivityMultiplierOf(type);
baseProd.food *= productivityMultiplierOf(type);

prod = applyGlobalProdBonuses(prod);
baseProd.food *= getGlobalProdBonus();

baseProd.food *= belongings[type].count;

return baseProd;
}

return prod * belongings[type].count;
function makeCost(source) {
const empty = mapObject(resourceTypes, () => 0);
Object.preventExtensions(empty);
return {...empty, ...source};
}

function addCost(cost1, cost2) {
return Object.keys(resourceTypes).reduce((o, k) => ({ ...o, [k]: cost1[k] + cost2[k]}), {});
}

function scaleCost(cost, scale) {
return Object.keys(resourceTypes).reduce((o, k) => ({ ...o, [k]: cost[k] * scale}), {});
}

function costOfBuilding(type, count = 1) {
let total = 0;
let total = makeCost();

while (count > 0) {
let baseCost = buildings[type].cost;
let countCost = baseCost * Math.pow(1.15, belongings[type].count + count - 1);
total += countCost;
let baseCost = makeCost(buildings[type].cost);
baseCost.food *= Math.pow(1.15, belongings[type].count + count - 1);
total = addCost(total, baseCost);
count--;
}


return Math.round(total);
return mapObject(total, round);
}

function buildingCount() {
@@ -148,9 +167,9 @@ function buyBuilding(type, e) {

let cost = costOfBuilding(type, count);

if (resources.food >= cost) {
if (canAfford(cost)) {
spend(cost);
belongings[type].count += count;
resources.food -= cost;
}

updateProductivity();
@@ -181,7 +200,7 @@ function updateDisplay() {
}

function updateProductivity() {
currentProductivity["food"] = calculateProductivity();
Object.assign(currentProductivity, calculateProductivity());

activePowerups.forEach(entry => {
const powerup = entry.powerup;
@@ -193,11 +212,7 @@ function updateProductivity() {
belongings: belongings
};

console.log(currentProductivity);

powerup.effect(state);

console.log(currentProductivity);
})
}

@@ -233,7 +248,9 @@ function displayBuildings() {
for (const [key, value] of Object.entries(belongings)) {

if (!belongings[key].visible) {
if (resources.food * 10 >= costOfBuilding(key)) {
if (resources.food * 10 >= costOfBuilding(key).food) {
unlockBuilding(key);
} if (belongings[key].count > 0) {
unlockBuilding(key);
} else {
continue;
@@ -247,15 +264,17 @@ function displayBuildings() {
let name = document.querySelector("#building-" + key + " > .building-button-name");
let cost = document.querySelector("#building-" + key + " > .building-button-cost");

const buildingCost = costOfBuilding(key, count);

name.innerText = value.count + " " + (value.count == 1 ? buildings[key].name : buildings[key].plural);
cost.innerText = render(costOfBuilding(key, count)) + " food";
cost.innerText = render(buildingCost.food) + " food";

if (costOfBuilding(key, count) > resources.food) {
button.classList.add("building-button-disabled");
cost.classList.add("building-button-cost-invalid");
} else {
if (canAfford(buildingCost)) {
button.classList.remove("building-button-disabled");
cost.classList.add("building-button-cost-valid");
} else {
button.classList.add("building-button-disabled");
cost.classList.add("building-button-cost-invalid");
}
}
}
@@ -375,7 +394,7 @@ function buyUpgrade(id, e) {
}

function eatPrey() {
const add = buildings[clickVictim]["prod"] * 10 * productivityMultiplierOf(clickVictim) + clickBonus;
const add = buildings[clickVictim]["prod"].food * 10 * productivityMultiplierOf(clickVictim) + clickBonus;
resources.food += add;
return add;
}
@@ -938,7 +957,7 @@ function buildingTooltip(id, event) {

fillTooltip("building", "name", (count != 1 ? count + "x " : "") + buildings[id].name);
fillTooltip("building", "desc", buildings[id].desc);
fillTooltip("building", "cost", render(costOfBuilding(id, count)) + " food");
fillTooltip("building", "cost", render(costOfBuilding(id, count).food) + " food");
fillTooltip("building", "prod", prodSummary(id));

let xPos = tooltip.parentElement.getBoundingClientRect().x - 450;


+ 3
- 0
numbers.js Voir le fichier

@@ -3,6 +3,9 @@ function render(val, places = 1, smallPlaces = 0) {
}

function numberText(val, places = 1, smallPlaces = 0) {
if (isNaN(val)) {
throw new RangeError("Invalid number: " + val);
}
if (val < 1000) {
return round(val, smallPlaces);
}


+ 21
- 0
util.js Voir le fichier

@@ -18,3 +18,24 @@ function removeChildren(element) {
function round(val, places = 0) {
return Math.round(val * Math.pow(10, places)) / Math.pow(10, places);
}

function mapObject(obj, func) {
return Object.keys(obj).reduce((o, k) => ({ ...o, [k]: func(obj[k])}), {});
}

function deepFreeze(object) {

// Retrieve the property names defined on object
var propNames = Object.getOwnPropertyNames(object);

// Freeze properties before freezing self
for (let name of propNames) {
let value = object[name];

object[name] = value && typeof value === "object" ?
deepFreeze(value) : value;
}

return Object.freeze(object);
}

Chargement…
Annuler
Enregistrer