int lastTile = 0;
uint8 i;
bool lightning = false;
bool hueShift = false;
bool sepia = false;
jjPAL myPal;
jjPAL sepiaPal;
jjPAL lightningPal;


void onLevelLoad() {
	myPal.load("plusPalettes.j2l");  //any file is allowed! and will give you awful results!
	myPal.color[0].red = myPal.color[0].green = myPal.color[0].blue = 0; //transparency
	apply(myPal);
}

void zoneExited() {
	if (true) myPal = jjPalette;
	else apply(myPal);
}

void apply(jjPAL pal = jjPalette) {
	jjSetFadeColors(
		pal.color[207].red,
		pal.color[207].green,
		pal.color[207].blue
	);
	pal.apply();
}

void onPlayer(jjPLAYER@ play) {
	//the point here is to check if we're in any of three tiles, as marked by the
	//flags flashingRed, hueShift, and sepia. If one of those flags is true and
	//the player hasn't left that tile, it's time to do that effect!
	if ((jjGameTicks & 3) > 0) return; //only update the palette every fourth tick, so the game doesn't run quite as slowly
	if (lightning) {
		if (lastTile != play.currTile) { lightning = false; zoneExited(); }
		else switch (jjGameTicks & 63) {
			//this one's pretty simple. all the work of creating the palette is in
			//onFunction10, so here we just apply it from time to time.
			case 0: case 16:
				jjPalette = lightningPal;
				apply();
				break;
			case 4: case 20:
				jjPalette = myPal;
				apply();
				break;
		}
	} else if (sepia) {
		if (lastTile != play.currTile) { sepia = false; zoneExited(); }
		else {
			//pretty much the same, but instead of filling, pasting in a
			//pre-prepared sepia palette. note that color indices 0 and 255
			//are bad juju, so we start at 1 and go to 254 for both palettes.
			jjPalette = myPal;
			jjPalette.copyFrom(1, 254, 1, sepiaPal, jjSin((jjGameTicks)*10) * .333 + .5);
			apply();
		}
	} else if (hueShift) {
		if (lastTile != play.currTile) { hueShift = false; zoneExited(); }
		else {
			//the most complicated. each main color index gets hit specifically,
			//changing the hue to its original hue (as saved in myPal, rather
			//than trying to make cumulative changes to jjPalette) plus
			//jjGameTicks. this is pretty much the standard way to use setHSL,
			//just grab the old values for whatever you don't want to change.
			for (i = 0; i < 254; i++) {
				jjPalette.color[i+1].setHSL(
					myPal.color[i+1].getHue() + jjGameTicks,
					myPal.color[i+1].getSat(),
					myPal.color[i+1].getLight()
				);
			}
			apply();
		}
	}
}


void onFunction0() {
	myPal.reset();
	apply(myPal);
}
void onFunction1() {	// Alternatively, all these gradients could have been prepared in
			// a separate jjPAL object on onLoad(). Whichever!
			// This way is slower, takes less memory, and was quicker to write.
	myPal.gradient(190,0,255, 0,0,147, 96, 8); //grass
	myPal.gradient(255,163,159, 103,27,27, 104, 8); //soil
	myPal.gradient(223,239,183, 7,59,63); //sky
	apply(myPal);
}
void onFunction2() {
	myPal.load("Carrot1n.j2t");
	apply(myPal);
}



void onFunction10(jjPLAYER@ play) {
	lightning = true;
	lastTile = play.currTile;
	jjSamplePriority(SOUND::BILSBOSS_THUNDER);
	play.showText("@@@@Lightning", STRING::LARGE);
	lightningPal = myPal;
	lightningPal.fill(255,255,255);//, 112,112);
	for (uint8 i = 16; i < 112; i += 8)
		lightningPal.gradient(myPal.color[i+4].red, myPal.color[i+4].green, myPal.color[i+4].blue, 255,255,255, i, 8);
}
void onFunction11(jjPLAYER@ play) {
	sepia = true;
	lastTile = play.currTile;
	play.showText("@@@@Sepia", STRING::LARGE);
	for (i = 0; i < 254; i++) {
		sepiaPal.color[i+1].setHSL( //these are some pretty arbitrary numbers, tbh
			20 + myPal.color[i+1].getHue() / 16,
			myPal.color[i+1].getSat() / 6,
			myPal.color[i+1].getLight() / 1.3
		);
	}
}
void onFunction12(jjPLAYER@ play) {
	hueShift = true;
	lastTile = play.currTile;
	play.showText("@@@@Hue", STRING::LARGE);
}