// Define humanTime function function humanTime (time) { var days = (((Math.abs(time)/1000)/60)/60)/24; var hours = (days%1)*24; var minutes = (hours%1)*60; var seconds = (minutes%1)*60; return (1 < days ? Math.floor(days)+"D " : "") + (1 < hours ? Math.floor(hours).toString().padStart(2,"0")+":": "") + ( 1 < minutes ? Math.floor(minutes).toString().padStart(2,"0")+":" : "")+ Math.floor(seconds).toString().padStart(2,"0") ; } // Define RNA validator function function validateRna (rna) { rna = "object" == typeof rna ? rna : {}; rna.healthMax = "number" == typeof rna.healthMax ? rna.healthMax : Math.floor(Math.random()*25)+75; rna.stomachMax = "number" == typeof rna.stomachMax ? rna.stomachMax : Math.floor(Math.random()*25)+25; rna.hydrationMax = "number" == typeof rna.hydrationMax ? rna.hydrationMax : Math.floor(Math.random()*90)+10; rna.nurishmentMax = "number" == typeof rna.nurishmentMax ? rna.nurishmentMax : Math.floor(Math.random()*90)+10; rna.thirstRate = "number" == typeof rna.thirstRate ? rna.thirstRate : 300000; rna.hungerRate = "number" == typeof rna.hungerRate ? rna.hungerRate : 300000; return rna; } // Define RNA to DNA function function rna2dna (motherRna,fatherRna) { return dna = [validateRna(motherRna),validateRna(fatherRna)]; } // Define DNA to RNA function function dna2rna (dna) { var rna = validateRna({ "healthMax":dna[Math.floor(Math.random())].healthMax, "stomachMax":dna[Math.floor(Math.random())].stomachMax, "hydrationMax":dna[Math.floor(Math.random())].hydrationMax, "nurishmentMax":dna[Math.floor(Math.random())].nurishmentMax, "thirstRate":dna[Math.floor(Math.random())].thirstRate, "hungerRate":dna[Math.floor(Math.random())].hungerRate }); return rna; } // Define item class class item { constructor (itemDef) { this.id = -1; this.name = "Azathoth"; this.desc = "Unknowable"; this.countInc = 1; this.action = function () { return 0; }; if ("object" == typeof itemDef) { if ("number" == typeof itemDef.id) { this.id = itemDef.id; } if ("string" == typeof itemDef.name) { this.name = itemDef.name; } if ("string" == typeof itemDef.desc) { this.desc = itemDef.desc; } if ("number" == typeof itemDef.countInc) { this.countInc = itemDef.countInc; } if ("function" == typeof itemDef.action) { this.action = itemDef.action; } } } }; // Define inventory class class inventory { constructor () { var me = this; this.update = false; this.contents = []; this.addItem = function (itemID,amount,overrides) { if ("number" != typeof amount) { amount = 1;} var exsistingItem = me.contents.findIndex( function (item) { return item.id == itemID; }); if (exsistingItem >= 0) { me.contents[exsistingItem].count += amount; } else { me.contents.push(new item(petGame.itemDB[itemID])); me.contents[me.contents.length-1].count = amount; if ("object" == typeof overrides) { if ("string" == typeof overrides.name) { me.contents[me.contents.length-1].name = overrides.name; } if ("string" == typeof overrides.desc) { me.contents[me.contents.length-1].desc = overrides.desc; } if ("number" == typeof overrides.countInc) { me.contents[me.contents.length-1].countInc = overrides.countInc; } if ("function" == typeof overrides.action) { me.contents[me.contents.length-1].action = overrides.action; } } } me.update = true; }; this.useItem = function (itemIndex,actionBool) { if (actionBool) { me.contents[itemIndex].action(); } me.contents[itemIndex].count -= me.contents[itemIndex].countInc; if (me.contents[itemIndex].count <= 0) { me.contents.splice(itemIndex,1); } me.update = true; }; this.getBasic = function (info) { return me.contents.map( function (item) { return item[info]; } ); }; this.getEssentials = function () { return me.contents.map( function (item) { return {"id":item.id,"count":item.count}; }); }; } }; // Define Pet class class pet { constructor (mother,father) { var me = this; this.dna = rna2dna(mother,father); this.activeRna = dna2rna(this.dna); this.birth = performance.now(); this.healthMax = this.activeRna.healthMax + (Math.floor(Math.random()*20)-10); this.stomachMax = this.activeRna.stomachMax + (Math.floor(Math.random()*10)-5); this.hydrationMax = this.activeRna.hydrationMax + (Math.floor(Math.random()*10)-5); this.thirstRate = this.activeRna.thirstRate + (Math.floor(Math.random()*120000)-60000); this.nurishmentMax = this.activeRna.nurishmentMax + (Math.floor(Math.random()*10)-5); this.hungerRate = this.activeRna.hungerRate + (Math.floor(Math.random()*120000)-60000); this.health = this.healthMax; this.stomach = 0; this.hydration = this.hydrationMax; this.nurishment = this.nurishmentMax; this.affection = 0; this.mood = 0; this.name = "pet"+Math.floor(this.birth); this.gender = Math.round(Math.random()); this.ageStart = this.birth.valueOf(); this.age = 0; this.dirty = 0; this.lastPoop = this.birth; this.busyUntil = this.birth; this.currentAction = null; this.dead = false; this.tick = function (deltaT) { var oldMood = me.mood; me.mood = 0; me.hydration -= deltaT/me.thirstRate; me.nurishment -= deltaT/me.hungerRate; if (me.hydrationMax / 2 >= me.hydration) { //Attempt to drink me.takeAction(function () { return me.intake("water"); }, 5000, "drinking",true); } if (me.nurishmentMax / 2 >= me.nurishment) { //Attempt to eat me.takeAction(function () { return me.intake("food"); }, 5000, "eating",true); } me.mood += me.hydration < 0 ? me.hydration : 0; me.health += me.hydration < 0 ? me.hydration : 0; me.hydration = me.hydration > 0 ? me.hydration : 0; me.mood += me.nurishment < 0 ? me.nurishment : 0; me.health += me.nurishment < 0 ? me.nurishment : 0; me.nurishment = me.nurishment > 0 ? me.nurishment : 0; var poops = Math.floor(me.stomach / 10); if (poops) { var time = Math.floor((performance.now() - me.lastPoop) / 25000); if (time > poops) { me.dirty += poops/10; me.stomach -= 10 * poops; me.lastPoop = performance.now(); petGame.gui.player.pets.update = true; } else { me.dirty += time/10; me.stomach -= 10 * time; } } if (0 >= me.stomach) { me.stomach = 0; } me.mood -= me.dirty*(deltaT/30000); me.affection += ((oldMood + me.mood)/2)*(deltaT/30000); if (performance.now() >= me.ageStart+(Math.pow(me.age+1,2)*1800000)) { me.age++; me.ageStart = performance.now(); petGame.log.messageAdd(me.name+" has grown!",2); } if (10 < me.age) { // Death from old age me.dead = true; me.tick = function () {return 0;}; petGame.log.messageAdd(me.name+" has died of old age.",2); } if (0 >= me.health) { //Death from health loss me.dead = true; me.tick = function () { return 0; }; petGame.log.messageAdd(me.name+" has died from health loss", 2); } if ((me.busyUntil <= performance.now()) && ("string" == typeof me.currentAction)) { petGame.log.messageAdd(me.name+" has finished "+me.currentAction); me.currentAction = null; petGame.gui.player.pets.update = true; if (true == me.selected) { petGame.player.actions.update = true; } } }; this.intake = function (type) { if (("string" != typeof type) || ("water" != type && "food" != type)) { console.error("intake: invalid type given to intake: "+type); return 0;} var max = "water" == type ? "hydrationMax" : "nurishmentMax"; var current = "water" == type ? "hydration" : "nurishment"; var def = me[max] - Math.ceil(me[current]); var sdef = me.stomachMax - Math.ceil(me.stomach); var amount = def <= sdef ? def : def - (def - sdef); if (petGame.player[type] > 0) { if (petGame.player[type] >= amount) { petGame.player[type] -= amount; me[current] += amount; me.stomach += amount; return [2, amount]; } else { me[current] += petGame.player[type]; me.stomach += petGame.player[type]; petGame.player[type] = 0; return 3; } } else { return 4; } }; this.takeAction = function (action, actionTime,actionString,silent) { if ("function" != typeof action) { console.error("given action is not a function"); return 0; } if ("number" != typeof actionTime) { actionTime = 10000; } if ("string" != typeof actionString) { actionString = "something"; } console.log(performance.now()+"-"+me.busyUntil); petGame.gui.player.pets.update = true; if (0 <= performance.now() - me.busyUntil){ var result = action(); if (0 == result) { return 0; } petGame.log.messageAdd(me.name+" began "+actionString); me.currentAction = actionString; me.busyUntil = performance.now()+actionTime; if (true == me.selected) { petGame.player.actions.update = true; } return result; } else { if (silent) {} else { petGame.log.messageAdd(me.name+" is busy right now."); } return 1; } }; this.feed = function () { var result = me.takeAction(function () { return me.intake("food"); },10000,"eating"); if ("number" == typeof result) { if (3 == result) { petGame.log.messageAdd("You fed "+me.name+" your remaining food."); } if (4 == result) { petGame.log.messageAdd("You have no food to give "+me.name, 1); } if (0 == result) { return console.error("Something went wrong");} } if ("object" == typeof result) { if (2 == result[0]) { petGame.log.messageAdd("You fed "+me.name+" "+result[1]+" food."); } } return result; }; this.water = function () { var result = me.takeAction(function () { return me.intake("water"); },10000,"drinking"); if ("number" == typeof result) { if (3 == result) { petGame.log.messageAdd("You gave "+me.name+" your remaining water."); } if (4 == result) { petGame.log.messageAdd("You have no water to give "+me.name, 1); } if (0 == result) { return console.error("Something went wrong");} } if ("object" == typeof result) { if (2 == result[0]) { petGame.log.messageAdd("You gave "+me.name+" "+result[1]+" water."); } } return result; }; this.play = function () { var result = me.takeAction(function () { me.mood+=50*(1+(function (a) {return a.length > 0 ? a.reduce(function (a,b) { return a + b;}) : 0})(petGame.player.inventory.contents.filter(function (item) { return (item.id == 4 || item.id == 5)}).map(function (item) { return item.count}))); return 2; }, 10000, "playing"); return result; }; this.sleep = function () { var result = me.takeAction(function () { var dif = me.healthMax - me.health; if (20 <= dif) { me.health += 20; } else { me.mood += (me.health+20)-me.healthMax; me.health = me.healthMax; } return 2; },30000,"sleeping"); return result; }; this.walk = function () { var result = me.takeAction(function () { me.mood+=20; me.health-=20; if(25 >= Math.floor(Math.random()*100)) { petGame.log.messageAdd("While out walking, "+me.name+" found something"); petGame.player.giveItem(5); } return 2; },10000,"walking"); return result; }; this.clean = function () { var result = me.takeAction(function () { me.dirty = 0; me.mood+=10; return 2; },10000,"bathing"); return result; }; this.rename = function () { me.name = window.prompt("What would you like to change "+me.name+"'s name to?",me.name)}; petGame.gui.player.pets.update = true; } } // Define main game object and its imidiate children window.petGame = {}; petGame.start = performance.now(); petGame.current = petGame.start; petGame.player = {}; petGame.log = {}; petGame.market = {}; petGame.eventDB = []; petGame.eventCountdown = 300000; petGame.itemDB = []; // Define player object and its children petGame.player.inventory = new inventory(); petGame.player.pets = []; petGame.player.water = 0; petGame.player.food = 0; petGame.player.coins = 0; petGame.player.actions = {}; petGame.player.give = function (type,amount) { if ("string" != typeof type) { return console.error("type must be string but was:"+(typeof type)); } if ("number" != typeof amount) { return console.error("amount must be number but was:"+(typeof amount)); } petGame.player[type] += amount; } petGame.player.giveItem = function (itemID,amount) { petGame.player.inventory.addItem(itemID,amount); } petGame.gui = {}; // Define log object and its children petGame.log.queue = []; petGame.log.messageAdd = function (message, priority, life) { if (petGame.log.queue.length >= 50) { petGame.log.queue.shift(); } message = "string" == typeof message ? message : "No message proveded?"; priority = "number" == typeof priority ? priority : 0; life = "number" == typeof life ? life : 600000; petGame.log.queue.push({"message":message, "priority":priority, "life":performance.now()+life}); petGame.log.update = true; } petGame.log.clean = function () { petGame.log.queue.forEach( function (message, index, queue) { if (performance.now() > message.life) { queue.splice(index,1); petGame.log.update = true; } }); } // Define market object and its children petGame.market.exchangeRate = 1; petGame.market.inventory = new inventory(); petGame.market.coins = 0; petGame.market.addItem = function (itemID,amount,override) { petGame.market.inventory.addItem(itemID,amount,override); } // Build eventDB database petGame.eventDB = [ {"chance":90,"action":function () { petGame.log.messageAdd("A stranger gives you some money, weird..."); petGame.player.give("coins",Math.floor(Math.random()*100)); }}, {"chance":3,"action":function () { petGame.log.messageAdd("A strange new egg appeared in the market."); petGame.market.addItem(3);; }}, {"chance":10,"action":function () { petGame.log.messageAdd("The market has more eggs!"); petGame.market.addItem(0,5); }}, {"chance":40,"action":function () { petGame.log.messageAdd("You find a toy on the ground, maybe your pets will have more fun playing now."); petGame.player.giveItem(4); }}, {"chance":30,"action":function () { petGame.log.messageAdd("The market has more food and water!"); petGame.market.addItem(1,5); petGame.market.addItem(2,5); }}, {"chance":3,"action":function () { petGame.log.messageAdd("The market has a Nexus for sale"); petGame.market.addItem(6,1); }}, ]; // Build itemDB database petGame.itemDB = [ {"id":0,"name":"Egg","cost":300,"countInc":1,"desc":"This is a pet egg, when you use it, it will hatch into a new pet.","action": function () { return petGame.player.pets.push(new pet()); }}, {"id":1,"name":"Water","cost":50,"countInc":1,"desc":"A package of water, use this to add more water to your supply.","action": function () { return petGame.player.give("water",100); }}, {"id":2,"name":"Food","cost":50,"countInc":1,"desc":"A package of food, use this to add more food to your supply.","action": function () { return petGame.player.give("food",100); }}, {"id":3,"name":"SEgg","cost":50000,"countInc":1,"desc":"This pet egg seems different than others, it seems stronger.","action": function () { return petGame.player.pets.push(new pet({ "healthMax":200, "stomachMax":200, "nutritionMax":200, "hydrationMax":200, "hungerRate":12000000, "thirstRate":12000000 },{ }));; }}, {"id":4,"name":"Toy","cost":100,"countInc":0,"desc":"This is a pet toy, the more of them you have for your pets to play with, the more affection you will gain each time you play with your pets.","action": function () { return petGame.log.messageAdd("It doesnt seem all that fun to you, but your pets sure enjoy it."); }}, {"id":5,"name":"Treasure","cost":500,"countInc":1,"desc":"A buried treasure, sell it for more coins or keep it for more bonus affection from your pets when you play with them.","action": function () { petGame.player.give("coins",500); petGame.market.addItem(5); return petGame.log.messageAdd("You have sold the treasure"); }}, {"id":6,"name":"Nexus","cost":1000,"countInc":1,"desc":"A nexus allows you to breed two pets of the opposite gender that are at least age 5.","action": function () { if ((1 <= petGame.player.pets.filter(function (pet) {if ((1 == pet.gender) && (5 <= pet.age)) { return {"name":pet.name,"dna":pet.dna}; } else { return false; }}).length) && (1 <= petGame.player.pets.filter(function (pet) {if ((0 == pet.gender) && (5 <= pet.age)) { return {"name":pet.name,"dna":pet.dna}; } else { return false; }}).length)) { popupDialog("breed","New Egg cross Unity System (N.E.X.U.S)",false,function (dialogRoot,container,args) { container.innerHTML = args.content; var father = elementPlace("#"+container.id, null, "nexus_father", "select"); args.malesOfAge.forEach(function (pet,index) {father.innerHTML += '';}); var mother = elementPlace("#"+container.id,null, "nexus_mother", "select"); args.femalesOfAge.forEach(function (pet,index) {mother.innerHTML += '';}); buttonAdd("#"+container.id,null,"Breed",function () { if (("number" != typeof parseInt(father.value)) || ("number" != typeof parseInt(mother.value))) { petGame.player.giveItem(6); petGame.log.messageAdd("Your Nexus was not provided good information, try again or wait till later"); } else { petGame.player.pets.push(new pet(dna2rna(args.malesOfAge[parseInt(father.value)].dna),dna2rna(args.femalesOfAge[parseInt(mother.value)].dna))); } dialogRoot.parentNode.removeChild(dialogRoot); },"dialog_button","div"); buttonAdd("#"+container.id,null,"Cancel",function () { petGame.player.giveItem(6); dialogRoot.parentNode.removeChild(dialogRoot); },"dialog_button","div"); },{ "content":"Please select the pets you wish to breed:", "malesOfAge":petGame.player.pets.filter(function (pet) {if ((1 == pet.gender) && (5 <= pet.age)) { return {"name":pet.name,"dna":pet.dna}; } else { return false; }}), "femalesOfAge":petGame.player.pets.filter(function (pet) {if ((0 == pet.gender) && (5 <= pet.age)) { return {"name":pet.name,"dna":pet.dna}; } else { return false; }}) }); } else { petGame.log.messageAdd("You don't have enough pets of the right age or gender to use this..."); petGame.player.giveItem(6); } }}, ]; // Define petGame.gui init function petGame.gui.init = function () { window.document.body.innerHTML = null; petGame.gui.player = titledContainer("body","player",null,"div",null,"Player:"); petGame.gui.player.stats = titledContainer("#player","playerStats",null,"ul",null,"Stats:"); petGame.gui.player.stats.water = elementPlace("#playerStats",null,"playerStat water","li"); petGame.gui.player.stats.food = elementPlace("#playerStats",null,"playerStat food","li"); petGame.gui.player.stats.coins = elementPlace("#playerStats",null,"playerStat coins","li"); petGame.gui.player.inventory = titledContainer("#player","playerInv","inventory","ul",null,"Inventory:"); petGame.gui.player.actions = titledContainer("#player","playerActions","actions","ul",null,"Actions:"); petGame.gui.player.pets = titledContainer("#player","playerPets",null,"div",null,"Pets:"); petGame.gui.player.pets.update = true; petGame.gui.info = elementPlace("body","info",null,"div"); petGame.gui.info.log = titledContainer("#info","infoLog",null,"ul",null,"Event Log:"); petGame.gui.info.market = titledContainer("#info","infoMarket","inventory","ul",null,"Market:"); } // Define gui update function petGame.gui.update = function () { petGame.gui.player.stats.water.innerText = "Water: "+numberShorten(petGame.player.water); petGame.gui.player.stats.food.innerText = "Food: "+numberShorten(petGame.player.food); petGame.gui.player.stats.coins.innerText = "Coins: "+numberShorten(petGame.player.coins); if (petGame.player.inventory.update) { petGame.gui.player.inventory.innerHTML = null; petGame.player.inventory.contents.forEach(function (item,itemIndex) { var itemGui = elementPlace("#playerInv",null,"item item"+item.name,"li"); itemGui.innerHTML =''+ item.name+''+numberShorten(item.count)+''+item.desc+''; itemGui.onclick = function () { petGame.player.inventory.useItem(itemIndex,true); }; }); petGame.player.inventory.update = false; } if (true == petGame.gui.player.pets.update) { petGame.gui.player.pets.innerHTML = null; petGame.player.pets.forEach(function (pet,index) { petGame.gui.player.pets["pet_"+index] = elementPlace("#playerPets","pet_"+pet.name, "pet gender"+pet.gender, "div"); var petGUI = petGame.gui.player.pets["pet_"+index]; petGUI.name = elementPlace("#pet_"+pet.name, null, "petName", "span"); petGUI.name.innerText = pet.name; if (false == pet.dead) { petGUI.age = elementPlace("#pet_"+pet.name, null, "petAge", "span"); petGUI.age.innerText = "Age: "+pet.age; petGUI.affection = elementPlace("#pet_"+pet.name, null, "petAffection", "span"); petGUI.affection.innerText = "Love: "+(Math.sign(pet.affection)*Math.floor(Math.pow(Math.abs(pet.affection),1/7))); petGUI.health = elementPlace("#pet_"+pet.name, null, "petHealth", "span"); petGUI.health.innerText = "health: "+Math.ceil(pet.health)+"/"+pet.healthMax; petGUI.hydration = elementPlace("#pet_"+pet.name, null, "petHydration", "span"); petGUI.hydration.innerText = "Hydration: "+Math.ceil(pet.hydration)+"/"+pet.hydrationMax; petGUI.nurishment = elementPlace("#pet_"+pet.name, null, "petNurishment", "span"); petGUI.nurishment.innerText = "Nurishment: "+Math.ceil(pet.nurishment)+"/"+pet.nurishmentMax; petGUI.stomach = elementPlace("#pet_"+pet.name, null, "petStomach", "span"); petGUI.stomach.innerText = "Stomach: "+Math.ceil(pet.stomach)+"/"+pet.stomachMax; if ("string" == typeof pet.currentAction) { petGUI.action = elementPlace("#pet_"+pet.name, null, "petAction", "span"); petGUI.action.innerText = humanTime(pet.busyUntil - performance.now()); petGUI.action.classList.add(pet.currentAction); } if (0 < pet.dirty) { petGUI.poop = elementPlace("#pet_"+pet.name, null, "petPoop", "span"); petGUI.poop.innerText = "Poop: "+Math.ceil(pet.dirty); } if (pet.selected) { petGUI.classList.add("selected"); } else { petGUI.onclick = function () { petGame.player.pets.forEach(function (p) { p.selected = false;}); petGame.player.actions.available = [ { "name":"Rename", "action":pet.rename, "petPointer": pet }, { "name":"Feed", "action":pet.feed, "petPointer": pet }, { "name":"Water", "action":pet.water, "petPointer": pet }, { "name":"Play", "action":pet.play, "petPointer": pet }, { "name":"Walk", "action":pet.walk, "petPointer": pet }, { "name":"Sleep", "action":pet.sleep, "petPointer": pet }, { "name":"Clean", "action":pet.clean, "petPointer": pet }, ]; petGame.player.actions.update = true; petGame.gui.player.pets.update = true; pet.selected = true; }; } } else { petGUI.name.innerHTML += '

