<commit_before>function Player(session,class_name, aspect, object_to_prototype, moon, godDestiny,id){
	this.baby = null;
	this.renderingType = 0; //0 means default for this sim.
	this.associatedStats = [];  //most players will have a 2x, a 1x and a -1x stat.
	this.sanity = 0; //eventually replace triggerLevel with this (it's polarity is opposite triggerLevel)
	this.alchemy = 0; //mostly unused until we get to the Alchemy update.
	this.interest1Category = null; //used by Replay page for custom interests.
	this.interest2Category = null; //both should be null once they have been used to add the custom interest to the right place
	this.spriteCanvasID = null;  //part of new rendering engine.
	this.session = session;
	this.currentHP = 0;
	this.denizen = null;
	this.denizenMinion = null;
	this.maxHornNumber = 73; //don't fuck with this
	this.maxHairNumber = 68; //same
	this.sprite = null; //gets set to a blank sprite when character is created.
	this.grist = 0; //total party grist needs to be at a certain level for the ultimate alchemy. luck events can raise it, boss fights, etc.
	this.hp = 0; //mostly used for boss battles;
	this.graphs = [];
	this.deriveChatHandle = true;
	this.id = id;
	this.flipOutReason = null; //if it's null, i'm not flipping my shit.
	this.flippingOutOverDeadPlayer = null; //don't let this go into url. but, don't flip out if the friend is currently alive, you goof.
	this.denizen_index = 0; //denizen quests are in order.
	this.causeOfDrain = ""; //just ghost things
	this.ghostWisdom = []; //keeps you from spamming the same ghost over and over for wisdom.
	this.ghostPacts = []; //some classes can form pacts with ghosts for use in boss battles (attack or revive) (ghosts don't leave bubbles, just lend power). or help others do so.  if i actually use a ghost i have a pact with, it's drained. (so anybody else with a pact with it can't use it.)
	this.land1 = null; //words my land is made of.
	this.land2 = null;
	this.minLuck = 0;
	this.maxLuck = 0;
	this.freeWill = 0;
	this.mobility = 0;
	this.crowned = null; //players can't be crowned.
	this.trickster = false;
	this.sbahj = false;
	this.sickRhymes = []; //oh hell yes. Hell. FUCKING. Yes!
	this.robot = false;
	this.ectoBiologicalSource = null; //might not be created in their own session now.
	this.class_name = class_name;
	this.guardian = null; //no longer the sessions job to keep track.
	this.number_confessions = 0;
	this.number_times_confessed_to = 0;
	this.baby_stuck = false;
	this.influenceSymbol = null; //multiple aspects can influence/mind control.
	this.influencePlayer = null; //who is controlling me? (so i can break free if i have more free will or they die)
	this.stateBackup = null; //if you get influenced by something, here's where your true self is stored until you break free.
	this.aspect = aspect;
	this.land = null;
	this.interest1 =null;
	this.interest2 = null;
	this.chatHandle = null;
	this.object_to_prototype = object_to_prototype;
	this.relationships = [];
	this.moon = moon;
	this.power = 1;   //power is generic. generally scales with any aplicable stats. lets me compare two different aspect players.
	this.leveledTheHellUp = false; //triggers level up scene.
	this.mylevels = null
	this.level_index = -1; //will be ++ before i query
	this.godTier = false;
	this.victimBlood = null; //used for murdermode players.
	this.hair = null
	//this.hair = 16;
	this.hairColor = null
	this.dreamSelf = true;
	this.isTroll = false; //later
	this.bloodColor = "#ff0000" //human red.
	this.leftHorn = null;
	this.rightHorn = null;
	this.lusus = "Adult Human"
	this.quirk = null;
	this.dead = false;
	this.godDestiny = godDestiny;
	//should only be false if killed permananetly as god tier
	this.canGodTierRevive = true;  //even if a god tier perma dies, a life or time player or whatever can brings them back.
	this.isDreamSelf = false;
	//players can be triggered for various things. higher their triggerLevle, greater chance of going murdermode or GrimDark.
	this.sanity = 2; //make up for moon bonus
	this.murderMode = false;  //kill all players you don't like. odds of a just death skyrockets.
	this.leftMurderMode = false; //have scars, unless left via death.
	this.corruptionLevelOther = 0; //every 100 points, sends you to next grimDarkLevel.
	this.grimDark = 0;  //  0 = none, 1 = some, 2 = some more 3 = full grim dark with aura and font and everything.
	this.leader = false;
	this.landLevel = 0; //at 10, you can challenge denizen.  only space player can go over 100 (breed better universe.)
	this.denizenFaced = false;
	this.denizenDefeated = false;
	this.denizenMinionDefeated = false;
	this.causeOfDeath = ""; //fill in every time you die. only matters if you're dead at end
	this.doomedTimeClones =  []; //help fight the final boss(es).
	this.doomed = false; //stat that doomed time clones have.


	this.fromThisSession = function(session){
		return (this.ectoBiologicalSource == null || this.ectoBiologicalSource == session.session_id)
	}

	this.isQuadranted = function(){
		if(this.getHearts().length > 0) return true;
		if(this.getClubs().length > 0) return true;
		if(this.getDiamonds().length > 0) return true;
		if(this.getSpades().length > 0) return true;

	}

	this.getClubs = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.clubs){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getHearts = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.heart){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getDenzenNameArray = function(){

	}

	//returns a number based on the absolute value of everything except relationships (can't help you with a denizen fight and that's what this is for)
	this.getOverallStrength  = function(){
		var ret = 0;
		ret += this.power;
		ret += Math.abs(this.freeWill)
		ret += Math.abs(this.mobility)
		ret += Math.abs(this.hp)
		ret += Math.abs(this.maxLuck - this.minLuck)
		ret += Math.abs(this.sanity)
		return ret;
	}

	this.generateDenizen = function(){
		var possibilities = this.getDenizenNameArray();
		var strength = this.getOverallStrength();
		var expectedMaxStrength = 1200; //from sim values of 50+ sessions. then balancing exercises with AB
		var strengthPerTier = (expectedMaxStrength)/possibilities.length;
		//console.log("Strength at start is, " + strength);//but what if you don't want STRANGTH!???
		var denizenIndex = Math.round(strength/strengthPerTier)-1;  //want lowest value to be off the denizen array.

		var denizenName = "";
		var denizenStrength = (denizenIndex/(possibilities.length/2))+1
		if(denizenIndex == 0){
			denizenName = this.weakDenizenNames();
			denizenStrength = 0.1;//fraymotifs about standing and looking at your pittifully
			console.log("strength demands a weak denizen " + this.session.session_id)
		}else if(denizenIndex >= possibilities.length){
			denizenName = this.strongDenizenNames(); //<-- doesn't have to be literally him. points for various mispellings of his name.
			denizenStrength = 5;
			console.log("Strength demands strong denizen. " + this.session.session_id)
		}else{
			denizenName = possibilities[denizenIndex];

		}

		this.makeDenizenWithStrength(denizenName, denizenStrength); //if you pick the middle enizen it will be at strength of "1", if you pick last denizen, it will be at 2 or more.

	}

	//generate denizen gets me name and strength, this just takes care of making it.
	this.makeDenizenWithStrength = function(name, strength){
		//based off existing denizen code.  care about which aspect i am.
		//also make minion here.
		var denizen =  new GameEntity(this.session, "Denizen " +name, null);
		var denizenMinion = new GameEntity(this.session,name + " Minion", null);
		var ml = 30;
		var xl = 50;
		var hp = 20 * strength;
		var mob = 20;
		var tl = 0;
		var fw = 0;
		var power = 10 * strength; //first minion.
		if(this.aspect == "Hope") power = power *4;
		if(this.aspect == "Life") hp = hp *4;
		if(this.aspect == "Doom"){
			 hp = hp/2;
			 ml = ml/2;
		}
		if(this.aspect == "Blood"){
			hp = hp * 2;
			tl = tl/2;
		}
		if(this.aspect == "Mind"){
			fw = fw *2;
			hp = hp * 2;
		}
		if(this.aspect == "Rage"){
			tl = tl *2;
			power = power*2;
		}
		if(this.aspect == "Void") power = power *4;
		if(this.aspect == "Time") fw = fw /4;
		if(this.aspect == "Heart"){
			power = power *2;
			ml = ml & 2;
		}
		if(this.aspect == "Breath") mob = mob *4;
		if(this.aspect == "Light") xl = xl *4;
		if(this.aspect == "Space") mob = mob /4;

		denizenMinion.setStats(ml,xl,hp,mob,tl,fw,power,true, false, [],1000000);
		power = 50*strength;
		if(this.aspect == "Hope") power = power *4; //only power and hp need recalced, will be same for all others.
		hp = 100* strength;
		if(this.aspect == "Life") hp = hp *4;
		if(this.aspect == "Doom"){
			 hp = hp/2;
			 ml = ml/2;
		}
		denizen.setStats(ml,xl,hp,mob,tl,fw,power,true, false, [],1000000);
		this.denizen = denizen;
		this.denizenMinion = denizenMinion;
	}

	this.getDenizenNameArray = function(){
		if(this.aspect == "Blood") return this.bloodDenizenNames();
		if(this.aspect == "Mind") return this.mindDenizenNames();
		if(this.aspect == "Rage") return this.rageDenizenNames();
		if(this.aspect == "Void") return this.voidDenizenNames();
		if(this.aspect == "Time") return this.timeDenizenNames();
		if(this.aspect == "Heart") return this.heartDenizenNames();
		if(this.aspect == "Breath") return this.breathDenizenNames();
		if(this.aspect == "Light") return this.lightDenizenNames();
		if(this.aspect == "Space") return this.spaceDenizenNames();
		if(this.aspect == "Hope") return this.hopeDenizenNames();
		if(this.aspect == "Life") return this.lifeDenizenNames();
		if(this.aspect == "Doom") return this.doomDenizenNames();
		return ["ERROR 404: DENIZEN NOT FOUND"]
	}
	//discord generated most of these names.
	this.bloodDenizenNames = function(){
		return ['Blood','Hera','Hestia','Bastet','Bes','Vesta','Eleos','Sanguine','Medusa','Frigg','Debella','Juno','Moloch','Baal','Eusebeia','Horkos','Homonia','Harmonia','Philotes'];
	}

	this.mindDenizenNames = function(){
		return ['Mind','Athena','Forseti','Janus','Anubis','Maat','Seshat','Thoth','Jyglag','Peryite','Nomos','Lugus','Sithus','Dike','Epimetheus','Metis','Morpheus','Omoikane','Argus','Hermha','Morha','Sespille','Selcric','Tzeench']
	}

	this.rageDenizenNames = function(){
		return ['Rage','Ares','Dyonisus','Bacchus','Abbadon','Mammon','Mania','Asmodeus','Belphegor','Set','Apophis','Nemesis','Menoetius','Shogorath','Loki','Alastor','Mol Bal','Deimos','Achos','Pallas','Deimos','Ania','Lupe','Lyssa','Ytilibatsni','Discord'];
	}

	this.voidDenizenNames = function(){
		return ['Void','Selene','Erebus','Nix','Artemis','Kuk','Kaos','Hypnos','Tartarus','Hœnir','Skoll',"Czernobog",'Vermina','Vidar','Asteria','Nocturne','Tsukuyomi','Leviathan','Hecate','Harpocrates','Diova'];
	}

	this.timeDenizenNames = function(){
		return ['Time','Ignis','Saturn','Cronos','Aion','Hephaestus','Vulcan','Perses','Prometheus','Geras','Acetosh','Styx','Kairos','Veter','Gegute','Etu','Postverta and Antevorta','Emitus','Moirai'];
	}

	this.heartDenizenNames = function(){
		return ['Heart','Aphrodite','Baldur','Eros','Hathor','Philotes','Anubis','Psyche','Mora','Isis','Jupiter', 'Narcissus','Hecate','Izanagi','Izanami','Ishtar','Anteros','Agape','Peitho','Mahara','Naidraug','Snoitome','Walthidian','Slanesh','Benu'];
	}

	this.breathDenizenNames = function(){
		return ['Breath','Ninlil','Ouranos','Typheus','Aether','Amun','Hermes','Shu','Sobek','Aura','Theia','Lelantos','Keenarth','Aeolus','Aurai','Zephyrus','Ventus','Sora','Htaerb','Worlourier','Quetzalcoatl'];
	}

	this.lightDenizenNames = function(){
		return ['Light','Helios','Ra','Cetus','Iris','Heimdall','Apollo','Coeus','Hyperion', "Belobog",'Phoebe','Metis','Eos','Dagr','Asura','Amaterasu','Sol','Tyche','Odin ','Erutuf'];
	}

	this.spaceDenizenNames = function(){
		return ['Space','Gaea','Nut','Echidna','Wadjet','Qetesh','Ptah','Geb','Fryja','Atlas','Hebe','Lork','Eve','Genesis','Morpheus','Veles ','Arche','Rekinom','Iago','Pilera','Tiamat','Gilgamesh','Implexel'];
	}


	this.hopeDenizenNames = function(){
		return ['Hope','Isis','Marduk','Fenrir','Apollo','Sekhmet','Votan','Wadjet','Baldur','Zanthar','Raphael','Metatron','Jerahmeel','Gabriel','Michael','Cassiel','Gavreel','Aariel','Uriel','Barachiel ','Jegudiel','Samael','Taylus','Tzeench'];
	}

	this.lifeDenizenNames = function(){
		return ['Life','Demeter','Pan','Nephthys','Ceres','Isis','Hemera','Andhrímnir','Agathodaemon','Eir','Baldur','Prometheus','Adonis','Geb','Panacea','Aborof','Nurgel','Adam'];
	}

	this.doomDenizenNames = function(){
		return ['Doom','Hades','Achlys','Cassandra','Osiris','Ananke','Thanatos','Moros','Iapetus','Themis','Aisa','Oizys','Styx','Keres','Maat','Castor and Pollux','Anubis','Azrael','Ankou','Kapre','Moros','Atropos','Oizys','Korne','Odin'];
	}

	this.strongDenizenNames = function(){
		var ret = ['Yaldabaoth', 'Jörmungandr','Apollyon','Siseneg','Borunam','Jadeacher','Karmiution','Authorot','Aspiratcher','Recurscker','Insurorracle','Maniomnia','Kazerad','Shiva','Goliath'];
		return getRandomElementFromArray(ret);
	}

	this.weakDenizenNames = function(){
		var ret = ['Eriotur','Abraxas','Succra','Watojo','Bluhubit','Swefrat','Helaja','Fischapris'];
		return getRandomElementFromArray(ret);
	}



	//flipping out over the dead won't call this but everything else will.
	this.flipOut = function(reason){
		//console.log("flip out method called for: " + reason)
		this.flippingOutOverDeadPlayer = null;
		this.flipOutReason = reason;
	}

	this.interestedIn = function(interestWord,interestNum){
		if(!interestNum){
			if(interestWord == "Comedy") return playerLikesComedy(this)
			if(interestWord == "Music") return playerLikesMusic(this)
			if(interestWord == "Culture") return playerLikesCulture(this)
			if(interestWord == "Writing") return playerLikesWriting(this)
			if(interestWord == "Athletic") return playerLikesAthletic(this)
			if(interestWord == "Terrible") return playerLikesTerrible(this)
			if(interestWord == "Justice") return playerLikesJustice(this)
			if(interestWord == "Fantasy") return playerLikesFantasy(this)
			if(interestWord == "Domestic") return playerLikesDomestic(this)
			if(interestWord == "PopCulture") return playerLikesPopculture(this)
			if(interestWord == "Technology") return playerLikesTechnology(this)
			if(interestWord == "Social") return playerLikesSocial(this)
			if(interestWord == "Romance") return playerLikesRomantic(this)
			if(interestWord == "Academic") return playerLikesAcademic(this)
			return false;
		}else if(interestNum == 1){
			if(interestWord == "Comedy") return comedy_interests.indexOf(this.interest1) != -1
			if(interestWord == "Music") return music_interests.indexOf(this.interest1) != -1
			if(interestWord == "Culture") return culture_interests.indexOf(this.interest1) != -1
			if(interestWord == "Writing") return writing_interests.indexOf(this.interest1) != -1
			if(interestWord == "Athletic") return athletic_interests.indexOf(this.interest1) != -1
			if(interestWord == "Terrible") return terrible_interests.indexOf(this.interest1) != -1
			if(interestWord == "Justice") return justice_interests.indexOf(this.interest1) != -1
			if(interestWord == "Fantasy") return fantasy_interests.indexOf(this.interest1) != -1
			if(interestWord == "Domestic") return domestic_interests.indexOf(this.interest1) != -1
			if(interestWord == "PopCulture") return pop_culture_interests.indexOf(this.interest1) != -1
			if(interestWord == "Technology") return technology_interests.indexOf(this.interest1) != -1
			if(interestWord == "Social") return social_interests.indexOf(this.interest1) != -1
			if(interestWord == "Romance") return romantic_interests.indexOf(this.interest1) != -1
			if(interestWord == "Academic") return academic_interests.indexOf(this.interest1) != -1
		}else if(interestNum == 2){
			if(interestWord == "Comedy") return comedy_interests.indexOf(this.interest2) != -1
			if(interestWord == "Music") return music_interests.indexOf(this.interest2) != -1
			if(interestWord == "Culture") return culture_interests.indexOf(this.interest2) != -1
			if(interestWord == "Writing") return writing_interests.indexOf(this.interest2) != -1
			if(interestWord == "Athletic") return athletic_interests.indexOf(this.interest2) != -1
			if(interestWord == "Terrible") return terrible_interests.indexOf(this.interest2) != -1
			if(interestWord == "Justice") return justice_interests.indexOf(this.interest2) != -1
			if(interestWord == "Fantasy") return fantasy_interests.indexOf(this.interest2) != -1
			if(interestWord == "Domestic") return domestic_interests.indexOf(this.interest2) != -1
			if(interestWord == "PopCulture") return pop_culture_interests.indexOf(this.interest2) != -1
			if(interestWord == "Technology") return technology_interests.indexOf(this.interest2) != -1
			if(interestWord == "Social") return social_interests.indexOf(this.interest2) != -1
			if(interestWord == "Romance") return romantic_interests.indexOf(this.interest2) != -1
			if(interestWord == "Academic") return academic_interests.indexOf(this.interest2) != -1
		}
	}

	//if change would push me over 3, render 'cause i'm newly grimdark
	//if it would pull be from over 3, render 'cause i have somewhat recovered.
	this.changeGrimDark = function(val){
		//this.grimDark += val;
		var tmp = this.grimDark + val;
		var render = false;

		if(this.grimDark <= 3 && tmp > 3){ //newly GrimDark
			console.log("grim dark 3 or more in session: " + this.session.session_id)
			render = true;
		}else if(this.grimDark >3 && tmp <=3){ //newly recovered.
			render = true;
		}
		this.grimDark += val;
		if(render){
			this.renderSelf();
		}

	}

	this.makeMurderMode = function(){
		this.murderMode = true;
		this.increasePower();
		this.renderSelf(); //new scars. //can't do scars just on top of sprite 'cause hair might cover.'
	}

	this.unmakeMurderMode = function(){
		this.murderMode = false;
		this.leftMurderMode = true;
		this.renderSelf();
	}

	this.makeDead = function(causeOfDeath){
		this.dead = true;
		this.causeOfDeath = causeOfDeath;
		//was in make alive, but realized that this makes doom ghosts way stronger if it's here. powered by DEATH, but being revived.
		if(this.aspect == "Doom"){ //powered by their own doom.
			//console.log("doom is powered by their own death: " + this.session.session_id) //omg, they are sayians.
			this.power += 50;
			this.hp = 100; //prophecy fulfilled. but hp and luck will probably drain again.
			this.minLuck = 100; //prophecy fulfilled. you are no longer doomed.
		}
		if(!this.godTier){ //god tiers only make ghosts in GodTierRevivial
			this.session.afterLife.addGhost(makeRenderingSnapshot(this));
		}

		this.renderSelf();
		this.triggerOtherPlayersWithMyDeath();
	}

	//this used to happen in beTriggered. fuck that noise, it was shit.
	this.triggerOtherPlayersWithMyDeath = function(){
		//go through my relationships. if i am the only dead person, trigger everybody (death still has impact)
		//trigger (possibly ontop of base trigger) friends, and quadrant mates. really fuck up my moirel(s) if i have any
		//if triggered, also give a flip out reason.
		var dead = findDeadPlayers(this.session.players);
		for(var i = 0; i <this.relationships.length; i++){
			var r = this.relationships[i];

			if(r.saved_type == r.goodBig){
				r.target.sanity += -1;
				if(r.target.flipOutReason == null){
					r.target.flipOutReason = " their dead crush, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead crush.
					r.target.flippingOutOverDeadPlayer = this;
				}
			}else if(r.value > 0){
				r.target.sanity += -1;
				if(r.target.flipOutReason == null){
					 r.target.flippingOutOverDeadPlayer = this;
					 r.target.flipOutReason = " their dead friend, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead friend.
				}
			}else if(r.saved_type == r.spades){
				r.target.sanity += -10;
				r.target.flipOutReason = " their dead Kismesis, the " + this.htmlTitleBasic();
				r.target.flippingOutOverDeadPlayer = this;
			}else if(r.saved_type == r.heart){
				r.target.sanity += -10
				r.target.flipOutReason = " their dead Matesprit, the " + this.htmlTitleBasic();
				r.target.flippingOutOverDeadPlayer = this;
			}
			else if(r.saved_type == r.diamond){
				r.target.sanity += -100
				r.target.damageAllRelationships();
				r.target.damageAllRelationships();
				r.target.damageAllRelationships();
				r.target.flipOutReason = " their dead Moirail, the " + this.htmlTitleBasic() + ", fuck, that can't be good...";
				r.target.flippingOutOverDeadPlayer = this;
			}
			//console.log(r.target.title() + " has flipOutReason of: " + r.target.flipOutReason + " and knows about dead player: " + r.target.flippingOutOverDeadPlayer);
		}

		//whether or not i care about them, there's also the novelty factor.
		if(dead.length == 1){  //if only I am dead, death still has it's impact and even my enemies care.
			r.target.sanity += -1;
			if(r.target.flipOutReason == null){
				r.target.flipOutReason = " the dead player, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead player.
			 r.target.flippingOutOverDeadPlayer = this;
			}
		}
	}

	//needed'cause ghost pacts are a an array of pairs now so i know how i'm reviving.
	this.getPactWithGhost = function(ghost){
		for(var i = 0; i<this.ghostPacts.length; i++){
			var g = this.ghostPacts[i][0]
			if(g == ghost) return g
		}
		return null;
	}

	this.getSpades = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.spades){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getCrushes = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.goodBig){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getBlackCrushes = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.badBig){
				ret.push(r);
			}
		}
		return ret;
	}


	this.getDiamonds = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.diamond){
				ret.push(r);
			}
		}
		return ret;
	}


	this.chatHandleShort = function(){
		return this.chatHandle.match(/\b(\w)|[A-Z]/g).join('').toUpperCase();
	}

	this.chatHandleShortCheckDup = function(otherHandle){
		var tmp= this.chatHandle.match(/\b(\w)|[A-Z]/g).join('').toUpperCase();
		if(tmp == otherHandle){
			tmp = tmp + "2";
		}
		return tmp;
	}

	//what happened when you reached god tier was too inconsistent, and also
	//this lets sprite be updated.
	this.makeGodTier = function(){
		this.hp += 500; //they are GODS.
		this.power += 500;
		this.increasePower();
		this.godTier = true;
		this.session.godTier = true;
		this.dreamSelf = false;
		this.canGodTierRevive = true;
		this.leftMurderMode = false; //no scars, unlike other revival methods
		this.isDreamSelf = false;
		this.makeAlive();
	}



	this.makeAlive = function(){
			if(this.stateBackup) this.stateBackup.restoreState(this);
			this.influencePlayer = null;
			this.influenceSymbol = null;
			this.dead = false;
			this.murderMode = false;
			this.currentHP = Math.max(this.hp,1); //if for some reason your hp is negative, don't do that.
			this.grimDark = 0;
			this.sanity += -11;  //dying is pretty triggering.
			this.flipOutReason = "they just freaking died"
			//this.leftMurderMode = false; //no scars
			this.victimBlood = null; //clean face
			this.renderSelf();
		}




	this.title = function(){
		var ret = "";

		if(this.doomed){
			ret += "Doomed "
		}



		if(this.trickster){
			ret += "Trickster "
		}

		if(this.murderMode){
			ret += "Murder Mode ";
		}

		if(this.grimDark>3){
			ret += "Severely Grim Dark ";
		}else if(this.grimDark > 1){
			ret += "Mildly Grim Dark ";
		}else if(this.grimDark >2){
			ret += "Grim Dark ";
		}

		if(this.godTier){
			ret+= "God Tier "
		}else if(this.isDreamSelf){
			ret+= "Dream ";
		}
		if(this.robot){
			ret += "Robo"
		}
		ret+= this.class_name + " of " + this.aspect;
		if(this.dead){
			ret += "'s Corpse"
		}else if(this.ghost){
			ret += "'s Ghost"
		}
		ret += " (" + this.chatHandle + ")"
		return ret;
	}

	this.htmlTitleBasic = function(){
			return getFontColorFromAspect(this.aspect) + this.titleBasic() + "</font>"
	}

	this.titleBasic = function(){
		var ret = "";

		ret+= this.class_name + " of " + this.aspect;
		return ret;
	}

	//old method from 1.0
	this.getRandomLevel = function(){
		if(Math.seededRandom() > .5){
			return getRandomLevelFromAspect(this.aspect);
		}else{
			return getRandomLevelFromClass(this.class_name);
		}
	}

