Downloads containing folTPG.j2as

Downloads
Name Author Game Mode Rating
JJ2+ Only: The Paint GameFeatured Download Foly Custom / Concept 8.5 Download file
JJ2+ Only: The Paint GameFeatured Download Foly Custom / Concept 8.5 Download file

File preview

/***************************************************/
/*	Made by Foly 								   */
/*	Feel free to use/copy any part of this script  */
/*	Credits: Unearth for his color change script   */
/*  and explaining how it works :)		   		   */
/***************************************************/

/***Constants***/
const int cUpdateTime = 700; //Time between each score update (70 ticks ~ 1 second)
const int cCaptureTime = 70; //Time of one counter tick (7 counter ticks for the top area, 4 for the left bottom area and 5 for the right bottom area)

enum ColorTrigger { //These are the triggers that change the color of a team by putting them on, you can change the value of a trigger here if it's used in your level
	GreenRed = 1,
	PurpleYellow = 2,
	BlueOrange = 3,
	BlackWhite = 4,
	BlueRed = 5,
}

enum Tile { //Tiles in top secret (this can be changed to make this script work for another tileset or different tiles)
	Red = 361,
	Black = 370,
	Blue = 480,
	None = 0
}

enum Level { //Information for the paintlayer, the paint area is a square with left side xLeft, right side xRight, top side yTop and bottom side yBot. Within that area should be all the paintable tiles.
	xLeft = 17,
	xRight = 101,
	yTop = 5,
	yBot = 73,
	PaintLayer = 6 //Layer you change tiles on
}


/***Variables***/
bool gamedone = false; //Used to update the score after a game finishes
int lightcounter = 0; //lightcounter bigger than 0 will start a fading effect

//Top Area = 0, Left Bottom Area = 1, Right Bottom Area = 2
array<int> AreaCounter(3, 0); //Counts how long there have been more players of one team in this area (red counts positive, blue counts negative)
array<int> PInArea(3, 0); //#red players - #blue players, so if there are more red players PInArea is positive else if there are more blue players it's negative and if there are no players its zero
array<bool> PInAreab(3, false); //If any player is in the area this is true, else it is false
jjPAL TeamColorPal; //Used to change the colors of the red and blue team


/***Color check functions***/
int CheckColor(int playerID) { //Returns the tile the player should paint (which ofcourse depends on their team)
	if (jjPlayers[playerID].teamRed)
		return Tile::Red;
	else
		return Tile::Blue;
}

int AreaColor(int AreaID) { //Returns the color (tile) of one of the 3 capture areas
	int TileColor;
	switch (AreaID) {
		case 0: TileColor = jjTileGet(Level::PaintLayer, 60, 30); break;
		case 1: TileColor = jjTileGet(Level::PaintLayer, 30, 55); break;
		case 2: TileColor = jjTileGet(Level::PaintLayer, 75, 65); break;
		default: TileColor = -1;
	}
	return TileColor;
}


/***Tile change functions***/
void ChangeTiles(int x1, int y1, int x2, int y2, int Tile, int layer) {
	//This function changes tiles in a square area with left side x1, right side x2, top side y1, bottom side y2
	//x1, y1, x2, y2 are JCS coördinates
	for (int i = x1 - 1; i < x2; i++) {
		for (int j = y1 - 1; j < y2; j++) {
			if (!(jjTileGet(layer, i, j) == 0))
				jjTileSet(layer, i, j, Tile);
		}
	}
}

void ClearAll() { //Changes all tiles in the arena to black
	ChangeTiles(Level::xLeft, Level::yTop, Level::xRight, Level::yBot, Tile::Black, Level::PaintLayer);
}

