pets/libs/pet.js

721 lines
30 KiB
JavaScript
Raw Normal View History

2019-04-21 10:40:02 -06:00
// 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 += '<option value="'+index+'">'+pet.name+'</option>';});
var mother = elementPlace("#"+container.id,null, "nexus_mother", "select");
args.femalesOfAge.forEach(function (pet,index) {mother.innerHTML += '<option value="'+index+'">'+pet.name+'</option>';});
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 ='<span class="itemName">'+ item.name+'</span><span class="itemCount">'+numberShorten(item.count)+'</span><span class="itemDesc">'+item.desc+'</span>';
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 += '<p class="dead">RIP</p>';
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 += '<p class="dead">RIP</p>';
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 += '<p class="'+message.priority+'">'+message.message+"</p>";
});
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 ='<span class="itemName">'+ item.name+'</span><span class="itemCost">'+numberShorten(cost)+'</span><span class="itemCount">'+numberShorten(item.count)+'</span><span class="itemDesc">'+item.desc+'</span>';
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);
}
}