//new method having to pick 16 levels before entering the medium
	this.getNextLevel = function(){
		this.level_index ++;
		var ret= this.mylevels[this.level_index];
		return ret;
	}

	this.getRandomQuest = function(){
		if(this.landLevel >= 9 && this.denizen_index < 3 && this.denizenDefeated == false){ //three quests before denizen
			//console.log("denizen quest")
			return getRandomDenizenQuestFromAspect(this); //denizen quests are aspect only, no class.
		}else if((this.landLevel < 9 || this.denizen_index >=3) && this.denizenDefeated == false){  //can do more land quests if denizen kicked your ass. need to grind.
			if(Math.seededRandom() > .5 || this.aspect == "Space"){ //back to having space players be locked to frogs.
				return getRandomQuestFromAspect(this.aspect);
			}else{
				return getRandomQuestFromClass(this.class_name);
			}
		}else if(this.denizenDefeated){
			//console.log("post denizen quests " +this.session.session_id);
			//return "restoring their land from the ravages of " + this.session.getDenizenForPlayer(this).name;
			if(Math.seededRandom() > .5 || this.aspect == "Space"){ //back to having space players be locked to frogs.
				return getRandomQuestFromAspect(this.aspect,true);
			}else{
				return getRandomQuestFromClass(this.class_name,true);
			}
		}

	}

	this.decideHemoCaste  =function (){
		if(this.aspect != "Blood"){  //sorry karkat
			this.bloodColor = getRandomElementFromArray(bloodColors);
		}
	}

	this.decideLusus = function(player){
		if(this.bloodColor == "#610061" || this.bloodColor == "#99004d" || this.bloodColor == "#631db4" ){
			this.lusus = getRandomElementFromArray(sea_lusus_objects);
		}else{
			this.lusus = getRandomElementFromArray(lusus_objects);
		}
	}

	this.isVoidAvailable = function(){
		var light = findAspectPlayer(findLivingPlayers(this.session.players), "Light");
		if(light && light.godTier) return false;
		return true;
	}

	//classes only, at least for now
	this.getPVPModifier = function(role){
		if(role == "Attacker") return this.getAttackerModifier();
		if(role == "Defender") return this.getDefenderModifier();
		if(role == "Murderer") return this.getMurderousModifier();

	}

	this.renderable = function(){
		return true;
	}

	//basically free will shit. choosing to kill a player despite not being crazy
	this.getAttackerModifier = function(){
		if(this.class_name == "Knight") return 1.0;
		if(this.class_name == "Seer") return 0.67;
		if(this.class_name == "Bard") return 2.0;
		if(this.class_name == "Maid") return 0.33;
		if(this.class_name == "Heir") return 0.5;
		if(this.class_name == "Rogue") return 1.25;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 1.5;
		if(this.class_name == "Sylph") return 2.5;
		if(this.class_name == "Prince") return 5.0;
		if(this.class_name == "Witch") return 2.0;
		if(this.class_name == "Mage") return 0.67;
		return 1.0;
	}



	//defending yourself from an attack
	this.getDefenderModifier = function(){
		if(this.class_name == "Knight") return 2.5;
		if(this.class_name == "Seer") return 0.67;
		if(this.class_name == "Bard") return 0.5;
		if(this.class_name == "Maid") return 3.0;
		if(this.class_name == "Heir") return 2.0;
		if(this.class_name == "Rogue") return 1.25;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 0.8;
		if(this.class_name == "Sylph") return 1.0;
		if(this.class_name == "Prince") return 0.33;
		if(this.class_name == "Witch") return 1.0;
		if(this.class_name == "Mage") return 0.67;
		return 1.0;
	}

	//being shit flippingly crazy AND initiating a fight
	this.getMurderousModifier = function(){
		if(this.class_name == "Knight") return 0.75;
		if(this.class_name == "Seer") return 1.0;
		if(this.class_name == "Bard") return 3.0;
		if(this.class_name == "Maid") return 1.5;
		if(this.class_name == "Heir") return 1.5;
		if(this.class_name == "Rogue") return 1.0;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 1.0;
		if(this.class_name == "Sylph") return 1.5;
		if(this.class_name == "Prince") return 1.5;
		if(this.class_name == "Witch") return 1.5;
		if(this.class_name == "Mage") return 1.5;
		return 1.0;
	}


	this.getDenizen = function(){
		return this.denizen.name; //<--convineint that it wasn't hard to upgrade.
	}

	this.didDenizenKillYou = function(){
		if(this.causeOfDeath.indexOf(this.denizen.name) != -1){
			return true; //also return true for minions. this is intentional.
		}
		return false;
	}

	//more likely if lots of people hate you
	this.justDeath = function(){
		var ret = false;

		//impossible to have a just death from a denizen or denizen minion. unless you are corrupt.
		if(this.didDenizenKillYou() && !this.grimDark <= 2){
			return false;
		}else if(this.grimDark > 2){
			console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!just death for a corrupt player from their denizen or denizen minion in session: " + this.session.session_id)
			return true; //always just if the denizen puts down a corrupt player.
		}


		//if much less friends than enemies.
		if(this.getFriends().length < this.getEnemies().length){
			if(Math.seededRandom() > .9){ //just deaths are rarer without things like triggers.
				ret = true;
			}
			//way more likely to be a just death if you're being an asshole.


			if((this.murderMode || this.grimDark > 2)){
				var rand = Math.seededRandom()
				//console.log("rand is: " + rand)
				if(rand > .2){
					//console.log(" just death for: " + this.title() + "rand is: " + rand)
					ret = true;
				}
			}
		}else{  //you are a good person. just corrupt.
			//way more likely to be a just death if you're being an asshole.
			if((this.murderMode || this.grimDark > 2) && Math.seededRandom()>.5){
				ret = true;
			}
		}
		//console.log(ret);
		//return true; //for testing
		return ret;
	}

	//more likely if lots of people like you
	this.heroicDeath = function(){
		var ret = false;

		//it's not heroic derping to death against a minion or whatever, or in a solo fight.
		if(this.didDenizenKillYou() || this.causeOfDeath == "from a Bad Break."){
			return false;
		}

		//if far more enemies than friends.
		if(this.getFriends().length > this.getEnemies().length ){
			if(Math.seededRandom() > .6){
				ret = true;
			}
			//extra likely if you just killed the king/queen, you hero you.
			if(curSessionGlobalVar.kingStrength <=0 && Math.seededRandom()>.2){
				ret = true;
			}
		}else{ //unlikely hero
			if(Math.seededRandom() > .8){
				ret = true;
			}
			//extra likely if you just killed the king/queen, you hero you.
			if(curSessionGlobalVar.kingStrength <=0 && Math.seededRandom()>.4){
				ret = true;
			}
		}

		if(ret){
			//console.log("heroic death");
		}
		return ret;
	}



	this.hasInteractionEffect = function(){
		return this.class_name == "Prince" || this.class_name == "Bard"|| this.class_name == "Witch"|| this.class_name == "Sylph"|| this.class_name == "Rogue"|| this.class_name == "Thief"
	}

	this.associatedStatsInteractionEffect = function(player){
		if(this.hasInteractionEffect()){ //don't even bother if you don't have an interaction effect.
			for(var i = 0; i<this.associatedStats.length; i++){
				this.processStatInteractionEffect(player, this.associatedStats[i]);
			}
		}
	}


	this.processStatInteractionEffect = function(player, stat){
		var powerBoost = this.power/20;
		if(this.class_name == "Witch"|| this.class_name == "Sylph"){
			powerBoost = powerBoost *  2 //sylph and witch get their primary boost here, so make it a good one.
		}
		var powerBoost = this.modPowerBoostByClass(powerBoost,stat);
		if(this.class_name == "Rogue"|| this.class_name == "Thief"){
			player.modifyAssociatedStat((-1 * powerBoost), stat);
			if(this.isActive()){ //modify me
				this.modifyAssociatedStat(powerBoost, stat);
			}else{  //modify others.
				for(var i = 0; i<this.session.players.length; i++){
					this.session.players[i].modifyAssociatedStat(powerBoost/this.session.players.length, stat);
				}
			}
		}else{
			if(this.isActive()){ //modify me
				this.modifyAssociatedStat(powerBoost, stat);
			}else{  //modify others.
				player.modifyAssociatedStat(powerBoost, stat);
			}
		}
	}

	this.interactionEffect = function(player){

		this.associatedStatsInteractionEffect(player);

		//no longer do this seperate. if close enough to modify with powers, close enough to be...closer.
		r1 = this.getRelationshipWith(player);
		if(r1){
			r1.moreOfSame();
		}

	}

	//SBURB is not a mystery to these classes/aspects.
	this.knowsAboutSburb = function(){
		//time might not innately get it, but they have future knowledge
		var rightClass = this.class_name == "Seer" || this.class_name == "Mage" || this.aspect == "Light" || this.aspect == "Mind" || this.aspect == "Doom" || this.aspect == "Time"
		return rightClass && this.power > 20; //need to be far enough in my claspect
	}

	this.performEctobiology = function(session){
		session.ectoBiologyStarted = true;
		playersMade = findPlayersWithoutEctobiologicalSource(session.players);
		setEctobiologicalSource(playersMade, session.session_id)
		return playersMade;
	}

	this.isActive = function(){
		return active_classes.indexOf(this.class_name) != -1;
	}



	//each player knows how to generate their own guardian.
	this.makeGuardian =function(){
		//console.log("guardian for " + player.titleBasic());
		var player = this;
		var possibilities = active_classes;
		if(this.isActive()) possibilities = passive_classes;
		var guardian = randomPlayerWithClaspect(this.session, getRandomElementFromArray(possibilities), this.aspect);

		guardian.isTroll = player.isTroll;
		guardian.quirk.favoriteNumber = player.quirk.favoriteNumber;
		if(guardian.isTroll){
			guardian.quirk = randomTrollSim(guardian) //not same quirk as guardian
		}else{
			guardian.quirk = randomHumanSim(guardian);
		}

		guardian.bloodColor = player.bloodColor;
		guardian.lusus = player.lusus;
		if(guardian.isTroll == true){ //trolls always use lusus.
			guardian.object_to_prototype = player.object_to_prototype;
		}
		guardian.hairColor = player.hairColor;

		//console.log("Guardian className: " + guardian.class_name + " Player was: " + this.class_name);
		guardian.leftHorn = player.leftHorn;
		guardian.rightHorn = player.rightHorn;
		guardian.level_index = 5; //scratched kids start more leveled up
		guardian.power = 50;
		guardian.leader = player.leader;
		if(Math.seededRandom() >0.5){ //have SOMETHING in common with your ectorelative.
			guardian.interest1 = player.interest1;
		}else{
			guardian.interest2 = player.interest2;
		}
		guardian.initializeDerivedStuff();//redo levels and land based on real aspect
		//this.guardians.push(guardian); //sessions don't keep track of this anymore
		player.guardian = guardian;
		guardian.guardian = this;//goes both ways.
	}



	this.associatedStatsIncreasePower = function(powerBoost){
		//modifyAssociatedStat
		for(var i = 0; i< this.associatedStats.length; i++){
			this.processStatPowerIncrease(powerBoost, this.associatedStats[i]);
		}
	}

	this.modPowerBoostByClass = function(powerBoost,stat){
		switch (this.class_name) {
			case "Knight":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 2;
				}else{
					powerBoost = powerBoost * 0.5
				}
				break;
			case  "Seer":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 1;
				}else{
					powerBoost = powerBoost * 0.25
				}
				break;
			case  "Bard":
				var lolrandoms = [-1, 1,2,-1,0.25,-0.25,0.5,-0.5]
				powerBoost = powerBoost * getRandomElementFromArray(lolrandoms);
				break;
			case  "Heir":
				powerBoost = powerBoost * 1.5;
				break;
			case  "Maid":
				powerBoost = powerBoost * 1.5;
				break;
			case  "Rogue":
				powerBoost = powerBoost * 0.5;
				break;
			case  "Page":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 2;
				}else{
					powerBoost = powerBoost * 0.5
				}
				break;
			case  "Thief":
				powerBoost = powerBoost * 0.5;
				break;
			case  "Sylph":
				powerBoost = powerBoost * 1;
				break;
			case  "Prince":
				var lolrandoms = [-1, 1,2,-1,0.25,-0.25,0.5,-0.5]
				powerBoost = powerBoost * getRandomElementFromArray(lolrandoms);
				break;
			case  "Witch":
				powerBoost = powerBoost * 1;
				break;
			case  "Mage":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 1;
				}else{
					powerBoost = powerBoost * 0.25
				}
				break;
			default:
				console.log('What the hell kind of class is ' + this.class_name + '???');
		}

		return powerBoost;
	}

	this.processStatPowerIncrease = function(powerBoost, stat){
		var powerBoost = this.modPowerBoostByClass(powerBoost,stat);
		if(this.isActive()){ //modify me
			this.modifyAssociatedStat(powerBoost, stat);
		}else{  //modify others.
			for(var i = 0; i<this.session.players.length; i++){
				this.session.players[i].modifyAssociatedStat(powerBoost, stat);
			}
		}
	}


	this.increasePower = function(){
		if(Math.seededRandom() >.9){
			this.leveledTheHellUp = true; //that multiple of ten thing is bullshit.
		}
		var powerBoost = 1;

		if(this.class_name == "Page"){  //they don't have many quests, but once they get going they are hard to stop.
			powerBoost = powerBoost * 5;
		}

		if(this.aspect == "Hope"){
			powerBoost = powerBoost * 2;
		}

		if(this.godTier){
			powerBoost = powerBoost * 20;  //god tiers are ridiculously strong.
		}

		if(this.denizenDefeated){
			powerBoost = powerBoost * 2; //permanent doubling of stats forever.
		}

		this.power += powerBoost;
		this.associatedStatsIncreasePower();
		//gain a bit of hp, otherwise denizen will never let players fight them if their hp isn't high enough.
		if(this.godTier || Math.seededRandom() >.25){
			this.hp += 10;
			this.currentHP += 10;
		}

	}

	this.shortLand = function(){
		return this.land.match(/\b(\w)/g).join('').toUpperCase();
	}