void PaintArea(int AreaID, int Tile) {  //Changes all tiles in one of the 3 capture areas
	switch (AreaID) {
		case 0:
			jjTileSet(Level::PaintLayer, 51, 26, Tile);
			jjTileSet(Level::PaintLayer, 52, 25, Tile);
			jjTileSet(Level::PaintLayer, 53, 25, Tile);
			jjTileSet(Level::PaintLayer, 54, 25, Tile);
			jjTileSet(Level::PaintLayer, 55, 25, Tile);
			jjTileSet(Level::PaintLayer, 68, 25, Tile);
			jjTileSet(Level::PaintLayer, 69, 25, Tile);
			jjTileSet(Level::PaintLayer, 68, 26, Tile);
			jjTileSet(Level::PaintLayer, 69, 26, Tile);
			jjTileSet(Level::PaintLayer, 70, 26, Tile);
			break;
		case 1:
			ChangeTiles(26, 53, 32, 53, Tile, Level::PaintLayer);
			ChangeTiles(33, 53, 33, 60, Tile, Level::PaintLayer);
			break;
		case 2:
			ChangeTiles(70, 62, 76, 62, Tile, Level::PaintLayer);
			break;
	}
}

void ChangeCounter(int AreaID, int Counter) {
	//Changes the "counter tiles" at the bottom of one area, the red counter is possitive and goes from 0 to 7, the blue counter 
	//is negative and goes from -1 to -8 (0 and -1 means all lights off int he color of the team and 7 and -8 means all lights on for the red and blue team respectively)
	switch (AreaID) {
		case 0:
			for (int i = 0; i < 8; i++)
				if (Counter >= 0) {
					if (Counter < i + 1)
						jjTileSet(5, 58 + i, 33, 868);
					else
						jjTileSet(5, 58 + i, 33, 869);
				} else {
					if (-(Counter + 1) < i + 1)
						jjTileSet(5, 58 + i, 33, 862);
					else
						jjTileSet(5, 58 + i, 33, 863);
				}
			break;
		case 1:
			for (int i = 0; i < 5; i++)
				if (Counter >= 0) {
					if (Counter < i + 1)
						jjTileSet(5, 27 + i, 60, 868);
					else
						jjTileSet(5, 27 + i, 60, 869);
				} else {
					if (-(Counter + 1) < i + 1)
						jjTileSet(5, 27 + i, 60, 862);
					else
						jjTileSet(5, 27 + i, 60, 863);
				}
			break;
		case 2:
			for (int i = 0; i < 6; i++)
				if (Counter >= 0) {
					if (Counter < i + 1)
						jjTileSet(5, 74 + i, 68, 868);
					else
						jjTileSet(5, 74 + i, 68, 869);
				} else {
					if (-(Counter + 1) < i + 1)
						jjTileSet(5, 74 + i, 68, 862);
					else
						jjTileSet(5, 74 + i, 68, 863);
				}
			break;
	}
}


/***Other functions***/
bool PlayerInArea(int x1, int y1, int x2, int y2, int playerID) {
	//Returns true if the player is in the square area with left side x1, right side x2, top side y1, bottom side y2, else it returns false
	//x1, y1, x2, y2 are JCS coördinates. The sides itself are also part of the area.
	bool tempbool = ((jjPlayers[playerID].xPos > (x1*32 - 32)) && (jjPlayers[playerID].xPos < x2*32) && (jjPlayers[playerID].yPos > (y1*32 - 32)) && (jjPlayers[playerID].yPos < y2*32));
	return tempbool;
}

void UpdateScore() {
	//Counts the black tiles, blue tiles and red tiles and changes the score as a percentage of the total amount of tiles times 100.
	//So if hte blue team got 60% of the tiles painted it sets the bluescore to 60.
	int RedTiles = 0;
	int BlueTiles = 0;
	int TotalTiles = 0;
	for (int xTile = Level::xLeft; xTile < Level::xRight + 1; xTile++)
		for (int yTile = Level::yTop; yTile < Level::yBot + 1; yTile++) {
			if (jjTileGet(Level::PaintLayer, xTile, yTile) == Tile::Red)
				RedTiles++;
			else if (jjTileGet(Level::PaintLayer, xTile, yTile) == Tile::Blue)
				BlueTiles++;
			else if (jjTileGet(Level::PaintLayer, xTile, yTile) == Tile::Black)
				TotalTiles++;
		}
	TotalTiles = TotalTiles + RedTiles + BlueTiles + 1;
	if (100*RedTiles/TotalTiles > 0)
		jjChat("/redscore " + 100*RedTiles/TotalTiles);
	if (100*BlueTiles/TotalTiles > 0)
		jjChat("/bluescore " + 100*BlueTiles/TotalTiles);
}

