<commit_before>//okay, fine, yes, global variables are getting untenable.
function Session(session_id){
	this.session_id = session_id; //initial seed
	this.players = [];
	this.hasClubs = false;
	this.sessionHealth = 5000; //grimDark players work to lower it. at 0, it crashes.  maybe have it do other things at other levels, or effect other things.
	this.hasDiamonds = false;
	this.afterLife = new AfterLife();
	this.queensRing = null; //eventually have white and black ones.
	this.kingsScepter = null;
	this.hasHearts = false;
	this.hasSpades = false;
	this.denizenBeat = false;
	//session no longer keeps track of guardians.
	this.king = null;
	this.queen = null;
	this.rapBattle = false;
	this.crashedFromSessionBug = false; //gets corrupted if an unrecoverable error gets caught.
	this.crashedFromPlayerActions = false;
	this.sickFires = false;
	this.dreamBubbleAfterlife = false;
	this.democraticArmy = null;
	this.sbahj = false;
	this.heroicDeath = null;
	this.won = false;
	this.justDeath = null;
	this.hardStrength = 275;
	this.minFrogLevel = 18;
	this.goodFrogLevel = 28;
	this.democracyStrength = 0;
	this.reckoningStarted = false;
	this.aliensClonedOnArrival = []; //if i'm gonna do time shenanigans, i need to know what the aliens were like when they got here.
	this.murdersHappened = false;
	this.goodLuckEvent = false;
	this.badLuckEvent = false;
	this.hasFreeWillEvents = false;
	this.ectoBiologyStarted = false;
	this.doomedTimeline = false;
	this.makeCombinedSession = false; //happens if sick frog and few living players
	this.scratched = false;
	this.scratchAvailable = false;
	this.timeTillReckoning = 0;
	this.godTier = false;
	this.questBed = false;
	this.sacrificialSlab = false;
	this.sessionType = -999
	this.scenesTriggered = []; //this.scenesTriggered
	this.doomedTimelineReasons = [];
	this.currentSceneNum = 0;
	this.scenes = []; //scene controller initializes all this.
	this.reckoningScenes = [];
	this.deathScenes = [];
	this.available_scenes = [];
	this.hadCombinedSession = false;
	this.parentSession = null;
	this.availablePlayers = [];  //which players are available for scenes or whatever.
	this.importantEvents = [];
	this.yellowYardController = new YellowYardResultController();//don't expect doomed time clones to follow them to any new sessions

	//IMPORTANT do not add important events directly, or can't check for alternate timelines.
	//oh god, just typing that gives me chills. time shenanigans are so great.
	this.addImportantEvent = function(important_event){
		var alternate = this.yellowYardController.doesEventNeedToBeUndone(important_event);
	//	console.log("alternate i got from yellowYardController is: " + alternate)
		if(alternate){
		//	console.log("returning alternate")
			return alternate; //scene will use the alternate to go a different way. important event no longer happens.
		}else{
			//console.log(" pushing important event and returning null")
			this.importantEvents.push(important_event);
			return null;
		}
	}

	this.frogStatus = function(){
		var spacePlayer = findAspectPlayer(this.players, "Space");
		if(spacePlayer.landLevel < this.minFrogLevel){
			return "No Frog"
		}else if(spacePlayer.landLevel > this.goodFrogLevel){
			return "Full Frog"
		}else{
			return "<NAME>"
		}

	}

	//make Math.seed  = to my session id, reinit all my variables (similar to a scratch.)
	//make sure the controller starts ticking again. very similar to scrach
	this.addEventToUndoAndReset = function(e){
		//console.log("undoing an event.")
		if(this.scratched){
			return this.addEventToUndoAndResetScratch(e); //works different
		}
		if(e){//will be null if undoing an undo
			this.yellowYardController.eventsToUndo.push(e);
		}
		//reinit the seed and restart the session
		var savedPlayers = curSessionGlobalVar.players;
		this.reinit();
		createScenesForSession(curSessionGlobalVar);
		//players need to be reinit as well.
		curSessionGlobalVar.makePlayers();
		curSessionGlobalVar.randomizeEntryOrder();
		curSessionGlobalVar.makeGuardians(); //after entry order established
		checkEasterEgg(); //in the controller.
		//now that i've done that, (for seed reasons) fucking ignore it and stick the actual players in
		//after alll, i could be from a combo session.
		//but don't just hardcore replace. need to...fuck. okay, cloning aliens now.
		curSessionGlobalVar.aliensClonedOnArrival = this.aliensClonedOnArrival;
		//console.log("adding this many clone aliens: " + curSessionGlobalVar.aliensClonedOnArrival.length)
		//console.log(getPlayersTitles(curSessionGlobalVar.aliensClonedOnArrival));
		var living = []  //if don't make copy of aliensClonedOnArrival, goes into an infinite loop as it loops on it and adds to it inside of addAliens
		for(var i = 0; i<this.aliensClonedOnArrival.length; i++){
			living.push(this.aliensClonedOnArrival[i])
		}
		this.aliensClonedOnArrival = [];//jettison old clones.
		addAliensToSession(curSessionGlobalVar, living);

		restartSession();//in controller
	}

	this.addEventToUndoAndResetScratch = function(e){
		console.log('yellow yard from scratched session')
		if(e){//will be null if undoing an undo
			this.yellowYardController.eventsToUndo.push(e);
		}
		var ectoSave = this.ectoBiologyStarted;
		reinit();
		//use seeds the same was as original session and also make DAMN sure the players/guardians are fresh.
		curSessionGlobalVar.makePlayers();
		curSessionGlobalVar.randomizeEntryOrder();
		curSessionGlobalVar.makeGuardians(); //after entry order established
		this.ectoBiologyStarted = ectoSave;
		this.scratched = true;
		this.switchPlayersForScratch();



		restartSession();//in controller
	}

	//child sessions are basically any session with an ID that matches the seed you stop on
	//TODO could possibly be constrained to need a space or time player to navigage. or godtier light/doom??? could further require the player be from derse
	//but this already 2-4% of all sessions, do i really want it to  be even rarer?
	this.initializeCombinedSession = function(){
		this.aliensClonedOnArrival = []; //PROBABLY want to do this.
		var living = findLivingPlayers(this.players);
		//nobody is the leader anymore.
		var newSession = new Session(Math.seed);  //this is a real session that could have gone on without these new players.
		newSession.currentSceneNum = this.currentSceneNum;
		newSession.afterLife = this.afterLife; //afterlife carries over.
		newSession.dreamBubbleAfterlife = this.dreamBubbleAfterlife; //this, too
		newSession.reinit();
		newSession.makePlayers();
		newSession.randomizeEntryOrder();
		newSession.makeGuardians();
		if(living.length + newSession.players.length > 12){
			//console.log("New session " + newSession.session_id +" cannot support living players. Already has " + newSession.players.length + " and would need to add: " + living.length)
			return;  //their child session is not able to support them
		}
	//	console.log("about to add: " + living.length + " aliens to new session.")
		//console.log(getPlayersTitles(living));
		addAliensToSession(newSession, living);


		this.hadCombinedSession = true;
		newSession.parentSession = this;
		createScenesForSession(newSession);
		//console.log("Session: " + this.session_id + " has made child universe: " + newSession.session_id + " child has this long till reckoning: " + newSession.timeTillReckoning)
		return newSession;
	}

	this.getVersionOfPlayerFromThisSession = function(player){
		//can double up on classes or aspects if it's a combo session. god. why are their combo sessions?
		for(var i = 0; i< this.players.length; i++){
			var p = this.players[i];
			if(p.class_name == player.class_name && p.aspect == player.aspect){
				return p; //yeah, technically there COULD be two players with the same claspect in a combo session, but i have ceased caring.
			}
		}
		console.log("Error finding session's: " + player.title());
	}


	//if htis is used for scratch, manually save ectobiology cause it's getting reset here
	//DEFINITELY don't erase the afterlife. that's the whole point.
	this.reinit = function(){
		groundHog = false;
		Math.seed = this.session_id; //if session is reset,
		//console.log("reinit with seed: "  + Math.seed)
		this.timeTillReckoning = getRandomInt(10,30);
		this.sessionType = Math.seededRandom();
		curSessionGlobalVar.available_scenes = curSessionGlobalVar.scenes.slice(0);
		curSessionGlobalVar.doomedTimeline = false;
		this.setUpBosses();
		this.democracyStrength = 0;
		this.reckoningStarted = false;
		this.importantEvents = [];
		this.scenesTriggered = []; //this.scenesTriggered
		this.doomedTimelineReasons = [];
		this.ectoBiologyStarted = false;
	}

	this.makePlayers = function(){
		//console.log("Making players with seed: " + Math.seed)
		this.players = [];
		available_classes = classes.slice(0); //re-initPlayers available classes.
		available_aspects = nonrequired_aspects.slice(0);
		var numPlayers = getRandomInt(2,12);
		this.players.push(randomSpacePlayer(this));
		this.players.push(randomTimePlayer(this));

		for(var i = 2; i<numPlayers; i++){
			this.players.push(randomPlayer(this));
		}

		for(var j = 0; j<this.players.length; j++){
			var p = this.players[j];

			p.generateRelationships(this.players);
			this.decideTroll(p);

			if(p.isTroll){
				p.quirk = randomTrollSim(p)
			}else{
				p.quirk = randomHumanSim(p);
			}
		}

		decideInitialQuadrants(this.players);

		for(var k = 0; k<this.players.length; k++){
			//can't escape consequences.
			this.players[k].consequencesForGoodPlayer();
			this.players[k].consequencesForTerriblePlayer();
		}
	}

	this.convertPlayerNumberToWords = function(){
		//alien players don't count
		var ps = findPlayersFromSessionWithId(this.players, this.session_id);
		if(ps.length == 0){
			ps = this.players;
		}
		var length = ps.length;
		if(length == 2){
			return "TWO";
		}else if(length == 3){
			return "THREE";
		}else if(length == 4){
			return "FOUR";
		}else if(length == 5){
			return "FIVE";
		}else if(length == 6){
			return "SIX";
		}else if(length == 7){
			return "SEVEN";
		}else if(length == 8){
			return "EIGHT";
		}else if(length == 9){
			return "NINE";
		}else if(length == 10){
			return "TEN";
		}else if(length == 11){
			return "ELEVEN";
		}else if(length == 12){
			return "TWELVE";
		}
	}

	this.makeGuardians = function(){
		//console.log("Making guardians")
		available_classes = classes.slice(0);
		available_aspects = nonrequired_aspects.slice(0); //required_aspects
		available_aspects = available_aspects.concat(required_aspects.slice(0));
		var guardians = [];
		for(var i = 0; i<this.players.length; i++){
			  var player = this.players[i];
				//console.log("guardian for " + player.titleBasic());
				var guardian = randomPlayer(this);
				guardian.isTroll = player.isTroll;
				if(guardian.isTroll){
					guardian.quirk = randomTrollSim(guardian)
				}else{
					guardian.quirk = randomHumanSim(guardian);
				}
				guardian.quirk.favoriteNumber = player.quirk.favoriteNumber;
				guardian.bloodColor = player.bloodColor;
				guardian.lusus = player.lusus;
				if(guardian.isTroll == true){ //trolls always use lusus.
					guardian.kernel_sprite = player.kernel_sprite;
				}
				guardian.hairColor = player.hairColor;
				guardian.aspect = player.aspect;
				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.reinit();//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 = player;//goes both ways.
				guardians.push(guardian)
		}

		for(var j = 0; j<this.players.length; j++){
			var g = this.players[j].guardian;
			g.generateRelationships(guardians);
		}
		decideInitialQuadrants(guardians);

		for(var k = 0; k<this.players.length; k++){
			//can't escape consequences.
			this.players[k].guardian.consequencesForGoodPlayer();
			this.players[k].guardian.consequencesForTerriblePlayer();
		}
	}

	this.randomizeEntryOrder = function(){
		this.players = shuffle(this.players);
		this.players[0].leader = true;
	}

	/*
	no longer as simple as just switching players and guardians.
	need to only switch players who have an ectobiologicalSource of this session.
	*/
	this.switchPlayersForScratch = function(){
		//var tmp = curSessionGlobalVar.players;
		//curSessionGlobalVar.players = curSessionGlobalVar.guardians;
		//curSessionGlobalVar.guardians = tmp;
		var nativePlayers = findPlayersFromSessionWithId(this.players, this.session_id);
		//console.log(nativePlayers)
		var guardians = getGuardiansForPlayers(nativePlayers);
		this.players = guardians;
	}

	this.decideTroll = function decideTroll(player){
		if(this.getSessionType() == "Human"){
			return;
		}

		if(this.getSessionType() == "Troll" || (this.getSessionType() == "Mixed" &&Math.seededRandom() > 0.5) ){
			player.isTroll = true;
			player.hairColor = "#000000"
			player.triggerLevel ++;//trolls are less stable
			player.decideHemoCaste(player);
			player.decideLusus(player);
			player.kernel_sprite = player.lusus;
		}
	}


	this.getSessionType = function(){
		if(this.sessionType > .6){
			return "Human"
		}else if(this.sessionType > .3){
			return "Troll"
		}
		return "Mixed"
	}


	this.setUpBosses = function(){
		console.log("Test jack and queen can be exiled, queen rejects ring, king is powerful, boss fights, jack gets bullshit weapon, jack rampage, jack promotion.")
		this.queensRing = new GameEntity(this, "!!!RING!!! OMG YOU SHOULD NEVER SEE THIS!",false)
		this.queensRing.setStats(0,0,0,0,0,0,0,false, false, [],false);
		this.kingsScepter = new GameEntity(this, "!!!SCEPTER!!! OMG YOU SHOULD NEVER SEE THIS!",false)
		this.kingsScepter.setStats(0,0,0,0,0,0,0,false, false, [],false);
		this.king = new GameEntity(this, "Black King", this.kingsScepter);
		//minLuck, maxLuck, hp, mobility, triggerLevel, freeWill, power, abscondable, canAbscond, framotifs
		this.king.setStats(25,75,500,0,0,25,100,false, false, []);  //anything prototype gives you. horrorterrors vastGlub.
		//TODO  jack, denizens, denizen minions
		this.queen = new GameEntity(this, "Black Queen",this.queensRing);
		this.queen.setStats(25,75,500,100,0,100,50,false, false, [],); //red miles

		this.jack = new GameEntity(this, "Jack",null);
		this.jack.setStats(25,75,50,100,50,1000,10,true, true, []); //jack is kind of a big deal

		this.democraticArmy = new GameEntity(this, "Democratic Army",null); //doesn't actually exist till WV does his thing.
		this.democraticArmy.setStats(0,0,0,0,0,0,0,false, false, [],false);
	}

	this.newScene = function(){
		this.currentSceneNum ++;
		var div;
		if(this.sbahj){
			div = "<div id='scene"+this.currentSceneNum+"' style='";
			div += "background-color: #00ff00;"
			div += "font-family: Comic Sans MS, cursive, sans-serif;"
			//$("#scene"+this.currentSceneNum).css("background-color", "#00ff00");
			var reallyRand = getRandomIntNoSeed(1,10);
			for(var i = 0; i<reallyRand; i++){<commit_msg>jack fights are almost ready besides absconding and nothing special/fraymotif works for anybody<commit_after>//okay, fine, yes, global variables are getting untenable.
function Session(session_id){
	this.session_id = session_id; //initial seed
	this.players = [];
	this.hasClubs = false;
	this.sessionHealth = 5000; //grimDark players work to lower it. at 0, it crashes.  maybe have it do other things at other levels, or effect other things.
	this.hasDiamonds = false;
	this.afterLife = new AfterLife();
	this.queensRing = null; //eventually have white and black ones.
	this.kingsScepter = null;
	this.hasHearts = false;
	this.hasSpades = false;
	this.denizenBeat = false;
	//session no longer keeps track of guardians.
	this.king = null;
	this.queen = null;
	this.rapBattle = false;
	this.crashedFromSessionBug = false; //gets corrupted if an unrecoverable error gets caught.
	this.crashedFromPlayerActions = false;
	this.sickFires = false;
	this.dreamBubbleAfterlife = false;
	this.democraticArmy = null;
	this.sbahj = false;
	this.heroicDeath = null;
	this.won = false;
	this.justDeath = null;
	this.hardStrength = 275;
	this.minFrogLevel = 18;
	this.goodFrogLevel = 28;
	this.democracyStrength = 0;
	this.reckoningStarted = false;
	this.aliensClonedOnArrival = []; //if i'm gonna do time shenanigans, i need to know what the aliens were like when they got here.
	this.murdersHappened = false;
	this.goodLuckEvent = false;
	this.badLuckEvent = false;
	this.hasFreeWillEvents = false;
	this.ectoBiologyStarted = false;
	this.doomedTimeline = false;
	this.makeCombinedSession = false; //happens if sick frog and few living players
	this.scratched = false;
	this.scratchAvailable = false;
	this.timeTillReckoning = 0;
	this.godTier = false;
	this.questBed = false;
	this.sacrificialSlab = false;
	this.sessionType = -999
	this.scenesTriggered = []; //this.scenesTriggered
	this.doomedTimelineReasons = [];
	this.currentSceneNum = 0;
	this.scenes = []; //scene controller initializes all this.
	this.reckoningScenes = [];
	this.deathScenes = [];
	this.available_scenes = [];
	this.hadCombinedSession = false;
	this.parentSession = null;
	this.availablePlayers = [];  //which players are available for scenes or whatever.
	this.importantEvents = [];
	this.yellowYardController = new YellowYardResultController();//don't expect doomed time clones to follow them to any new sessions

	//IMPORTANT do not add important events directly, or can't check for alternate timelines.
	//oh god, just typing that gives me chills. time shenanigans are so great.
	this.addImportantEvent = function(important_event){
		var alternate = this.yellowYardController.doesEventNeedToBeUndone(important_event);
	//	console.log("alternate i got from yellowYardController is: " + alternate)
		if(alternate){
		//	console.log("returning alternate")
			return alternate; //scene will use the alternate to go a different way. important event no longer happens.
		}else{
			//console.log(" pushing important event and returning null")
			this.importantEvents.push(important_event);
			return null;
		}
	}

	this.frogStatus = function(){
		var spacePlayer = findAspectPlayer(this.players, "Space");
		if(spacePlayer.landLevel < this.minFrogLevel){
			return "No Frog"
		}else if(spacePlayer.landLevel > this.goodFrogLevel){
			return "Full Frog"
		}else{
			return "Sick Frog"
		}

	}

	//make Math.seed  = to my session id, reinit all my variables (similar to a scratch.)
	//make sure the controller starts ticking again. very similar to scrach
	this.addEventToUndoAndReset = function(e){
		//console.log("undoing an event.")
		if(this.scratched){
			return this.addEventToUndoAndResetScratch(e); //works different
		}
		if(e){//will be null if undoing an undo
			this.yellowYardController.eventsToUndo.push(e);
		}
		//reinit the seed and restart the session
		var savedPlayers = curSessionGlobalVar.players;
		this.reinit();
		createScenesForSession(curSessionGlobalVar);
		//players need to be reinit as well.
		curSessionGlobalVar.makePlayers();
		curSessionGlobalVar.randomizeEntryOrder();
		curSessionGlobalVar.makeGuardians(); //after entry order established
		checkEasterEgg(); //in the controller.
		//now that i've done that, (for seed reasons) fucking ignore it and stick the actual players in
		//after alll, i could be from a combo session.
		//but don't just hardcore replace. need to...fuck. okay, cloning aliens now.
		curSessionGlobalVar.aliensClonedOnArrival = this.aliensClonedOnArrival;
		//console.log("adding this many clone aliens: " + curSessionGlobalVar.aliensClonedOnArrival.length)
		//console.log(getPlayersTitles(curSessionGlobalVar.aliensClonedOnArrival));
		var living = []  //if don't make copy of aliensClonedOnArrival, goes into an infinite loop as it loops on it and adds to it inside of addAliens
		for(var i = 0; i<this.aliensClonedOnArrival.length; i++){
			living.push(this.aliensClonedOnArrival[i])
		}
		this.aliensClonedOnArrival = [];//jettison old clones.
		addAliensToSession(curSessionGlobalVar, living);

		restartSession();//in controller
	}

	this.addEventToUndoAndResetScratch = function(e){
		console.log('yellow yard from scratched session')
		if(e){//will be null if undoing an undo
			this.yellowYardController.eventsToUndo.push(e);
		}
		var ectoSave = this.ectoBiologyStarted;
		reinit();
		//use seeds the same was as original session and also make DAMN sure the players/guardians are fresh.
		curSessionGlobalVar.makePlayers();
		curSessionGlobalVar.randomizeEntryOrder();
		curSessionGlobalVar.makeGuardians(); //after entry order established
		this.ectoBiologyStarted = ectoSave;
		this.scratched = true;
		this.switchPlayersForScratch();



		restartSession();//in controller
	}

	//child sessions are basically any session with an ID that matches the seed you stop on
	//TODO could possibly be constrained to need a space or time player to navigage. or godtier light/doom??? could further require the player be from derse
	//but this already 2-4% of all sessions, do i really want it to  be even rarer?
	this.initializeCombinedSession = function(){
		this.aliensClonedOnArrival = []; //PROBABLY want to do this.
		var living = findLivingPlayers(this.players);
		//nobody is the leader anymore.
		var newSession = new Session(Math.seed);  //this is a real session that could have gone on without these new players.
		newSession.currentSceneNum = this.currentSceneNum;
		newSession.afterLife = this.afterLife; //afterlife carries over.
		newSession.dreamBubbleAfterlife = this.dreamBubbleAfterlife; //this, too
		newSession.reinit();
		newSession.makePlayers();
		newSession.randomizeEntryOrder();
		newSession.makeGuardians();
		if(living.length + newSession.players.length > 12){
			//console.log("New session " + newSession.session_id +" cannot support living players. Already has " + newSession.players.length + " and would need to add: " + living.length)
			return;  //their child session is not able to support them
		}
	//	console.log("about to add: " + living.length + " aliens to new session.")
		//console.log(getPlayersTitles(living));
		addAliensToSession(newSession, living);


		this.hadCombinedSession = true;
		newSession.parentSession = this;
		createScenesForSession(newSession);
		//console.log("Session: " + this.session_id + " has made child universe: " + newSession.session_id + " child has this long till reckoning: " + newSession.timeTillReckoning)
		return newSession;
	}

	this.getVersionOfPlayerFromThisSession = function(player){
		//can double up on classes or aspects if it's a combo session. god. why are their combo sessions?
		for(var i = 0; i< this.players.length; i++){
			var p = this.players[i];
			if(p.class_name == player.class_name && p.aspect == player.aspect){
				return p; //yeah, technically there COULD be two players with the same claspect in a combo session, but i have ceased caring.
			}
		}
		console.log("Error finding session's: " + player.title());
	}


	//if htis is used for scratch, manually save ectobiology cause it's getting reset here
	//DEFINITELY don't erase the afterlife. that's the whole point.
	this.reinit = function(){
		groundHog = false;
		Math.seed = this.session_id; //if session is reset,
		//console.log("reinit with seed: "  + Math.seed)
		this.timeTillReckoning = getRandomInt(10,30);
		this.sessionType = Math.seededRandom();
		curSessionGlobalVar.available_scenes = curSessionGlobalVar.scenes.slice(0);
		curSessionGlobalVar.doomedTimeline = false;
		this.setUpBosses();
		this.democracyStrength = 0;
		this.reckoningStarted = false;
		this.importantEvents = [];
		this.scenesTriggered = []; //this.scenesTriggered
		this.doomedTimelineReasons = [];
		this.ectoBiologyStarted = false;
	}

	this.makePlayers = function(){
		//console.log("Making players with seed: " + Math.seed)
		this.players = [];
		available_classes = classes.slice(0); //re-initPlayers available classes.
		available_aspects = nonrequired_aspects.slice(0);
		var numPlayers = getRandomInt(2,12);
		this.players.push(randomSpacePlayer(this));
		this.players.push(randomTimePlayer(this));

		for(var i = 2; i<numPlayers; i++){
			this.players.push(randomPlayer(this));
		}

		for(var j = 0; j<this.players.length; j++){
			var p = this.players[j];

			p.generateRelationships(this.players);
			this.decideTroll(p);

			if(p.isTroll){
				p.quirk = randomTrollSim(p)
			}else{
				p.quirk = randomHumanSim(p);
			}
		}

		decideInitialQuadrants(this.players);

		for(var k = 0; k<this.players.length; k++){
			//can't escape consequences.
			this.players[k].consequencesForGoodPlayer();
			this.players[k].consequencesForTerriblePlayer();
		}
	}

	this.convertPlayerNumberToWords = function(){
		//alien players don't count
		var ps = findPlayersFromSessionWithId(this.players, this.session_id);
		if(ps.length == 0){
			ps = this.players;
		}
		var length = ps.length;
		if(length == 2){
			return "TWO";
		}else if(length == 3){
			return "THREE";
		}else if(length == 4){
			return "FOUR";
		}else if(length == 5){
			return "FIVE";
		}else if(length == 6){
			return "SIX";
		}else if(length == 7){
			return "SEVEN";
		}else if(length == 8){
			return "EIGHT";
		}else if(length == 9){
			return "NINE";
		}else if(length == 10){
			return "TEN";
		}else if(length == 11){
			return "ELEVEN";
		}else if(length == 12){
			return "TWELVE";
		}
	}

	this.makeGuardians = function(){
		//console.log("Making guardians")
		available_classes = classes.slice(0);
		available_aspects = nonrequired_aspects.slice(0); //required_aspects
		available_aspects = available_aspects.concat(required_aspects.slice(0));
		var guardians = [];
		for(var i = 0; i<this.players.length; i++){
			  var player = this.players[i];
				//console.log("guardian for " + player.titleBasic());
				var guardian = randomPlayer(this);
				guardian.isTroll = player.isTroll;
				if(guardian.isTroll){
					guardian.quirk = randomTrollSim(guardian)
				}else{
					guardian.quirk = randomHumanSim(guardian);
				}
				guardian.quirk.favoriteNumber = player.quirk.favoriteNumber;
				guardian.bloodColor = player.bloodColor;
				guardian.lusus = player.lusus;
				if(guardian.isTroll == true){ //trolls always use lusus.
					guardian.kernel_sprite = player.kernel_sprite;
				}
				guardian.hairColor = player.hairColor;
				guardian.aspect = player.aspect;
				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.reinit();//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 = player;//goes both ways.
				guardians.push(guardian)
		}

		for(var j = 0; j<this.players.length; j++){
			var g = this.players[j].guardian;
			g.generateRelationships(guardians);
		}
		decideInitialQuadrants(guardians);

		for(var k = 0; k<this.players.length; k++){
			//can't escape consequences.
			this.players[k].guardian.consequencesForGoodPlayer();
			this.players[k].guardian.consequencesForTerriblePlayer();
		}
	}

	this.randomizeEntryOrder = function(){
		this.players = shuffle(this.players);
		this.players[0].leader = true;
	}

	/*
	no longer as simple as just switching players and guardians.
	need to only switch players who have an ectobiologicalSource of this session.
	*/
	this.switchPlayersForScratch = function(){
		//var tmp = curSessionGlobalVar.players;
		//curSessionGlobalVar.players = curSessionGlobalVar.guardians;
		//curSessionGlobalVar.guardians = tmp;
		var nativePlayers = findPlayersFromSessionWithId(this.players, this.session_id);
		//console.log(nativePlayers)
		var guardians = getGuardiansForPlayers(nativePlayers);
		this.players = guardians;
	}

	this.decideTroll = function decideTroll(player){
		if(this.getSessionType() == "Human"){
			return;
		}

		if(this.getSessionType() == "Troll" || (this.getSessionType() == "Mixed" &&Math.seededRandom() > 0.5) ){
			player.isTroll = true;
			player.hairColor = "#000000"
			player.triggerLevel ++;//trolls are less stable
			player.decideHemoCaste(player);
			player.decideLusus(player);
			player.kernel_sprite = player.lusus;
		}
	}


	this.getSessionType = function(){
		if(this.sessionType > .6){
			return "Human"
		}else if(this.sessionType > .3){
			return "Troll"
		}
		return "Mixed"
	}


	this.setUpBosses = function(){
		console.log("Test jack and queen can be exiled, queen rejects ring, king is powerful, boss fights, jack gets bullshit weapon, jack rampage, jack promotion.")
		this.queensRing = new GameEntity(this, "!!!RING!!! OMG YOU SHOULD NEVER SEE THIS!",false)
		this.queensRing.setStats(0,0,0,0,0,0,0,false, false, [],false);
		this.kingsScepter = new GameEntity(this, "!!!SCEPTER!!! OMG YOU SHOULD NEVER SEE THIS!",false)
		this.kingsScepter.setStats(0,0,0,0,0,0,0,false, false, [],false);
		this.king = new GameEntity(this, "Black King", this.kingsScepter);
		//minLuck, maxLuck, hp, mobility, triggerLevel, freeWill, power, abscondable, canAbscond, framotifs
		this.king.setStats(25,75,500,0,0,25,100,false, false, []);  //anything prototype gives you. horrorterrors vastGlub.
		//TODO  jack, denizens, denizen minions
		this.queen = new GameEntity(this, "Black Queen",this.queensRing);
		this.queen.setStats(25,75,500,100,0,100,50,false, false, [],); //red miles

		this.jack = new GameEntity(this, "Jack",null);
		this.jack.setStats(25,75,50,100,50,1000,30,true, true, []); //jack is kind of a big deal

		this.democraticArmy = new GameEntity(this, "Democratic Army",null); //doesn't actually exist till WV does his thing.
		this.democraticArmy.setStats(0,0,0,0,0,0,0,false, false, [],false);
	}

	this.newScene = function(){
		this.currentSceneNum ++;
		var div;
		if(this.sbahj){
			div = "<div id='scene"+this.currentSceneNum+"' style='";
			div += "background-color: #00ff00;"
			div += "font-family: Comic Sans MS, cursive, sans-serif;"
			//$("#scene"+this.currentSceneNum).css("background-color", "#00ff00");
			var reallyRand = getRandomIntNoSeed(1,10);
			for(var i = 0; i<reallyRand; i++){
{'fraction_non_alphanumeric': 0.12268192968111202, 'fraction_numerical': 0.010400654129190515, 'mean_word_length': 4.209746123700801, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 16, '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': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3181649', 'n_tokens_mistral': 11367, 'n_tokens_neox': 10002, 'n_words': 2560}