<commit_msg>nan fixed?<commit_after>function Player(session,class_name, aspect, object_to_prototype, moon, godDestiny,id){
	this.baby = null;
	this.renderingType = 0; //0 means default for this sim.
	this.associatedStats = [];  //most players will have a 2x, a 1x and a -1x stat.
	this.sanity = 0; //eventually replace triggerLevel with this (it's polarity is opposite triggerLevel)
	this.alchemy = 0; //mostly unused until we get to the Alchemy update.
	this.interest1Category = null; //used by Replay page for custom interests.
	this.interest2Category = null; //both should be null once they have been used to add the custom interest to the right place
	this.spriteCanvasID = null;  //part of new rendering engine.
	this.session = session;
	this.currentHP = 0;
	this.denizen = null;
	this.denizenMinion = null;
	this.maxHornNumber = 73; //don't fuck with this
	this.maxHairNumber = 68; //same
	this.sprite = null; //gets set to a blank sprite when character is created.
	this.grist = 0; //total party grist needs to be at a certain level for the ultimate alchemy. luck events can raise it, boss fights, etc.
	this.hp = 0; //mostly used for boss battles;
	this.graphs = [];
	this.deriveChatHandle = true;
	this.id = id;
	this.flipOutReason = null; //if it's null, i'm not flipping my shit.
	this.flippingOutOverDeadPlayer = null; //don't let this go into url. but, don't flip out if the friend is currently alive, you goof.
	this.denizen_index = 0; //denizen quests are in order.
	this.causeOfDrain = ""; //just ghost things
	this.ghostWisdom = []; //keeps you from spamming the same ghost over and over for wisdom.
	this.ghostPacts = []; //some classes can form pacts with ghosts for use in boss battles (attack or revive) (ghosts don't leave bubbles, just lend power). or help others do so.  if i actually use a ghost i have a pact with, it's drained. (so anybody else with a pact with it can't use it.)
	this.land1 = null; //words my land is made of.
	this.land2 = null;
	this.minLuck = 0;
	this.maxLuck = 0;
	this.freeWill = 0;
	this.mobility = 0;
	this.crowned = null; //players can't be crowned.
	this.trickster = false;
	this.sbahj = false;
	this.sickRhymes = []; //oh hell yes. Hell. FUCKING. Yes!
	this.robot = false;
	this.ectoBiologicalSource = null; //might not be created in their own session now.
	this.class_name = class_name;
	this.guardian = null; //no longer the sessions job to keep track.
	this.number_confessions = 0;
	this.number_times_confessed_to = 0;
	this.baby_stuck = false;
	this.influenceSymbol = null; //multiple aspects can influence/mind control.
	this.influencePlayer = null; //who is controlling me? (so i can break free if i have more free will or they die)
	this.stateBackup = null; //if you get influenced by something, here's where your true self is stored until you break free.
	this.aspect = aspect;
	this.land = null;
	this.interest1 =null;
	this.interest2 = null;
	this.chatHandle = null;
	this.object_to_prototype = object_to_prototype;
	this.relationships = [];
	this.moon = moon;
	this.power = 1;   //power is generic. generally scales with any aplicable stats. lets me compare two different aspect players.
	this.leveledTheHellUp = false; //triggers level up scene.
	this.mylevels = null
	this.level_index = -1; //will be ++ before i query
	this.godTier = false;
	this.victimBlood = null; //used for murdermode players.
	this.hair = null
	//this.hair = 16;
	this.hairColor = null
	this.dreamSelf = true;
	this.isTroll = false; //later
	this.bloodColor = "#ff0000" //human red.
	this.leftHorn = null;
	this.rightHorn = null;
	this.lusus = "Adult Human"
	this.quirk = null;
	this.dead = false;
	this.godDestiny = godDestiny;
	//should only be false if killed permananetly as god tier
	this.canGodTierRevive = true;  //even if a god tier perma dies, a life or time player or whatever can brings them back.
	this.isDreamSelf = false;
	//players can be triggered for various things. higher their triggerLevle, greater chance of going murdermode or GrimDark.
	this.sanity = 2; //make up for moon bonus
	this.murderMode = false;  //kill all players you don't like. odds of a just death skyrockets.
	this.leftMurderMode = false; //have scars, unless left via death.
	this.corruptionLevelOther = 0; //every 100 points, sends you to next grimDarkLevel.
	this.grimDark = 0;  //  0 = none, 1 = some, 2 = some more 3 = full grim dark with aura and font and everything.
	this.leader = false;
	this.landLevel = 0; //at 10, you can challenge denizen.  only space player can go over 100 (breed better universe.)
	this.denizenFaced = false;
	this.denizenDefeated = false;
	this.denizenMinionDefeated = false;
	this.causeOfDeath = ""; //fill in every time you die. only matters if you're dead at end
	this.doomedTimeClones =  []; //help fight the final boss(es).
	this.doomed = false; //stat that doomed time clones have.


	this.fromThisSession = function(session){
		return (this.ectoBiologicalSource == null || this.ectoBiologicalSource == session.session_id)
	}

	this.isQuadranted = function(){
		if(this.getHearts().length > 0) return true;
		if(this.getClubs().length > 0) return true;
		if(this.getDiamonds().length > 0) return true;
		if(this.getSpades().length > 0) return true;

	}

	this.getClubs = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.clubs){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getHearts = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.heart){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getDenzenNameArray = function(){

	}

	//returns a number based on the absolute value of everything except relationships (can't help you with a denizen fight and that's what this is for)
	this.getOverallStrength  = function(){
		var ret = 0;
		ret += this.power;
		ret += Math.abs(this.freeWill)
		ret += Math.abs(this.mobility)
		ret += Math.abs(this.hp)
		ret += Math.abs(this.maxLuck - this.minLuck)
		ret += Math.abs(this.sanity)
		return ret;
	}

	this.generateDenizen = function(){
		var possibilities = this.getDenizenNameArray();
		var strength = this.getOverallStrength();
		var expectedMaxStrength = 1200; //from sim values of 50+ sessions. then balancing exercises with AB
		var strengthPerTier = (expectedMaxStrength)/possibilities.length;
		//console.log("Strength at start is, " + strength);//but what if you don't want STRANGTH!???
		var denizenIndex = Math.round(strength/strengthPerTier)-1;  //want lowest value to be off the denizen array.

		var denizenName = "";
		var denizenStrength = (denizenIndex/(possibilities.length/2))+1
		if(denizenIndex == 0){
			denizenName = this.weakDenizenNames();
			denizenStrength = 0.1;//fraymotifs about standing and looking at your pittifully
			console.log("strength demands a weak denizen " + this.session.session_id)
		}else if(denizenIndex >= possibilities.length){
			denizenName = this.strongDenizenNames(); //<-- doesn't have to be literally him. points for various mispellings of his name.
			denizenStrength = 5;
			console.log("Strength demands strong denizen. " + this.session.session_id)
		}else{
			denizenName = possibilities[denizenIndex];

		}

		this.makeDenizenWithStrength(denizenName, denizenStrength); //if you pick the middle enizen it will be at strength of "1", if you pick last denizen, it will be at 2 or more.

	}

	//generate denizen gets me name and strength, this just takes care of making it.
	this.makeDenizenWithStrength = function(name, strength){
		//based off existing denizen code.  care about which aspect i am.
		//also make minion here.
		var denizen =  new GameEntity(this.session, "Denizen " +name, null);
		var denizenMinion = new GameEntity(this.session,name + " Minion", null);
		var ml = 30;
		var xl = 50;
		var hp = 20 * strength;
		var mob = 20;
		var tl = 0;
		var fw = 0;
		var power = 10 * strength; //first minion.
		if(this.aspect == "Hope") power = power *4;
		if(this.aspect == "Life") hp = hp *4;
		if(this.aspect == "Doom"){
			 hp = hp/2;
			 ml = ml/2;
		}
		if(this.aspect == "Blood"){
			hp = hp * 2;
			tl = tl/2;
		}
		if(this.aspect == "Mind"){
			fw = fw *2;
			hp = hp * 2;
		}
		if(this.aspect == "Rage"){
			tl = tl *2;
			power = power*2;
		}
		if(this.aspect == "Void") power = power *4;
		if(this.aspect == "Time") fw = fw /4;
		if(this.aspect == "Heart"){
			power = power *2;
			ml = ml & 2;
		}
		if(this.aspect == "Breath") mob = mob *4;
		if(this.aspect == "Light") xl = xl *4;
		if(this.aspect == "Space") mob = mob /4;

		denizenMinion.setStats(ml,xl,hp,mob,tl,fw,power,true, false, [],1000000);
		power = 50*strength;
		if(this.aspect == "Hope") power = power *4; //only power and hp need recalced, will be same for all others.
		hp = 100* strength;
		if(this.aspect == "Life") hp = hp *4;
		if(this.aspect == "Doom"){
			 hp = hp/2;
			 ml = ml/2;
		}
		denizen.setStats(ml,xl,hp,mob,tl,fw,power,true, false, [],1000000);
		this.denizen = denizen;
		this.denizenMinion = denizenMinion;
	}

	this.getDenizenNameArray = function(){
		if(this.aspect == "Blood") return this.bloodDenizenNames();
		if(this.aspect == "Mind") return this.mindDenizenNames();
		if(this.aspect == "Rage") return this.rageDenizenNames();
		if(this.aspect == "Void") return this.voidDenizenNames();
		if(this.aspect == "Time") return this.timeDenizenNames();
		if(this.aspect == "Heart") return this.heartDenizenNames();
		if(this.aspect == "Breath") return this.breathDenizenNames();
		if(this.aspect == "Light") return this.lightDenizenNames();
		if(this.aspect == "Space") return this.spaceDenizenNames();
		if(this.aspect == "Hope") return this.hopeDenizenNames();
		if(this.aspect == "Life") return this.lifeDenizenNames();
		if(this.aspect == "Doom") return this.doomDenizenNames();
		return ["ERROR 404: DENIZEN NOT FOUND"]
	}
	//discord generated most of these names.
	this.bloodDenizenNames = function(){
		return ['Blood','Hera','Hestia','Bastet','Bes','Vesta','Eleos','Sanguine','Medusa','Frigg','Debella','Juno','Moloch','Baal','Eusebeia','Horkos','Homonia','Harmonia','Philotes'];
	}

	this.mindDenizenNames = function(){
		return ['Mind','Athena','Forseti','Janus','Anubis','Maat','Seshat','Thoth','Jyglag','Peryite','Nomos','Lugus','Sithus','Dike','Epimetheus','Metis','Morpheus','Omoikane','Argus','Hermha','Morha','Sespille','Selcric','Tzeench']
	}

	this.rageDenizenNames = function(){
		return ['Rage','Ares','Dyonisus','Bacchus','Abbadon','Mammon','Mania','Asmodeus','Belphegor','Set','Apophis','Nemesis','Menoetius','Shogorath','Loki','Alastor','Mol Bal','Deimos','Achos','Pallas','Deimos','Ania','Lupe','Lyssa','Ytilibatsni','Discord'];
	}

	this.voidDenizenNames = function(){
		return ['Void','Selene','Erebus','Nix','Artemis','Kuk','Kaos','Hypnos','Tartarus','Hœnir','Skoll',"Czernobog",'Vermina','Vidar','Asteria','Nocturne','Tsukuyomi','Leviathan','Hecate','Harpocrates','Diova'];
	}

	this.timeDenizenNames = function(){
		return ['Time','Ignis','Saturn','Cronos','Aion','Hephaestus','Vulcan','Perses','Prometheus','Geras','Acetosh','Styx','Kairos','Veter','Gegute','Etu','Postverta and Antevorta','Emitus','Moirai'];
	}

	this.heartDenizenNames = function(){
		return ['Heart','Aphrodite','Baldur','Eros','Hathor','Philotes','Anubis','Psyche','Mora','Isis','Jupiter', 'Narcissus','Hecate','Izanagi','Izanami','Ishtar','Anteros','Agape','Peitho','Mahara','Naidraug','Snoitome','Walthidian','Slanesh','Benu'];
	}

	this.breathDenizenNames = function(){
		return ['Breath','Ninlil','Ouranos','Typheus','Aether','Amun','Hermes','Shu','Sobek','Aura','Theia','Lelantos','Keenarth','Aeolus','Aurai','Zephyrus','Ventus','Sora','Htaerb','Worlourier','Quetzalcoatl'];
	}

	this.lightDenizenNames = function(){
		return ['Light','Helios','Ra','Cetus','Iris','Heimdall','Apollo','Coeus','Hyperion', "Belobog",'Phoebe','Metis','Eos','Dagr','Asura','Amaterasu','Sol','Tyche','Odin ','Erutuf'];
	}

	this.spaceDenizenNames = function(){
		return ['Space','Gaea','Nut','Echidna','Wadjet','Qetesh','Ptah','Geb','Fryja','Atlas','Hebe','Lork','Eve','Genesis','Morpheus','Veles ','Arche','Rekinom','Iago','Pilera','Tiamat','Gilgamesh','Implexel'];
	}


	this.hopeDenizenNames = function(){
		return ['Hope','Isis','Marduk','Fenrir','Apollo','Sekhmet','Votan','Wadjet','Baldur','Zanthar','Raphael','Metatron','Jerahmeel','Gabriel','Michael','Cassiel','Gavreel','Aariel','Uriel','Barachiel ','Jegudiel','Samael','Taylus','Tzeench'];
	}

	this.lifeDenizenNames = function(){
		return ['Life','Demeter','Pan','Nephthys','Ceres','Isis','Hemera','Andhrímnir','Agathodaemon','Eir','Baldur','Prometheus','Adonis','Geb','Panacea','Aborof','Nurgel','Adam'];
	}

	this.doomDenizenNames = function(){
		return ['Doom','Hades','Achlys','Cassandra','Osiris','Ananke','Thanatos','Moros','Iapetus','Themis','Aisa','Oizys','Styx','Keres','Maat','Castor and Pollux','Anubis','Azrael','Ankou','Kapre','Moros','Atropos','Oizys','Korne','Odin'];
	}

	this.strongDenizenNames = function(){
		var ret = ['Yaldabaoth', 'Jörmungandr','Apollyon','Siseneg','Borunam','Jadeacher','Karmiution','Authorot','Aspiratcher','Recurscker','Insurorracle','Maniomnia','Kazerad','Shiva','Goliath'];
		return getRandomElementFromArray(ret);
	}

	this.weakDenizenNames = function(){
		var ret = ['Eriotur','Abraxas','Succra','Watojo','Bluhubit','Swefrat','Helaja','Fischapris'];
		return getRandomElementFromArray(ret);
	}



	//flipping out over the dead won't call this but everything else will.
	this.flipOut = function(reason){
		//console.log("flip out method called for: " + reason)
		this.flippingOutOverDeadPlayer = null;
		this.flipOutReason = reason;
	}

	this.interestedIn = function(interestWord,interestNum){
		if(!interestNum){
			if(interestWord == "Comedy") return playerLikesComedy(this)
			if(interestWord == "Music") return playerLikesMusic(this)
			if(interestWord == "Culture") return playerLikesCulture(this)
			if(interestWord == "Writing") return playerLikesWriting(this)
			if(interestWord == "Athletic") return playerLikesAthletic(this)
			if(interestWord == "Terrible") return playerLikesTerrible(this)
			if(interestWord == "Justice") return playerLikesJustice(this)
			if(interestWord == "Fantasy") return playerLikesFantasy(this)
			if(interestWord == "Domestic") return playerLikesDomestic(this)
			if(interestWord == "PopCulture") return playerLikesPopculture(this)
			if(interestWord == "Technology") return playerLikesTechnology(this)
			if(interestWord == "Social") return playerLikesSocial(this)
			if(interestWord == "Romance") return playerLikesRomantic(this)
			if(interestWord == "Academic") return playerLikesAcademic(this)
			return false;
		}else if(interestNum == 1){
			if(interestWord == "Comedy") return comedy_interests.indexOf(this.interest1) != -1
			if(interestWord == "Music") return music_interests.indexOf(this.interest1) != -1
			if(interestWord == "Culture") return culture_interests.indexOf(this.interest1) != -1
			if(interestWord == "Writing") return writing_interests.indexOf(this.interest1) != -1
			if(interestWord == "Athletic") return athletic_interests.indexOf(this.interest1) != -1
			if(interestWord == "Terrible") return terrible_interests.indexOf(this.interest1) != -1
			if(interestWord == "Justice") return justice_interests.indexOf(this.interest1) != -1
			if(interestWord == "Fantasy") return fantasy_interests.indexOf(this.interest1) != -1
			if(interestWord == "Domestic") return domestic_interests.indexOf(this.interest1) != -1
			if(interestWord == "PopCulture") return pop_culture_interests.indexOf(this.interest1) != -1
			if(interestWord == "Technology") return technology_interests.indexOf(this.interest1) != -1
			if(interestWord == "Social") return social_interests.indexOf(this.interest1) != -1
			if(interestWord == "Romance") return romantic_interests.indexOf(this.interest1) != -1
			if(interestWord == "Academic") return academic_interests.indexOf(this.interest1) != -1
		}else if(interestNum == 2){
			if(interestWord == "Comedy") return comedy_interests.indexOf(this.interest2) != -1
			if(interestWord == "Music") return music_interests.indexOf(this.interest2) != -1
			if(interestWord == "Culture") return culture_interests.indexOf(this.interest2) != -1
			if(interestWord == "Writing") return writing_interests.indexOf(this.interest2) != -1
			if(interestWord == "Athletic") return athletic_interests.indexOf(this.interest2) != -1
			if(interestWord == "Terrible") return terrible_interests.indexOf(this.interest2) != -1
			if(interestWord == "Justice") return justice_interests.indexOf(this.interest2) != -1
			if(interestWord == "Fantasy") return fantasy_interests.indexOf(this.interest2) != -1
			if(interestWord == "Domestic") return domestic_interests.indexOf(this.interest2) != -1
			if(interestWord == "PopCulture") return pop_culture_interests.indexOf(this.interest2) != -1
			if(interestWord == "Technology") return technology_interests.indexOf(this.interest2) != -1
			if(interestWord == "Social") return social_interests.indexOf(this.interest2) != -1
			if(interestWord == "Romance") return romantic_interests.indexOf(this.interest2) != -1
			if(interestWord == "Academic") return academic_interests.indexOf(this.interest2) != -1
		}
	}

	//if change would push me over 3, render 'cause i'm newly grimdark
	//if it would pull be from over 3, render 'cause i have somewhat recovered.
	this.changeGrimDark = function(val){
		//this.grimDark += val;
		var tmp = this.grimDark + val;
		var render = false;

		if(this.grimDark <= 3 && tmp > 3){ //newly GrimDark
			console.log("grim dark 3 or more in session: " + this.session.session_id)
			render = true;
		}else if(this.grimDark >3 && tmp <=3){ //newly recovered.
			render = true;
		}
		this.grimDark += val;
		if(render){
			this.renderSelf();
		}

	}

	this.makeMurderMode = function(){
		this.murderMode = true;
		this.increasePower();
		this.renderSelf(); //new scars. //can't do scars just on top of sprite 'cause hair might cover.'
	}

	this.unmakeMurderMode = function(){
		this.murderMode = false;
		this.leftMurderMode = true;
		this.renderSelf();
	}

	this.makeDead = function(causeOfDeath){
		this.dead = true;
		this.causeOfDeath = causeOfDeath;
		//was in make alive, but realized that this makes doom ghosts way stronger if it's here. powered by DEATH, but being revived.
		if(this.aspect == "Doom"){ //powered by their own doom.
			//console.log("doom is powered by their own death: " + this.session.session_id) //omg, they are sayians.
			this.power += 50;
			this.hp = 100; //prophecy fulfilled. but hp and luck will probably drain again.
			this.minLuck = 100; //prophecy fulfilled. you are no longer doomed.
		}
		if(!this.godTier){ //god tiers only make ghosts in GodTierRevivial
			this.session.afterLife.addGhost(makeRenderingSnapshot(this));
		}

		this.renderSelf();
		this.triggerOtherPlayersWithMyDeath();
	}

	//this used to happen in beTriggered. fuck that noise, it was shit.
	this.triggerOtherPlayersWithMyDeath = function(){
		//go through my relationships. if i am the only dead person, trigger everybody (death still has impact)
		//trigger (possibly ontop of base trigger) friends, and quadrant mates. really fuck up my moirel(s) if i have any
		//if triggered, also give a flip out reason.
		var dead = findDeadPlayers(this.session.players);
		for(var i = 0; i <this.relationships.length; i++){
			var r = this.relationships[i];

			if(r.saved_type == r.goodBig){
				r.target.sanity += -1;
				if(r.target.flipOutReason == null){
					r.target.flipOutReason = " their dead crush, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead crush.
					r.target.flippingOutOverDeadPlayer = this;
				}
			}else if(r.value > 0){
				r.target.sanity += -1;
				if(r.target.flipOutReason == null){
					 r.target.flippingOutOverDeadPlayer = this;
					 r.target.flipOutReason = " their dead friend, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead friend.
				}
			}else if(r.saved_type == r.spades){
				r.target.sanity += -10;
				r.target.flipOutReason = " their dead Kismesis, the " + this.htmlTitleBasic();
				r.target.flippingOutOverDeadPlayer = this;
			}else if(r.saved_type == r.heart){
				r.target.sanity += -10
				r.target.flipOutReason = " their dead Matesprit, the " + this.htmlTitleBasic();
				r.target.flippingOutOverDeadPlayer = this;
			}
			else if(r.saved_type == r.diamond){
				r.target.sanity += -100
				r.target.damageAllRelationships();
				r.target.damageAllRelationships();
				r.target.damageAllRelationships();
				r.target.flipOutReason = " their dead Moirail, the " + this.htmlTitleBasic() + ", fuck, that can't be good...";
				r.target.flippingOutOverDeadPlayer = this;
			}
			//console.log(r.target.title() + " has flipOutReason of: " + r.target.flipOutReason + " and knows about dead player: " + r.target.flippingOutOverDeadPlayer);
		}

		//whether or not i care about them, there's also the novelty factor.
		if(dead.length == 1){  //if only I am dead, death still has it's impact and even my enemies care.
			r.target.sanity += -1;
			if(r.target.flipOutReason == null){
				r.target.flipOutReason = " the dead player, the " + this.htmlTitleBasic(); //don't override existing flip out reasons. not for something as generic as a dead player.
			 r.target.flippingOutOverDeadPlayer = this;
			}
		}
	}

	//needed'cause ghost pacts are a an array of pairs now so i know how i'm reviving.
	this.getPactWithGhost = function(ghost){
		for(var i = 0; i<this.ghostPacts.length; i++){
			var g = this.ghostPacts[i][0]
			if(g == ghost) return g
		}
		return null;
	}

	this.getSpades = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.spades){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getCrushes = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.goodBig){
				ret.push(r);
			}
		}
		return ret;
	}

	this.getBlackCrushes = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.badBig){
				ret.push(r);
			}
		}
		return ret;
	}


	this.getDiamonds = function(){
		var ret = [];
		for (var i = 0; i<this.relationships.length; i++){
			var r = this.relationships[i];
			if(r.saved_type == r.diamond){
				ret.push(r);
			}
		}
		return ret;
	}


	this.chatHandleShort = function(){
		return this.chatHandle.match(/\b(\w)|[A-Z]/g).join('').toUpperCase();
	}

	this.chatHandleShortCheckDup = function(otherHandle){
		var tmp= this.chatHandle.match(/\b(\w)|[A-Z]/g).join('').toUpperCase();
		if(tmp == otherHandle){
			tmp = tmp + "2";
		}
		return tmp;
	}

	//what happened when you reached god tier was too inconsistent, and also
	//this lets sprite be updated.
	this.makeGodTier = function(){
		this.hp += 500; //they are GODS.
		this.power += 500;
		this.increasePower();
		this.godTier = true;
		this.session.godTier = true;
		this.dreamSelf = false;
		this.canGodTierRevive = true;
		this.leftMurderMode = false; //no scars, unlike other revival methods
		this.isDreamSelf = false;
		this.makeAlive();
	}



	this.makeAlive = function(){
			if(this.stateBackup) this.stateBackup.restoreState(this);
			this.influencePlayer = null;
			this.influenceSymbol = null;
			this.dead = false;
			this.murderMode = false;
			this.currentHP = Math.max(this.hp,1); //if for some reason your hp is negative, don't do that.
			this.grimDark = 0;
			this.sanity += -11;  //dying is pretty triggering.
			this.flipOutReason = "they just freaking died"
			//this.leftMurderMode = false; //no scars
			this.victimBlood = null; //clean face
			this.renderSelf();
		}




	this.title = function(){
		var ret = "";

		if(this.doomed){
			ret += "Doomed "
		}



		if(this.trickster){
			ret += "Trickster "
		}

		if(this.murderMode){
			ret += "Murder Mode ";
		}

		if(this.grimDark>3){
			ret += "Severely Grim Dark ";
		}else if(this.grimDark > 1){
			ret += "Mildly Grim Dark ";
		}else if(this.grimDark >2){
			ret += "Grim Dark ";
		}

		if(this.godTier){
			ret+= "God Tier "
		}else if(this.isDreamSelf){
			ret+= "Dream ";
		}
		if(this.robot){
			ret += "Robo"
		}
		ret+= this.class_name + " of " + this.aspect;
		if(this.dead){
			ret += "'s Corpse"
		}else if(this.ghost){
			ret += "'s Ghost"
		}
		ret += " (" + this.chatHandle + ")"
		return ret;
	}

	this.htmlTitleBasic = function(){
			return getFontColorFromAspect(this.aspect) + this.titleBasic() + "</font>"
	}

	this.titleBasic = function(){
		var ret = "";

		ret+= this.class_name + " of " + this.aspect;
		return ret;
	}

	//old method from 1.0
	this.getRandomLevel = function(){
		if(Math.seededRandom() > .5){
			return getRandomLevelFromAspect(this.aspect);
		}else{
			return getRandomLevelFromClass(this.class_name);
		}
	}