void WarpToArea(int AreaID) { //Warps the player to an area (fast warp)
	switch (AreaID) {
		case 0:
			p.warpToTile(61, 29, true);
			break;
		case 1:
			p.warpToTile(29, 56, true);
			break;
		case 2:
			p.warpToTile(76, 64, true);
			break;
		case 3: //Warp to red starting area
			p.warpToTile(29, 80, true);
			break;
		case 4: //Warp to blue starting area
			p.warpToTile(126, 80, true);
			break;
		default: jjAlert("|Error: Area not found.");
	}
}


/***onFunctions***/
void onFunction0(uint8 lightvar) { //Changes the direction of a players movement and starts music/lighting counter when a player is going to enter the arena
	int direction = jjRandom()%2;
	p.xSpeed = -7*direction; //Direction 1 is left, direction 0 is up
	p.ySpeed = -7*(1 - direction);
	if (lightvar == direction) {
		lightcounter = 80;
		jjMusicResume();
	}
}

void onFunction1(uint8 lightvar) { //Changes the direction of a players movement
	int direction = jjRandom()%2; //Direction 1 is right, direction 0 is up
	p.xSpeed = 7*direction;
	p.ySpeed = -7*(1 - direction);
}

void onFunction2() { //Starts music/lighting when a player is going to enter the arena
	lightcounter = 80;
	jjMusicResume();
}