RIP

'; petGUI.classList.add("dead"); } }); petGame.gui.player.pets.update = false; } else { petGame.player.pets.forEach(function (pet,index) { var petGUI = petGame.gui.player.pets["pet_"+index]; petGUI.name.innerText = pet.name; if (false == pet.dead) { petGUI.age.innerText = "Age: "+pet.age; petGUI.affection.innerText = "Love: "+(Math.sign(pet.affection)*Math.floor(Math.pow(Math.abs(pet.affection),1/7))); petGUI.health.innerText = "health: "+Math.ceil(pet.health)+"/"+pet.healthMax; petGUI.hydration.innerText = "Hydration: "+Math.ceil(pet.hydration)+"/"+pet.hydrationMax; petGUI.nurishment.innerText = "Nurishment: "+Math.ceil(pet.nurishment)+"/"+pet.nurishmentMax; petGUI.stomach.innerText = "Stomach: "+Math.ceil(pet.stomach)+"/"+pet.stomachMax; if ("string" == typeof pet.currentAction) { petGUI.action.innerText = humanTime(pet.busyUntil - performance.now()); petGUI.action.classList.add(pet.currentAction); } if (0 < pet.dirty) { petGUI.poop.innerText = "Poop: "+Math.ceil(pet.dirty); } } else { petGUI.name.innerHTML += '