//new method having to pick 16 levels before entering the medium
	this.getNextLevel = function(){
		this.level_index ++;
		var ret= this.mylevels[this.level_index];
		return ret;
	}

	this.getRandomQuest = function(){
		if(this.landLevel >= 9 && this.denizen_index < 3 && this.denizenDefeated == false){ //three quests before denizen
			//console.log("denizen quest")
			return getRandomDenizenQuestFromAspect(this); //denizen quests are aspect only, no class.
		}else if((this.landLevel < 9 || this.denizen_index >=3) && this.denizenDefeated == false){  //can do more land quests if denizen kicked your ass. need to grind.
			if(Math.seededRandom() > .5 || this.aspect == "Space"){ //back to having space players be locked to frogs.
				return getRandomQuestFromAspect(this.aspect);
			}else{
				return getRandomQuestFromClass(this.class_name);
			}
		}else if(this.denizenDefeated){
			//console.log("post denizen quests " +this.session.session_id);
			//return "restoring their land from the ravages of " + this.session.getDenizenForPlayer(this).name;
			if(Math.seededRandom() > .5 || this.aspect == "Space"){ //back to having space players be locked to frogs.
				return getRandomQuestFromAspect(this.aspect,true);
			}else{
				return getRandomQuestFromClass(this.class_name,true);
			}
		}

	}

	this.decideHemoCaste  =function (){
		if(this.aspect != "Blood"){  //sorry karkat
			this.bloodColor = getRandomElementFromArray(bloodColors);
		}
	}

	this.decideLusus = function(player){
		if(this.bloodColor == "#610061" || this.bloodColor == "#99004d" || this.bloodColor == "#631db4" ){
			this.lusus = getRandomElementFromArray(sea_lusus_objects);
		}else{
			this.lusus = getRandomElementFromArray(lusus_objects);
		}
	}

	this.isVoidAvailable = function(){
		var light = findAspectPlayer(findLivingPlayers(this.session.players), "Light");
		if(light && light.godTier) return false;
		return true;
	}

	//classes only, at least for now
	this.getPVPModifier = function(role){
		if(role == "Attacker") return this.getAttackerModifier();
		if(role == "Defender") return this.getDefenderModifier();
		if(role == "Murderer") return this.getMurderousModifier();

	}

	this.renderable = function(){
		return true;
	}

	//basically free will shit. choosing to kill a player despite not being crazy
	this.getAttackerModifier = function(){
		if(this.class_name == "Knight") return 1.0;
		if(this.class_name == "Seer") return 0.67;
		if(this.class_name == "Bard") return 2.0;
		if(this.class_name == "Maid") return 0.33;
		if(this.class_name == "Heir") return 0.5;
		if(this.class_name == "Rogue") return 1.25;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 1.5;
		if(this.class_name == "Sylph") return 2.5;
		if(this.class_name == "Prince") return 5.0;
		if(this.class_name == "Witch") return 2.0;
		if(this.class_name == "Mage") return 0.67;
		return 1.0;
	}



	//defending yourself from an attack
	this.getDefenderModifier = function(){
		if(this.class_name == "Knight") return 2.5;
		if(this.class_name == "Seer") return 0.67;
		if(this.class_name == "Bard") return 0.5;
		if(this.class_name == "Maid") return 3.0;
		if(this.class_name == "Heir") return 2.0;
		if(this.class_name == "Rogue") return 1.25;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 0.8;
		if(this.class_name == "Sylph") return 1.0;
		if(this.class_name == "Prince") return 0.33;
		if(this.class_name == "Witch") return 1.0;
		if(this.class_name == "Mage") return 0.67;
		return 1.0;
	}

	//being shit flippingly crazy AND initiating a fight
	this.getMurderousModifier = function(){
		if(this.class_name == "Knight") return 0.75;
		if(this.class_name == "Seer") return 1.0;
		if(this.class_name == "Bard") return 3.0;
		if(this.class_name == "Maid") return 1.5;
		if(this.class_name == "Heir") return 1.5;
		if(this.class_name == "Rogue") return 1.0;
		if(this.class_name == "Page"){
			if(this.godTier){
				return 5.0;
			}else{
				return 1.0;
			}
		}
		if(this.class_name == "Thief") return 1.0;
		if(this.class_name == "Sylph") return 1.5;
		if(this.class_name == "Prince") return 1.5;
		if(this.class_name == "Witch") return 1.5;
		if(this.class_name == "Mage") return 1.5;
		return 1.0;
	}


	this.getDenizen = function(){
		return this.denizen.name; //<--convineint that it wasn't hard to upgrade.
	}

	this.didDenizenKillYou = function(){
		if(this.causeOfDeath.indexOf(this.denizen.name) != -1){
			return true; //also return true for minions. this is intentional.
		}
		return false;
	}

	//more likely if lots of people hate you
	this.justDeath = function(){
		var ret = false;

		//impossible to have a just death from a denizen or denizen minion. unless you are corrupt.
		if(this.didDenizenKillYou() && !this.grimDark <= 2){
			return false;
		}else if(this.grimDark > 2){
			console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!just death for a corrupt player from their denizen or denizen minion in session: " + this.session.session_id)
			return true; //always just if the denizen puts down a corrupt player.
		}


		//if much less friends than enemies.
		if(this.getFriends().length < this.getEnemies().length){
			if(Math.seededRandom() > .9){ //just deaths are rarer without things like triggers.
				ret = true;
			}
			//way more likely to be a just death if you're being an asshole.


			if((this.murderMode || this.grimDark > 2)){
				var rand = Math.seededRandom()
				//console.log("rand is: " + rand)
				if(rand > .2){
					//console.log(" just death for: " + this.title() + "rand is: " + rand)
					ret = true;
				}
			}
		}else{  //you are a good person. just corrupt.
			//way more likely to be a just death if you're being an asshole.
			if((this.murderMode || this.grimDark > 2) && Math.seededRandom()>.5){
				ret = true;
			}
		}
		//console.log(ret);
		//return true; //for testing
		return ret;
	}

	//more likely if lots of people like you
	this.heroicDeath = function(){
		var ret = false;

		//it's not heroic derping to death against a minion or whatever, or in a solo fight.
		if(this.didDenizenKillYou() || this.causeOfDeath == "from a Bad Break."){
			return false;
		}

		//if far more enemies than friends.
		if(this.getFriends().length > this.getEnemies().length ){
			if(Math.seededRandom() > .6){
				ret = true;
			}
			//extra likely if you just killed the king/queen, you hero you.
			if(curSessionGlobalVar.kingStrength <=0 && Math.seededRandom()>.2){
				ret = true;
			}
		}else{ //unlikely hero
			if(Math.seededRandom() > .8){
				ret = true;
			}
			//extra likely if you just killed the king/queen, you hero you.
			if(curSessionGlobalVar.kingStrength <=0 && Math.seededRandom()>.4){
				ret = true;
			}
		}

		if(ret){
			//console.log("heroic death");
		}
		return ret;
	}



	this.hasInteractionEffect = function(){
		return this.class_name == "Prince" || this.class_name == "Bard"|| this.class_name == "Witch"|| this.class_name == "Sylph"|| this.class_name == "Rogue"|| this.class_name == "Thief"
	}

	this.associatedStatsInteractionEffect = function(player){
		if(this.hasInteractionEffect()){ //don't even bother if you don't have an interaction effect.
			for(var i = 0; i<this.associatedStats.length; i++){
				this.processStatInteractionEffect(player, this.associatedStats[i]);
			}
		}
	}


	this.processStatInteractionEffect = function(player, stat){
		var powerBoost = this.power/20;
		if(this.class_name == "Witch"|| this.class_name == "Sylph"){
			powerBoost = powerBoost *  2 //sylph and witch get their primary boost here, so make it a good one.
		}
		var powerBoost = this.modPowerBoostByClass(powerBoost,stat);
		if(this.class_name == "Rogue"|| this.class_name == "Thief"){
			player.modifyAssociatedStat((-1 * powerBoost), stat);
			if(this.isActive()){ //modify me
				this.modifyAssociatedStat(powerBoost, stat);
			}else{  //modify others.
				for(var i = 0; i<this.session.players.length; i++){
					this.session.players[i].modifyAssociatedStat(powerBoost/this.session.players.length, stat);
				}
			}
		}else{
			if(this.isActive()){ //modify me
				this.modifyAssociatedStat(powerBoost, stat);
			}else{  //modify others.
				player.modifyAssociatedStat(powerBoost, stat);
			}
		}
	}

	this.interactionEffect = function(player){

		this.associatedStatsInteractionEffect(player);

		//no longer do this seperate. if close enough to modify with powers, close enough to be...closer.
		r1 = this.getRelationshipWith(player);
		if(r1){
			r1.moreOfSame();
		}

	}

	//SBURB is not a mystery to these classes/aspects.
	this.knowsAboutSburb = function(){
		//time might not innately get it, but they have future knowledge
		var rightClass = this.class_name == "Seer" || this.class_name == "Mage" || this.aspect == "Light" || this.aspect == "Mind" || this.aspect == "Doom" || this.aspect == "Time"
		return rightClass && this.power > 20; //need to be far enough in my claspect
	}

	this.performEctobiology = function(session){
		session.ectoBiologyStarted = true;
		playersMade = findPlayersWithoutEctobiologicalSource(session.players);
		setEctobiologicalSource(playersMade, session.session_id)
		return playersMade;
	}

	this.isActive = function(){
		return active_classes.indexOf(this.class_name) != -1;
	}



	//each player knows how to generate their own guardian.
	this.makeGuardian =function(){
		//console.log("guardian for " + player.titleBasic());
		var player = this;
		var possibilities = active_classes;
		if(this.isActive()) possibilities = passive_classes;
		var guardian = randomPlayerWithClaspect(this.session, getRandomElementFromArray(possibilities), this.aspect);

		guardian.isTroll = player.isTroll;
		guardian.quirk.favoriteNumber = player.quirk.favoriteNumber;
		if(guardian.isTroll){
			guardian.quirk = randomTrollSim(guardian) //not same quirk as guardian
		}else{
			guardian.quirk = randomHumanSim(guardian);
		}

		guardian.bloodColor = player.bloodColor;
		guardian.lusus = player.lusus;
		if(guardian.isTroll == true){ //trolls always use lusus.
			guardian.object_to_prototype = player.object_to_prototype;
		}
		guardian.hairColor = player.hairColor;

		//console.log("Guardian className: " + guardian.class_name + " Player was: " + this.class_name);
		guardian.leftHorn = player.leftHorn;
		guardian.rightHorn = player.rightHorn;
		guardian.level_index = 5; //scratched kids start more leveled up
		guardian.power = 50;
		guardian.leader = player.leader;
		if(Math.seededRandom() >0.5){ //have SOMETHING in common with your ectorelative.
			guardian.interest1 = player.interest1;
		}else{
			guardian.interest2 = player.interest2;
		}
		guardian.initializeDerivedStuff();//redo levels and land based on real aspect
		//this.guardians.push(guardian); //sessions don't keep track of this anymore
		player.guardian = guardian;
		guardian.guardian = this;//goes both ways.
	}



	this.associatedStatsIncreasePower = function(powerBoost){
		//modifyAssociatedStat
		for(var i = 0; i< this.associatedStats.length; i++){
			this.processStatPowerIncrease(powerBoost, this.associatedStats[i]);
		}
	}

	this.modPowerBoostByClass = function(powerBoost,stat){
		switch (this.class_name) {
			case "Knight":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 2;
				}else{
					powerBoost = powerBoost * 0.5
				}
				break;
			case  "Seer":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 1;
				}else{
					powerBoost = powerBoost * 0.25
				}
				break;
			case  "Bard":
				var lolrandoms = [-1, 1,2,-1,0.25,-0.25,0.5,-0.5]
				powerBoost = powerBoost * getRandomElementFromArray(lolrandoms);
				break;
			case  "Heir":
				powerBoost = powerBoost * 1.5;
				break;
			case  "Maid":
				powerBoost = powerBoost * 1.5;
				break;
			case  "Rogue":
				powerBoost = powerBoost * 0.5;
				break;
			case  "Page":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 2;
				}else{
					powerBoost = powerBoost * 0.5
				}
				break;
			case  "Thief":
				powerBoost = powerBoost * 0.5;
				break;
			case  "Sylph":
				powerBoost = powerBoost * 1;
				break;
			case  "Prince":
				var lolrandoms = [-1, 1,2,-1,0.25,-0.25,0.5,-0.5]
				powerBoost = powerBoost * getRandomElementFromArray(lolrandoms);
				break;
			case  "Witch":
				powerBoost = powerBoost * 1;
				break;
			case  "Mage":
				if(stat.multiplier > 0){
					powerBoost = powerBoost * 1;
				}else{
					powerBoost = powerBoost * 0.25
				}
				break;
			default:
				console.log('What the hell kind of class is ' + this.class_name + '???');
		}

		return powerBoost;
	}

	this.processStatPowerIncrease = function(powerBoost, stat){
		var powerBoost = this.modPowerBoostByClass(powerBoost,stat);
		if(this.isActive()){ //modify me
			this.modifyAssociatedStat(powerBoost, stat);
		}else{  //modify others.
			for(var i = 0; i<this.session.players.length; i++){
				this.session.players[i].modifyAssociatedStat(powerBoost, stat);
			}
		}
	}


	this.increasePower = function(){
		if(Math.seededRandom() >.9){
			this.leveledTheHellUp = true; //that multiple of ten thing is bullshit.
		}
		var powerBoost = 1;

		if(this.class_name == "Page"){  //they don't have many quests, but once they get going they are hard to stop.
			powerBoost = powerBoost * 5;
		}

		if(this.aspect == "Hope"){
			powerBoost = powerBoost * 2;
		}

		if(this.godTier){
			powerBoost = powerBoost * 20;  //god tiers are ridiculously strong.
		}

		if(this.denizenDefeated){
			powerBoost = powerBoost * 2; //permanent doubling of stats forever.
		}

		this.power += powerBoost;
		this.associatedStatsIncreasePower(powerBoost);
		//gain a bit of hp, otherwise denizen will never let players fight them if their hp isn't high enough.
		if(this.godTier || Math.seededRandom() >.25){
			this.hp += 10;
			this.currentHP += 10;
		}

	}

	this.shortLand = function(){
		return this.land.match(/\b(\w)/g).join('').toUpperCase();
	}

{'fraction_non_alphanumeric': 0.15074609630608554, 'fraction_numerical': 0.011778442114987362, 'mean_word_length': 3.9795553283925376, 'pattern_counts': {'":': 24, '<': 49, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 8, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2603013', 'n_tokens_mistral': 30675, 'n_tokens_neox': 26908, 'n_words': 6595}