/***Gameplay functions***/
void onMain() {
	//Everything that has to haphen at the start but not at levelload
	if (jjGameTicks == 1) {
		if (jjIsServer)
			jjChat("/maxscore 100");
		ClearAll();
		jjMusicPause();
	}
	
	//If lightcounter is bigger than 0 this will create a fade effect (used when the player enters the arena)
	if (lightcounter > 0) {
		p.lighting = (80 - lightcounter);
		lightcounter--;
	}

	//These triggers are used to changes the team colors
	if (jjTriggers[ColorTrigger::GreenRed]) { //Green vs Red
		TeamColorPal = jjBackupPalette;
		//Changes blue team colors to green
		TeamColorPal.gradient(0, 255, 0, 0, 0, 0, 32, 8, 1.0); //32 - 40 = blue team
		TeamColorPal.fill(30, 150, 8, 96, 1, 1.0); //96 = blue tile
		TeamColorPal.apply();
		jjTriggers[ColorTrigger::GreenRed] = false;
	} else if (jjTriggers[ColorTrigger::PurpleYellow]) { //Purple vs Yellow
		TeamColorPal = jjBackupPalette;
		//Changes blue team colors to purple
		TeamColorPal.copyFrom(32, 8, 88, jjBackupPalette, 1.0);
		TeamColorPal.fill(163, 0, 211, 96, 1, 1.0);
		//Changes red team colors to yellow
		TeamColorPal.gradient(255, 255, 0, 30, 0, 10, 24, 8, 1.0);
		TeamColorPal.apply();
		jjTriggers[ColorTrigger::PurpleYellow] = false;
	} else if (jjTriggers[ColorTrigger::BlueOrange]) { //Blue vs orange
		TeamColorPal = jjBackupPalette;
		//Changes red team colors to orange
		TeamColorPal.gradient(255, 130, 10, 0, 0, 10, 24, 8, 1.0);
		TeamColorPal.apply();
		jjTriggers[ColorTrigger::BlueOrange] = false;
	} else if (jjTriggers[ColorTrigger::BlackWhite]) { //Black vs white
		TeamColorPal = jjBackupPalette;
		//Changes blue team colors to black
		TeamColorPal.gradient(80, 80, 80, 0, 0, 0, 32, 8, 1.0);
		TeamColorPal.fill(0, 0, 0, 96, 1, 1.0);
		//Changes red team colors to white
		TeamColorPal.gradient(255, 255, 255, 0, 0, 0, 24, 8, 1.0);
		TeamColorPal.apply();
		jjTriggers[ColorTrigger::BlackWhite] = false;
	} else if (jjTriggers[ColorTrigger::BlueRed]) { //Blue vs red
		jjBackupPalette.apply();
		jjTriggers[ColorTrigger::BlueRed] = false;
	}
	
	//Changes lighting for spectating players
	if (!PlayerInArea(1, 1, jjLayerWidth[4], jjLayerHeight[4], p.playerID) && p.lighting != 80)
		p.lighting = 80;
	if ((PlayerInArea(117, 76, 134, 85, p.playerID) || PlayerInArea(20, 76, 37, 85, p.playerID)) && p.lighting != 0)
		p.lighting = 0;
		
	//Fixes a spawn bug at the start of the game when teams are shuffled but players arent warped to the right spawn area (i.e. a blue players spawns at the red start area)
	if (PlayerInArea(117, 76, 134, 85, p.playerID) && !p.teamRed)
		WarpToArea(3);
	else if (PlayerInArea(20, 76, 37, 85, p.playerID) && p.teamRed)
		WarpToArea(4);
	
	//Everything that haphens when the game is started
	if (jjGameState == GAME::STARTED || jjGameState == GAME::OVERTIME) {
	
		//Update the score every cUpdateTime/70 seconds
		if (jjGameTicks%cUpdateTime == 0 && jjIsServer)
			UpdateScore();

		//Let the player spawn at captured areas
		if (PlayerInArea(117, 76, 134, 85, p.playerID) && (AreaColor(0) == Tile::Red || AreaColor(1) == Tile::Red || AreaColor(2) == Tile::Red)) {
			int AreaSpawnID;
			do {
				AreaSpawnID = jjRandom()%3;
			} while (AreaColor(AreaSpawnID) != Tile::Red);
			p.lighting = 80;
			WarpToArea(AreaSpawnID);
		} else if (PlayerInArea(20, 76, 37, 85, p.playerID) && (AreaColor(0) == Tile::Blue || AreaColor(1) == Tile::Blue || AreaColor(2) == Tile::Blue)) {
			int AreaSpawnID;
			do {
				AreaSpawnID = jjRandom()%3;
			} while (AreaColor(AreaSpawnID) != Tile::Blue);
			p.lighting = 80;
			WarpToArea(AreaSpawnID);
		}
				
		//This is done when the game is started
		if (!gamedone) {
			if (jjIsServer)
				gamedone = true;
			//Remove the tiles at layer 4 at the starting area so players will get sucked into the arena
			ChangeTiles(22, 84, 28, 84, Tile::None, 4);
			ChangeTiles(119, 84, 120, 84, Tile::None, 4);
			ChangeTiles(133, 84, 133, 84, Tile::None, 4);
		}

		//Reset variables
		for (int i = 0; i < 3; i++) {
			PInArea[i] = 0;
			PInAreab[i] = false;
		}

		for (int i = 0; i < 32; i++) {
			if (jjPlayers[i].isActive) {
				//Player painting
				if (!(PlayerInArea(52, 26, 71, 33, i) || PlayerInArea(26, 53, 33, 60, i) || PlayerInArea(70, 62, 84, 68, i))) {
					if (jjTileGet(Level::PaintLayer, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32) != Tile::None)
						jjTileSet(Level::PaintLayer, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32, CheckColor(i));
					if ((jjTileGet(4, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32 + 1) == 120 || jjTileGet(4, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32 + 1) == 121) && jjTileGet(Level::PaintLayer, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32 + 1) != Tile::None)
						jjTileSet(Level::PaintLayer, jjPlayers[i].xPos/32, jjPlayers[i].yPos/32 + 1, CheckColor(i));
				} else {
				//Area painting (change variables for the area handling part)
					if (PlayerInArea(52, 26, 71, 33, i)) { //Top area
						if (jjPlayers[i].teamRed)
							PInArea[0]++;
						else
							PInArea[0]--;
						PInAreab[0] = true;
					}
					if (PlayerInArea(26, 53, 33, 60, i)) { //Left bottom area
						if (jjPlayers[i].teamRed)
							PInArea[1]++;
						else
							PInArea[1]--;
						PInAreab[1] = true;
					}
					if (PlayerInArea(70, 62, 84, 68, i)) { //Right bottom area
						if (jjPlayers[i].teamRed)
							PInArea[2]++;
						else
							PInArea[2]--;
						PInAreab[2] = true;
					}
				}
			}
		}

		//Area handling
		for (int i = 0; i < 3; i++) {
			//Resets counter to 0 if one team is capturing the area but more players of the other team have joined the area
			if ((AreaCounter[i] > 0 && PInArea[i] < 0) || (AreaCounter[i] < 0 && PInArea[i] > 0))
				AreaCounter[i] = 0;

			//If more players of one team are in an area increase/decrease the area counter
			if (PInArea[i] > 0)
				AreaCounter[i]++;
			else if (PInArea[i] < 0)
				AreaCounter[i]--;

			//Area Capture Time Multiplier tells how long the area takes to capture (it is equal to the amount of lights that need to be lit)
			int ACTMult;
			switch (i) {
				case 0:
					ACTMult = 7;
					break;
				case 1:
					ACTMult = 4;
					break;
				case 2:
					ACTMult = 5;
					break;
			}
				
			//If no player is in the area, reset the counter to maximum if the area is captured. If the area isn't captured reset the area counter.
			if (!PInAreab[i])
				if (AreaColor(i) == Tile::Red) {
					ChangeCounter(i, ACTMult);
					AreaCounter[i] = ACTMult*cCaptureTime + 1;
				} else if (AreaColor(i) == Tile::Blue) {
					ChangeCounter(i, -ACTMult - 1);
					AreaCounter[i] = -ACTMult*cCaptureTime - 1;
				} else if (AreaColor(i) == Tile::Black && AreaCounter[i] != 0) {
					if (AreaCounter[i] > 0)
						ChangeCounter(i, 0);
					else
						ChangeCounter(i, -1);
					AreaCounter[i] = 0;
				}
			
			//Changes the counter at the bottom of an area to the teams color when the team starts capturing the area
			if (AreaCounter[i] == -1)
				ChangeCounter(i, -1);
			else if (AreaCounter[i] == 1)
				ChangeCounter(i, 0);

			if (AreaCounter[i]%cCaptureTime == 0) {
				//Changes the counter at the bottom of the area according to how long players have been standing there
				if (AreaCounter[i] > 0 && AreaCounter[i] <= ACTMult*cCaptureTime)
					ChangeCounter(i, AreaCounter[i]/cCaptureTime);
				else if (AreaCounter[i] < 0 && AreaCounter[i] >= -ACTMult*cCaptureTime)
					ChangeCounter(i, AreaCounter[i]/cCaptureTime - 1);
				
				//When the area counter has reached capturetime put on triggers to recolor the area (one trigger is used to let the client know they should paint (20 - 22) and one is used to determine the color (24 - 26))
				if (jjIsServer)
					if (AreaCounter[i] == ACTMult*cCaptureTime) {
						jjChat("/trigger " + (20 + i) + " on");
						jjChat("/trigger " + (24 + i) + " on");
					} else if (AreaCounter[i] == -ACTMult*cCaptureTime) {
						jjChat("/trigger " + (20 + i) + " off");
						jjChat("/trigger " + (24 + i) + " on");
					}

				//Change the area color according to the triggers that are set
				if (jjTriggers[24+i]) {
					jjTriggers[24+i] = false;
					if (jjTriggers[20+i])
						PaintArea(i, Tile::Red);
					else
						PaintArea(i, Tile::Blue);
				}
			}
		}
	} else if (gamedone && jjIsServer) {
		gamedone = false;
		UpdateScore();
	}
}