RIP

'; petGUI.classList.add("dead"); } }); } if (true == petGame.player.actions.update) { petGame.gui.player.actions.innerHTML = null; petGame.player.actions.available.forEach(function (action) { var enabled = action.petPointer.currentAction ? "disabled" : "enabled"; var thisAction = elementPlace("#playerActions",null,"actionButton "+enabled,"span"); thisAction.innerText = action.name; thisAction.onclick = action.action; }); petGame.player.actions.update = false; } if (true == petGame.log.update) { petGame.gui.info.log.innerHTML = null; petGame.log.queue.forEach(function (message) { petGame.gui.info.log.innerHTML += '

'+message.message+"

"; }); petGame.gui.info.log.scrollTop = petGame.gui.info.log.scrollHeight; petGame.log.update = false; } if(petGame.market.inventory.update) { petGame.gui.info.market.innerHTML = null; petGame.market.inventory.contents.forEach(function (item,itemIndex) { var itemGui = elementPlace("#infoMarket",null,"item item"+item.name,"li"); var cost = petGame.itemDB[item.id].cost; itemGui.innerHTML =''+ item.name+''+numberShorten(cost)+''+numberShorten(item.count)+''+item.desc+''; itemGui.onclick = function () { if (cost <= petGame.player.coins) { petGame.market.coins += cost; petGame.player.coins -= cost; petGame.player.giveItem(item.id); petGame.market.inventory.useItem(itemIndex,false); } else { petGame.log.messageAdd("You don't have enough coins for "+item.name,2,10000); } }; }); petGame.market.inventory.update = false; } } // Define random events function petGame.randomEvent = function () { var dice = Math.floor(Math.random()*100); var potentialEvents = petGame.eventDB.filter(anEvent => anEvent.chance > dice); if (potentialEvents.length > 0) { potentialEvents[Math.floor(Math.random()*potentialEvents.length)].action(); } } // Define Save function petGame.save = function () { var save = {}; save.sessionDate = performance.timeOrigin + performance.now(); save.sessionTime = performance.now(); save.current = petGame.current; save.eventCountdown = petGame.eventCountdown; save.market = {"exchangeRate":petGame.market.exchangeRate,"coins":petGame.market.coins,"inventory":petGame.market.inventory.getEssentials()}; save.player = {"water":petGame.player.water,"food":petGame.player.food,"coins":petGame.player.coins,"inventory":petGame.player.inventory.getEssentials(),"pets":[]}; petGame.player.pets.forEach(function (pet,index) { save.player.pets[index] = { "affection":pet.affection, "age":pet.age, "ageStart":pet.ageStart, "birth":pet.birth, "busyUntil":pet.busyUntil, "currentAction":pet.currentAction, "dead":pet.dead, "dirty":pet.dirty, "dna":pet.dna, "activeRna":pet.activeRna, "gender":pet.gender, "health":pet.health, "healthMax":pet.healthMax, "hungerRate":pet.hungerRate, "hydration":pet.hydration, "hydrationMax":pet.hydrationMax, "lastPoop":pet.lastPoop, "mood":pet.mood, "name":pet.name, "nurishment":pet.nurishment, "nurishmentMax":pet.nurishmentMax, "stomach":pet.stomach, "stomachMax":pet.stomachMax, "thirstRate":pet.thirstRate, }; }); localStorage.setItem("petGameSave",JSON.stringify(save)); } // Define Load function petGame.load = function () { var load = JSON.parse(localStorage.getItem("petGameSave")); var sessionStartDif = (load.sessionDate - load.sessionTime) - performance.timeOrigin; var offlineDeltaT = performance.timeOrigin - load.sessionDate; console.log("deltaT = "+offlineDeltaT); console.log("time between last start and this start: "+sessionStartDif); petGame.current = load.current + sessionStartDif + offlineDeltaT; petGame.eventCountdown = load.eventCountdown + offlineDeltaT + sessionStartDif; petGame.market.exchangeRate = load.market.exchangeRate; petGame.market.coins = load.market.coins; petGame.market.inventory.contents = []; load.market.inventory.forEach(function (item) {petGame.market.addItem(item.id,item.count);}); petGame.player.water = load.player.water; petGame.player.food = load.player.food; petGame.player.coins = load.player.coins; petGame.player.inventory.contents = []; load.player.inventory.forEach(function (item) {petGame.player.giveItem(item.id,item.count);}); load.player.pets.forEach(function (oldPet) { var index = (petGame.player.pets.push(new pet()) - 1); petGame.player.pets[index].affection = oldPet.affection; petGame.player.pets[index].age = oldPet.age, petGame.player.pets[index].ageStart = oldPet.ageStart + sessionStartDif + offlineDeltaT, petGame.player.pets[index].birth = oldPet.birth + sessionStartDif + offlineDeltaT, petGame.player.pets[index].busyUntil = oldPet.busyUntil + sessionStartDif + offlineDeltaT, petGame.player.pets[index].currentAction = oldPet.currentAction, petGame.player.pets[index].dead = oldPet.dead, petGame.player.pets[index].dirty = oldPet.dirty, petGame.player.pets[index].dna = oldPet.dna, petGame.player.pets[index].activeRna = oldPet.activeRna, petGame.player.pets[index].gender = oldPet.gender, petGame.player.pets[index].health = oldPet.health, petGame.player.pets[index].healthMax = oldPet.healthMax, petGame.player.pets[index].hungerRate = oldPet.hungerRate, petGame.player.pets[index].hydration = oldPet.hydration, petGame.player.pets[index].hydrationMax = oldPet.hydrationMax, petGame.player.pets[index].lastPoop = oldPet.lastPoop + offlineDeltaT + sessionStartDif, petGame.player.pets[index].mood = oldPet.mood, petGame.player.pets[index].name = oldPet.name, petGame.player.pets[index].nurishment = oldPet.nurishment, petGame.player.pets[index].nurishmentMax = oldPet.nurishmentMax, petGame.player.pets[index].stomach = oldPet.stomach, petGame.player.pets[index].stomachMax = oldPet.stomachMax, petGame.player.pets[index].thirstRate = oldPet.thirstRate }); } // Define games ticker function petGame.tickerFunction = function () { var deltaT = performance.now() - petGame.current; petGame.current += deltaT; petGame.eventCountdown -= deltaT; petGame.player.pets.forEach( function (pet) { pet.tick(deltaT); }); if (petGame.eventCountdown <= 0) { petGame.eventCountdown += Math.floor(Math.random()*1800000); petGame.randomEvent(); } // non time sensitive ticking functions petGame.save(); petGame.log.clean(); petGame.gui.update(); } // Define petGame init function petGame.init = function () { petGame.gui.init(); petGame.gui.update(); petGame.ticker = setInterval(petGame.tickerFunction, 250); if (localStorage.getItem("petGameSave")) { petGame.load(); } else { petGame.player.give("coins",500); petGame.market.addItem(0); petGame.market.addItem(1,10); petGame.market.addItem(2,10); } }