2024-06-21 11:58:15 -07:00
|
|
|
(function () {
|
|
|
|
"use strict";
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
const UPDATES_PER_MINUTE = 2;
|
|
|
|
const UPDATES_PER_HOUR = UPDATES_PER_MINUTE * 60;
|
|
|
|
const UPDATES_PER_DAY = UPDATES_PER_HOUR * 24;
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the current pet version.. */
|
|
|
|
const CURRENT_PET_VERSION = 1;
|
|
|
|
/** the max food a pet will eat */
|
|
|
|
const MAX_FOOD = 100;
|
|
|
|
/** the amount of time it takes for a pet to have to GO */
|
|
|
|
const POTTY_TIME = 100;
|
|
|
|
/** how fast a pet's food value decays */
|
2024-06-24 23:21:00 -07:00
|
|
|
const FOOD_DECAY = MAX_FOOD / (UPDATES_PER_HOUR * 8); // to stay on top should be fed roughly once every 8 hours?
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the rate at which a pet ages */
|
|
|
|
const AGING_RATE = 1;
|
|
|
|
/** how fast a pet's potty need decays */
|
2024-06-24 23:21:00 -07:00
|
|
|
const POTTY_DECAY = FOOD_DECAY / 2; // roughly every 4 hours?
|
|
|
|
/** how much mess can be in a pet's space at once */
|
|
|
|
const MAX_MESS = 5;
|
|
|
|
/** how fast a pet's happiness decays */
|
|
|
|
const HAPPINESS_DECAY = FOOD_DECAY;
|
|
|
|
/** a pet's maximum happiness */
|
|
|
|
const MAX_HAPPINESS = 100;
|
|
|
|
/** how quickly a pet's happiness will be reduced by when hungry */
|
|
|
|
const HAPPINESS_EMPTY_STOMACH_MODIFIER = -10 / UPDATES_PER_HOUR;
|
|
|
|
/** how quickly a pet's happiness will be reduced by when their space is messy, per piece of mess */
|
|
|
|
const HAPPINESS_MESS_MODIFIER = -5 / UPDATES_PER_HOUR;
|
2024-06-25 13:48:56 -07:00
|
|
|
/** how quickly a pet's behavior drops when unhappy */
|
|
|
|
const BEHAVIOR_UNHAPPY_MODIFIER = -5 / UPDATES_PER_HOUR;
|
2024-06-24 23:21:00 -07:00
|
|
|
|
|
|
|
/** the amount of happiness gained when the pet is fed (excluding when the pet doesn't yet need food) */
|
|
|
|
const FEED_HAPPINESS = 5;
|
|
|
|
/** the amount of happiness gained when the pet is pet */
|
|
|
|
const PET_HAPPINESS = 20;
|
|
|
|
/** the amount of happiness gained when the pet's space is cleaned */
|
|
|
|
const CLEAN_HAPPINESS = 1;
|
|
|
|
|
|
|
|
/** the minimum amount of time between feedings */
|
2024-06-25 01:00:15 -07:00
|
|
|
const FEED_TIMER = 1000 * 60 * 60;
|
2024-06-24 23:21:00 -07:00
|
|
|
/** the minimum amount of time between pets */
|
2024-06-25 01:00:15 -07:00
|
|
|
const PET_TIMER = 60000;
|
2024-06-24 23:21:00 -07:00
|
|
|
/** the minimum amount of time between cleans */
|
2024-06-25 01:00:15 -07:00
|
|
|
const CLEAN_TIMER = 1000 * 60 * 60;
|
2024-06-24 23:21:00 -07:00
|
|
|
|
|
|
|
const PET_SAVE_KEY = "pet-game";
|
2024-06-21 11:58:15 -07:00
|
|
|
|
|
|
|
/** life stage for an egg */
|
|
|
|
const LIFE_STAGE_EGG = 1;
|
|
|
|
/** life stage for a pup */
|
|
|
|
const LIFE_STAGE_PUP = 2;
|
|
|
|
/** life stage for an adult */
|
|
|
|
const LIFE_STAGE_ADULT = 3;
|
|
|
|
/** life stage for an elder pet */
|
|
|
|
const LIFE_STAGE_ELDER = 4;
|
|
|
|
/** the time it takes for a pet to grow past the egg phase */
|
2024-06-24 23:21:00 -07:00
|
|
|
const EGG_TIME = UPDATES_PER_MINUTE;
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the time it takes for a pet to grow past the pup phase */
|
2024-06-24 23:21:00 -07:00
|
|
|
const PUP_TIME = UPDATES_PER_DAY * 7;
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the time it takes for a pet to grow past the adult phase */
|
2024-06-24 23:21:00 -07:00
|
|
|
const ADULT_TIME = UPDATES_PER_DAY * 15;
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the time it takes for a pet to grow past the elder phase */
|
2024-06-24 23:21:00 -07:00
|
|
|
const ELDER_TIME = UPDATES_PER_DAY * 7;
|
2024-06-21 11:58:15 -07:00
|
|
|
|
2024-06-25 00:02:11 -07:00
|
|
|
const WIDTH_PUP = 150;
|
|
|
|
const HEIGHT_PUP = 150;
|
|
|
|
const WIDTH_ADULT = 250;
|
|
|
|
const HEIGHT_ADULT = 250;
|
|
|
|
const WIDTH_ELDER = 210;
|
|
|
|
const HEIGHT_ELDER = 210;
|
|
|
|
|
|
|
|
/** the different types of pets available */
|
|
|
|
const PET_TYPES = ["circle", "square", "triangle"];
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
const petDisplay = document.querySelector("#pet-display");
|
2024-06-25 00:02:11 -07:00
|
|
|
const thePet = petDisplay.querySelector(".the-pet");
|
2024-06-25 00:42:10 -07:00
|
|
|
|
|
|
|
const status = petDisplay.querySelector(".status");
|
|
|
|
const statusHungry = status.querySelector("[name=hungry]");
|
|
|
|
const statusStarving = status.querySelector("[name=starving]");
|
|
|
|
const statusUnhappy = status.querySelector("[name=unhappy]");
|
|
|
|
const statusMessy1 = status.querySelector("[name=messy-1]");
|
|
|
|
const statusMessy2 = status.querySelector("[name=messy-2]");
|
|
|
|
const statusMessy3 = status.querySelector("[name=messy-3]");
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
const petName = document.querySelectorAll(".pet-name");
|
2024-06-21 11:58:15 -07:00
|
|
|
const eggDiv = document.querySelector("div#egg");
|
2024-06-24 23:21:00 -07:00
|
|
|
const petSetup = document.querySelector("#pet-setup");
|
|
|
|
const adultInfo = document.querySelector("div#adult-info");
|
|
|
|
const elderInfo = document.querySelector("div#elder-info");
|
|
|
|
const passedAwayInfo = document.querySelector("div#passed-away-info");
|
2024-06-21 11:58:15 -07:00
|
|
|
const name = petSetup.querySelector("input[name=pet-name]");
|
2024-06-24 23:21:00 -07:00
|
|
|
|
|
|
|
const petActions = document.querySelector("div#pet-actions");
|
|
|
|
const pauseButton = petActions.querySelector("button[name=pause]");
|
|
|
|
const hatchedActions = petActions.querySelector("div[name=hatched-actions]");
|
|
|
|
const feedButton = hatchedActions.querySelector("button[name=feed]");
|
|
|
|
const petButton = hatchedActions.querySelector("button[name=pet]");
|
|
|
|
const cleanButton = hatchedActions.querySelector("button[name=clean]");
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
const debug = document.querySelector("div#debug-section");
|
|
|
|
const debugLifeStage = debug.querySelector("span[name=ls]");
|
|
|
|
const debugAge = debug.querySelector("span[name=a]");
|
|
|
|
const debugFood = debug.querySelector("span[name=f]");
|
|
|
|
const debugBehavior = debug.querySelector("span[name=b]");
|
|
|
|
const debugPotty = debug.querySelector("span[name=p]");
|
2024-06-24 23:21:00 -07:00
|
|
|
const debugMessCounter = debug.querySelector("span[name=mc]");
|
|
|
|
const debugHappiness = debug.querySelector("span[name=h]");
|
2024-06-21 11:58:15 -07:00
|
|
|
const forceUpdateButton = debug.querySelector("button#force-update");
|
2024-06-24 23:21:00 -07:00
|
|
|
const resetButton = debug.querySelector("button#reset");
|
|
|
|
|
|
|
|
let canFeed = true;
|
|
|
|
let canPet = true;
|
|
|
|
let canClean = true;
|
2024-06-21 11:58:15 -07:00
|
|
|
|
2024-06-25 00:02:11 -07:00
|
|
|
/**
|
|
|
|
* generates a random number within the given range
|
|
|
|
* @param {number} min the minimum number for the random generation
|
|
|
|
* @param {number} max the maximum number for the random generation
|
|
|
|
* @returns the generated number
|
|
|
|
*/
|
|
|
|
function rand(min, max) {
|
|
|
|
return Math.random() * (max - min) + min;
|
|
|
|
}
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
/**
|
|
|
|
* class containing information about a pet
|
|
|
|
*/
|
|
|
|
class Pet {
|
|
|
|
/** current pet version */
|
|
|
|
version = CURRENT_PET_VERSION;
|
|
|
|
/** whether the pet can die or not */
|
|
|
|
canDie = false;
|
|
|
|
/** whether the pet is alive or dead */
|
|
|
|
alive = true;
|
|
|
|
/** whether the pet simulation is paused */
|
|
|
|
paused = false;
|
2024-06-24 23:21:00 -07:00
|
|
|
/** whether the pet simulation needs an interactive advancement */
|
|
|
|
needsAdvancement = false;
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the pet's current life stage */
|
|
|
|
lifeStage = LIFE_STAGE_EGG;
|
|
|
|
/** the pet's name */
|
|
|
|
name = "";
|
|
|
|
/** how much food the pet has stored */
|
|
|
|
food = MAX_FOOD;
|
|
|
|
/** the pet's age */
|
|
|
|
age = 0;
|
|
|
|
/** the pet's behavior score */
|
|
|
|
behavior = 0;
|
|
|
|
/** how long until the pet needs to go potty */
|
|
|
|
pottyTimer = POTTY_TIME;
|
2024-06-24 23:21:00 -07:00
|
|
|
/** how much mess the pet has made */
|
|
|
|
messCounter = 0;
|
|
|
|
/** the pet's current happiness */
|
2024-06-24 23:24:19 -07:00
|
|
|
_happiness = MAX_HAPPINESS;
|
2024-06-21 11:58:15 -07:00
|
|
|
/** the time the pet was last updated */
|
|
|
|
lastUpdate = Date.now();
|
|
|
|
/** the time the egg was found */
|
|
|
|
eggFound = Date.now();
|
|
|
|
/** the time the egg hatched */
|
|
|
|
hatched = Date.now();
|
2024-06-25 00:02:11 -07:00
|
|
|
/** the pet's type */
|
|
|
|
type = PET_TYPES[Math.floor(rand(0, PET_TYPES.length))];
|
2024-06-25 00:15:19 -07:00
|
|
|
/** the pet's color */
|
|
|
|
color = `rgb(${rand(0, 255)}, ${rand(0, 255)}, ${rand(0, 255)})`;
|
|
|
|
/** the pet's scaled width */
|
|
|
|
scaleWidth = rand(0.6, 1.4);
|
|
|
|
/** the pet's scaled height */
|
|
|
|
scaleHeight = rand(0.6, 1.4);
|
2024-06-21 11:58:15 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* updates a pet
|
|
|
|
*/
|
|
|
|
update() {
|
2024-06-24 23:21:00 -07:00
|
|
|
if (!this.alive || this.paused || this.needsAdvancement) {
|
2024-06-21 11:58:15 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
console.log("update");
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
this.lastUpdate = Date.now();
|
2024-06-21 11:58:15 -07:00
|
|
|
this.age += AGING_RATE;
|
|
|
|
|
|
|
|
if (this.lifeStage !== LIFE_STAGE_EGG) {
|
|
|
|
this.food -= FOOD_DECAY;
|
|
|
|
this.pottyTimer -= POTTY_DECAY;
|
2024-06-24 23:21:00 -07:00
|
|
|
this.happiness -= HAPPINESS_DECAY;
|
2024-06-21 11:58:15 -07:00
|
|
|
|
|
|
|
if (this.food < 0) {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.happiness += HAPPINESS_EMPTY_STOMACH_MODIFIER;
|
|
|
|
this.food = 0;
|
2024-06-21 11:58:15 -07:00
|
|
|
if (this.canDie) {
|
|
|
|
// TODO: pet dies
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-25 13:48:56 -07:00
|
|
|
if (this.happiness <= 0) {
|
|
|
|
this.behavior -= BEHAVIOR_UNHAPPY_MODIFIER;
|
|
|
|
}
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
if (this.pottyTimer < 0) {
|
|
|
|
this.goPotty();
|
|
|
|
}
|
2024-06-24 23:21:00 -07:00
|
|
|
for (let i = 0; i < this.messCounter; i++) {
|
|
|
|
this.happiness += HAPPINESS_MESS_MODIFIER;
|
|
|
|
}
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.lifeStage === LIFE_STAGE_EGG && this.age >= EGG_TIME) {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.needsAdvancement = true;
|
2024-06-21 11:58:15 -07:00
|
|
|
this.lifeStage = LIFE_STAGE_PUP;
|
|
|
|
this.age = 0;
|
|
|
|
} else if (this.lifeStage === LIFE_STAGE_PUP && this.age >= PUP_TIME) {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.needsAdvancement = true;
|
2024-06-21 11:58:15 -07:00
|
|
|
this.lifeStage = LIFE_STAGE_ADULT;
|
|
|
|
this.age = 0;
|
|
|
|
} else if (
|
|
|
|
this.lifeStage === LIFE_STAGE_ADULT &&
|
|
|
|
this.age >= ADULT_TIME
|
|
|
|
) {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.needsAdvancement = true;
|
2024-06-21 11:58:15 -07:00
|
|
|
this.lifeStage = LIFE_STAGE_ELDER;
|
|
|
|
this.age = 0;
|
|
|
|
} else if (
|
|
|
|
this.lifeStage === LIFE_STAGE_ELDER &&
|
|
|
|
this.age >= ELDER_TIME
|
|
|
|
) {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.needsAdvancement = true;
|
2024-06-21 11:58:15 -07:00
|
|
|
this.alive = false;
|
|
|
|
// TODO: DEATH
|
|
|
|
}
|
|
|
|
this.updateDom();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* updates the html dom
|
|
|
|
*/
|
|
|
|
updateDom() {
|
|
|
|
eggDiv.classList.add("hidden");
|
|
|
|
petSetup.classList.add("hidden");
|
2024-06-24 23:21:00 -07:00
|
|
|
hatchedActions.classList.remove("hidden");
|
2024-06-21 11:58:15 -07:00
|
|
|
|
2024-06-25 00:02:11 -07:00
|
|
|
thePet.classList.remove("egg");
|
|
|
|
thePet.classList.remove("pup");
|
|
|
|
thePet.classList.remove("adult");
|
|
|
|
thePet.classList.remove("elder");
|
|
|
|
thePet.classList.remove("dead");
|
|
|
|
|
2024-06-25 00:42:10 -07:00
|
|
|
statusHungry.classList.add("hidden");
|
|
|
|
statusStarving.classList.add("hidden");
|
|
|
|
statusUnhappy.classList.add("hidden");
|
|
|
|
statusMessy1.classList.add("hidden");
|
|
|
|
statusMessy2.classList.add("hidden");
|
|
|
|
statusMessy3.classList.add("hidden");
|
|
|
|
|
2024-06-25 00:15:19 -07:00
|
|
|
let width = 0;
|
|
|
|
let height = 0;
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
if (this.lifeStage === LIFE_STAGE_EGG) {
|
|
|
|
eggDiv.classList.remove("hidden");
|
2024-06-24 23:21:00 -07:00
|
|
|
hatchedActions.classList.add("hidden");
|
2024-06-25 00:02:11 -07:00
|
|
|
|
|
|
|
thePet.classList.add("egg");
|
2024-06-21 11:58:15 -07:00
|
|
|
} else if (this.lifeStage === LIFE_STAGE_PUP) {
|
2024-06-24 23:21:00 -07:00
|
|
|
if (this.needsAdvancement) {
|
2024-06-21 11:58:15 -07:00
|
|
|
petSetup.classList.remove("hidden");
|
|
|
|
}
|
2024-06-25 00:02:11 -07:00
|
|
|
|
|
|
|
thePet.classList.add("pup");
|
2024-06-25 00:15:19 -07:00
|
|
|
width = WIDTH_PUP;
|
|
|
|
height = HEIGHT_PUP;
|
2024-06-21 11:58:15 -07:00
|
|
|
} else if (this.lifeStage === LIFE_STAGE_ADULT) {
|
2024-06-24 23:21:00 -07:00
|
|
|
if (this.needsAdvancement) {
|
|
|
|
adultInfo.classList.remove("hidden");
|
|
|
|
}
|
2024-06-25 00:02:11 -07:00
|
|
|
|
|
|
|
thePet.classList.add("adult");
|
2024-06-25 00:15:19 -07:00
|
|
|
width = WIDTH_ADULT;
|
|
|
|
height = HEIGHT_ADULT;
|
2024-06-21 11:58:15 -07:00
|
|
|
} else if (this.lifeStage === LIFE_STAGE_ELDER) {
|
2024-06-24 23:21:00 -07:00
|
|
|
if (this.needsAdvancement) {
|
|
|
|
if (this.alive) {
|
|
|
|
elderInfo.classList.remove("hidden");
|
|
|
|
} else {
|
|
|
|
passedAwayInfo.classList.remove("hidden");
|
2024-06-25 00:02:11 -07:00
|
|
|
|
|
|
|
thePet.classList.add("elder");
|
2024-06-25 00:15:19 -07:00
|
|
|
width = WIDTH_ELDER;
|
|
|
|
height = HEIGHT_ELDER;
|
2024-06-24 23:21:00 -07:00
|
|
|
}
|
|
|
|
}
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
|
2024-06-25 00:15:19 -07:00
|
|
|
width *= this.scaleWidth;
|
|
|
|
height *= this.scaleHeight;
|
|
|
|
|
|
|
|
thePet.style.setProperty("--width", `${width}px`);
|
|
|
|
thePet.style.setProperty("--height", `${height}px`);
|
|
|
|
thePet.style.setProperty("--color", this.color);
|
2024-06-25 00:55:06 -07:00
|
|
|
let happinessFilter = 1 - this.happiness / MAX_HAPPINESS;
|
|
|
|
if (happinessFilter < 0.6) {
|
|
|
|
happinessFilter = 0;
|
|
|
|
}
|
|
|
|
happinessFilter = (happinessFilter - 0.6) * 2.5;
|
|
|
|
if (happinessFilter < 0) {
|
|
|
|
happinessFilter = 0;
|
|
|
|
}
|
|
|
|
thePet.style.setProperty(
|
|
|
|
"filter",
|
|
|
|
`grayscale(${happinessFilter * 100}%)`
|
|
|
|
);
|
2024-06-25 00:15:19 -07:00
|
|
|
|
2024-06-25 00:02:11 -07:00
|
|
|
if (!this.alive) {
|
|
|
|
thePet.classList.add("dead");
|
|
|
|
} else if (this.lifeStage !== LIFE_STAGE_EGG) {
|
|
|
|
thePet.classList.add(this.type);
|
2024-06-25 00:42:10 -07:00
|
|
|
|
|
|
|
if (this.food <= MAX_FOOD / 10) {
|
|
|
|
statusStarving.classList.remove("hidden");
|
|
|
|
} else if (this.food <= MAX_FOOD / 2) {
|
|
|
|
statusHungry.classList.remove("hidden");
|
|
|
|
}
|
|
|
|
if (this.happiness <= MAX_HAPPINESS / 3) {
|
|
|
|
statusUnhappy.classList.remove("hidden");
|
|
|
|
}
|
|
|
|
if (this.messCounter >= MAX_MESS) {
|
|
|
|
statusMessy3.classList.remove("hidden");
|
|
|
|
} else if (this.messCounter >= MAX_MESS / 2) {
|
|
|
|
statusMessy2.classList.remove("hidden");
|
|
|
|
} else if (this.messCounter > 0) {
|
|
|
|
statusMessy1.classList.remove("hidden");
|
|
|
|
}
|
2024-06-25 00:02:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.paused) {
|
|
|
|
pauseButton.innerText = "unpause";
|
|
|
|
} else {
|
|
|
|
pauseButton.innerText = "pause";
|
|
|
|
}
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
debugLifeStage.innerText = this.lifeStage;
|
|
|
|
debugAge.innerText = this.age;
|
|
|
|
debugFood.innerText = this.food;
|
|
|
|
debugBehavior.innerText = this.behavior;
|
|
|
|
debugPotty.innerText = this.pottyTimer;
|
2024-06-24 23:21:00 -07:00
|
|
|
debugMessCounter.innerText = this.messCounter;
|
|
|
|
debugHappiness.innerText = this.happiness;
|
|
|
|
|
|
|
|
this.save();
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* feeds the pet
|
|
|
|
* @param {number} amount the amount to feed the pet by
|
|
|
|
*/
|
|
|
|
feed(amount) {
|
|
|
|
if (this.food > MAX_FOOD) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.food += amount;
|
2024-06-24 23:21:00 -07:00
|
|
|
if (this.food <= MAX_FOOD) {
|
|
|
|
this.happiness += FEED_HAPPINESS;
|
|
|
|
}
|
|
|
|
this.updateDom();
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* makes the pet go potty
|
|
|
|
*/
|
|
|
|
goPotty() {
|
2024-06-25 00:44:55 -07:00
|
|
|
if (this.behavior > 45) {
|
2024-06-21 11:58:15 -07:00
|
|
|
// go potty properly
|
|
|
|
} else {
|
2024-06-24 23:21:00 -07:00
|
|
|
this.messCounter += 1;
|
|
|
|
if (this.messCounter > MAX_MESS) {
|
|
|
|
this.messCounter = MAX_MESS;
|
|
|
|
}
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
this.pottyTimer = POTTY_TIME;
|
2024-06-24 23:21:00 -07:00
|
|
|
pet.updateDom();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* pets the pet
|
|
|
|
*/
|
|
|
|
pet() {
|
|
|
|
this.behavior += 0.5;
|
|
|
|
this.happiness += PET_HAPPINESS;
|
|
|
|
pet.updateDom();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cleans the pet's space
|
|
|
|
*/
|
|
|
|
clean() {
|
|
|
|
if (this.messCounter > 0) {
|
|
|
|
this.messCounter -= 1;
|
|
|
|
this.happiness += CLEAN_HAPPINESS;
|
|
|
|
} else {
|
|
|
|
this.behavior += 1;
|
|
|
|
this.happiness -= CLEAN_HAPPINESS;
|
|
|
|
}
|
|
|
|
pet.updateDom();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* saves the pet
|
|
|
|
*/
|
|
|
|
save() {
|
|
|
|
localStorage.setItem(PET_SAVE_KEY, JSON.stringify(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* loads the pet
|
|
|
|
*/
|
|
|
|
load() {
|
|
|
|
const item = localStorage.getItem(PET_SAVE_KEY);
|
|
|
|
if (item != undefined) {
|
|
|
|
const loaded = JSON.parse(localStorage.getItem(PET_SAVE_KEY));
|
|
|
|
for (let k of Object.keys(loaded)) {
|
|
|
|
this[k] = loaded[k];
|
|
|
|
}
|
|
|
|
this.version = CURRENT_PET_VERSION;
|
|
|
|
this.updateDom();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** whether the pet can be updated */
|
|
|
|
get canUpdate() {
|
|
|
|
return !this.paused && !this.needsAdvancement;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** the pet's happiness */
|
|
|
|
get happiness() {
|
2024-06-24 23:24:19 -07:00
|
|
|
return this._happiness;
|
2024-06-24 23:21:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
set happiness(amount) {
|
|
|
|
if (amount < 0) {
|
|
|
|
amount = 0;
|
|
|
|
} else if (amount > MAX_HAPPINESS) {
|
|
|
|
amount = MAX_HAPPINESS;
|
|
|
|
}
|
2024-06-24 23:24:19 -07:00
|
|
|
this._happiness = amount;
|
2024-06-21 11:58:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let pet = new Pet();
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
petSetup.addEventListener("submit", (e) => {
|
|
|
|
e.preventDefault();
|
2024-06-21 11:58:15 -07:00
|
|
|
const newName = name.value;
|
|
|
|
if (newName.trim().length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pet.name = newName;
|
2024-06-24 23:21:00 -07:00
|
|
|
for (let name of petName) {
|
|
|
|
name.innerText = pet.name;
|
|
|
|
}
|
|
|
|
pet.hatched = Date.now();
|
|
|
|
pet.needsAdvancement = false;
|
2024-06-21 11:58:15 -07:00
|
|
|
pet.updateDom();
|
|
|
|
});
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
feedButton.addEventListener("click", () => {
|
|
|
|
if (!canFeed || !pet.canUpdate) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
canFeed = false;
|
2024-06-25 00:44:21 -07:00
|
|
|
feedButton.disabled = true;
|
2024-06-24 23:21:00 -07:00
|
|
|
setTimeout(() => {
|
|
|
|
canFeed = true;
|
2024-06-25 00:44:21 -07:00
|
|
|
feedButton.disabled = false;
|
2024-06-24 23:21:00 -07:00
|
|
|
}, FEED_TIMER);
|
|
|
|
|
|
|
|
pet.feed(38);
|
|
|
|
});
|
|
|
|
|
|
|
|
petButton.addEventListener("click", () => {
|
|
|
|
if (!canPet || !pet.canUpdate) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
canPet = false;
|
2024-06-25 00:44:21 -07:00
|
|
|
petButton.disabled = true;
|
2024-06-24 23:21:00 -07:00
|
|
|
setTimeout(() => {
|
|
|
|
canPet = true;
|
2024-06-25 00:44:21 -07:00
|
|
|
petButton.disabled = false;
|
2024-06-24 23:21:00 -07:00
|
|
|
}, PET_TIMER);
|
|
|
|
|
|
|
|
pet.pet();
|
|
|
|
});
|
|
|
|
|
|
|
|
cleanButton.addEventListener("click", () => {
|
|
|
|
if (!canClean || !pet.canUpdate) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
canClean = false;
|
2024-06-25 00:44:21 -07:00
|
|
|
cleanButton.disabled = true;
|
2024-06-24 23:21:00 -07:00
|
|
|
setTimeout(() => {
|
|
|
|
canClean = true;
|
2024-06-25 00:44:21 -07:00
|
|
|
cleanButton.disabled = false;
|
2024-06-24 23:21:00 -07:00
|
|
|
}, CLEAN_TIMER);
|
|
|
|
|
|
|
|
pet.clean();
|
|
|
|
});
|
|
|
|
|
2024-06-25 00:02:11 -07:00
|
|
|
pauseButton.addEventListener("click", () => {
|
|
|
|
pet.paused = !pet.paused;
|
|
|
|
pet.updateDom();
|
|
|
|
});
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
const advance = () => {
|
|
|
|
pet.needsAdvancement = false;
|
|
|
|
pet.updateDom();
|
|
|
|
};
|
|
|
|
for (let btn of document.querySelectorAll("button.advancement")) {
|
|
|
|
btn.addEventListener("click", advance);
|
|
|
|
}
|
|
|
|
|
2024-06-24 23:24:19 -07:00
|
|
|
passedAwayInfo.querySelector("button").addEventListener("click", () => {
|
|
|
|
pet = new Pet();
|
|
|
|
pet.updateDom();
|
|
|
|
});
|
|
|
|
|
2024-06-21 11:58:15 -07:00
|
|
|
const update = () => {
|
|
|
|
pet.update();
|
|
|
|
};
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
setInterval(update, 60000 / UPDATES_PER_MINUTE);
|
2024-06-21 11:58:15 -07:00
|
|
|
|
|
|
|
forceUpdateButton.addEventListener("click", update);
|
2024-06-24 23:21:00 -07:00
|
|
|
resetButton.addEventListener("click", () => {
|
2024-06-25 00:02:11 -07:00
|
|
|
thePet.classList.remove(pet.type);
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
pet = new Pet();
|
|
|
|
pet.updateDom();
|
|
|
|
});
|
|
|
|
|
|
|
|
pet.load();
|
|
|
|
|
|
|
|
for (let name of petName) {
|
|
|
|
name.innerText = pet.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (document.body.classList.contains("debug")) {
|
|
|
|
debug.classList.remove("hidden");
|
2024-06-25 00:42:10 -07:00
|
|
|
document.pet = pet;
|
2024-06-24 23:21:00 -07:00
|
|
|
}
|
|
|
|
|
2024-06-25 13:46:44 -07:00
|
|
|
const updates = Math.floor(
|
|
|
|
(Date.now() - pet.lastUpdate) / (60000 / UPDATES_PER_MINUTE)
|
|
|
|
);
|
|
|
|
for (let i = 0; i < updates; i++) {
|
|
|
|
pet.update();
|
|
|
|
}
|
|
|
|
|
2024-06-24 23:21:00 -07:00
|
|
|
pet.updateDom();
|
2024-06-21 11:58:15 -07:00
|
|
|
|
|
|
|
console.log(pet);
|
|
|
|
})();
|