Downloads containing xlmmonopoly.j2as

Downloads
Name Author Game Mode Rating
JJ2+ Only: JazzopolyFeatured Download Superjazz Custom / Concept 9 Download file

File preview

//http://www.hasbro.de/manuals/15283i09text.pdf
//http://en.wikibooks.org/wiki/Monopoly/Official_Rules

//*** Jazzopoly ***//
//*** Written by Vivando/CJ ***//
//*** An scripted level dedicated to XLM ***//
//*** This level is not an attempt to make a real Monopoly game, but it uses the same concept. Therefore it's called Jazzopoly ***//
//*** Instead it uses fictional Jazz-themed places and events to personalize the game in a custom way ***//
//*** Thus not all the rules are exactly the same as in monopoly, and the board is only 20 tiles("squares") big ***//
//*** Special thanks to Sir Ementaler for the textured BG fix and for general guiding ***//
//*** Special thanks to PurpleJazz and TreyLina for testing ***//
//*** This level pays tribute to Monopoly by URJazz ***//
//*** Yeah, some of the property-names were unadventurously recycled from monopoly2.j2l ***//

//*OBJECT DECLARATION*//
Dice dice;

array<Square> squares = {
Square(0, -2, 0, 0, 0, "||||START", 0), //-1 = no owner, -2 = non-buyable
Square(1, -1, 20, 16, 8, "Diamondus Drive", 1),
Square(2, -1, 25, 20, 10, "Lagunicus Lowland", 1),
Square(3, -2, 0, 0, 0, "||||CHANCE", 0),
Square(4, -1, 30, 24, 12, "Letni Loop", 1),
Square(5, -2, 0, 0, 0, "||||JAIL", 0),
Square(6, -1, 40, 32, 16, "Raneforus Road", 1),
Square(7, -1, 45, 36, 18, "Exoticus Avenue", 1),
Square(8, -2, 0, 0, 0, "||||COMMUNITY CHEST", 0),
Square(9, -1, 50, 40, 20, "Muckamok Marsh", 1),
Square(10, -2, 0, 0, 0, "||||FREE PARKING", 0),
Square(11, -1, 60, 48, 24, "Ceramicus Corner", 1),
Square(12, -1, 65, 52, 26, "Stonar Subway", 1),
Square(13, -2, 0, 0, 0, "||||CHANCE", 0),
Square(14, -1, 70, 56, 28, "Scraparap Street", 1),
Square(15, -2, 0, 0, 0, "||||GO TO JAIL!", 0),
Square(16, -1, 80, 64, 32, "Industrius Section", 1),
Square(17, -1, 85, 68, 34, "Deserto Downtown", 1),
Square(18, -2, 0, 0, 0, "||||COMMUNITY CHEST", 0),
Square(19, -1, 100, 80, 40, "Holidaius Hills", 1)
};

array<PlayerLoc> players(4);

//*END OF OBJECT DECLARATION*//

//*OTHER DECLARATIONS*//

enum packet_type {packet_turnStart, packet_turnFinish, packet_turnSkip, packet_move, packet_signupReq, packet_signupResp,
packet_signupAnn, packet_dice, packet_rent, packet_buy, packet_sell, packet_idRequest, packet_jail, packet_jailbreak,
packet_jailAvoid, packet_chance, packet_cc, packet_elim, packet_noThrow, packet_wildCard, packet_wildCardUse,
packet_coin, packet_firstPlayer, packet_gameStart, packet_option1, packet_option2, packet_registered, packet_cc2,
packet_rentChange, packet_freeProperty, packet_spaceTroll, packet_endGame, packet_players, packet_gameEnding, packet_gameCancel}; //for network communication

enum page {page_blank, page_preAction, page_postAction, page_buyable, page_wildCard, page_jailMoney, page_spaceTroll};

bool inGame = false; //to check whether the player is signed up for the game
bool isInBox = false; //the box in the center
bool doTurn = false;
bool isTurn = false; //determines whether the current player has it's turn
bool hasThrown = false; //whether the player has thrown the dice
bool diceRolls = false;
bool printDice = false;
bool playerMoves = false; //moves the player tile by tile
bool playerMovesBack = false; //moves the player tile by tile backwards (chance)
bool playerMovesQuick = false; //gotta go fast!
bool playerMovesBackQuick = false;
bool finishedMoving = false; //to true once playerMoves ends
bool confirmed = true; //to true once player throws the dice or performs a square action, initial value true so that player can't sign up before security check, see level pos. 4-6,2
bool diceConfirmed = false;
bool buyable = false;
bool bought = false;
bool requestJailMoney = false;
bool giveCoins = false; //increment coins
bool takeCoins = false; //deduct coins
bool drawBackground = true; //draw transparent background when the level is loaded
bool drawMark = false; //question mark for chance
bool printSquare = false;
bool printChance = false;
bool printCC = false;
bool printReward = false;
bool printOK = false;
bool gameRuns = false; //shortcut for game states
bool gameStarted = false; //player can no longer sign up once true
bool gameEnded = false;
bool waitForFinish = false; //to true once player has performed his turn, waiting 3 seconds before sending turn finish packet
//bool hasSelected = false; //remove this part for final version
bool selectYes = true; //a player has selection on "Yes" by default when choosing whether to buy property or not
bool selectView = false;
bool preAction = false; //page shown once the player turn begins
bool midAction = false; //page shown before postAction if necessary
bool postAction = false; //page shown after the player performed moving and square action
bool postTurn = false;
bool promptWildCard = false;
bool isThrowing = false;
bool viewMap = false;
bool selling = false;
bool upgrading = false;
bool confirmation = false;
bool keyFireReleased = true;
bool waitForChance = false;
bool waitForCC = false;
bool waitForMove = false; //for little delay between printing chance texts and the moved square texts
bool waitForMoveForward = false;
bool waitForMoveBack = false;
bool waitForMoveQuick = false;
bool waitForSelect = false;
bool waitForWildCard = false;
bool switched = false;
//bool inChance = true;
bool isJailed = false; //for checking whether the player is jailed or not in general
bool isNotInJail = false; //for checking whether or not the player is already in jail at the event of wild card use
bool firstPlayer = false;
bool initiateTurn = true;
bool zeroReleased = true;
bool spaceTroll = false;
bool firstTime = true; //first game start for the server

string turnTimer;
string squareFunction = ""; //the first string describing the square ownership
string squareAction = ""; //the second string describing the action the player may or must take
string squarePrice = ""; //only displayed if the player doesn't have enough money to buy a property
string c1 = "";
string c2 = "";
string c3 = "";

uint8 requestedPage = 0;
uint8 animFrame = 0;
uint selectionPos = 0;
uint confirmationPos = 0;

int8 yourPlayerNo = -1;
int8 turnTimeLimitInt = 6;
int8 playersLeft = 0;
int8 playerTurn = 4;
int8 currentTurn = 4;
int8 turnCounter = 1;

int lastThrownNumber = 1;
int toMove = 0; //copied from lastThrownNumber in default case (throw dice), but used also from chance-events so that it doesn't affect lastThrownNumber
int toSquare = 0;
int diceElapsed = 0; //for how long the dice "rolls"
int moveElapsed = 1; //for how long the player moves
int turnElapsed = 0; //for how long the turn lasts
int roundElapsed = 0;
int coinElapsed = 1;
int coinFinal = 0;
int rewardElapsed = 0;
int buyElapsed = 0;
int jailElapsed = 0;
int playerSquare = 0;
int currSquare = 0; //used for moving the player in the first place
int squareID = -1;
int registered = 0; //to be incremented when a player is signed up for the game
int currentChance = 0;
int currentCC = 0;
int wait = 0; //waiter-variable before finishing a player's turn
//int enteredInt = 1; //remove this part for final version
int diceWait = 0;
int returnWait = 0;
int viewWait = 0;
int chanceWait = 0;
int ccWait = 0;
int moveWait = 0;
int selectWait = 0;
int wildCardWait = 0;
int marky = 0; //question mark's y position
int markIni = 336; //initial mark location on y axis
int markFinal = 236; //final location
int turnDelay = 420;
int round = 0;
int roundLimit = 0;
int roundLimitInt = 6;
int M = 60; //amount of minutes
int S = 0;  //amount of seconds
int timer = (M * 60 + S) * 70; //timer structure
int maxTime = (M * 60 + S) * 70; //used for timing the turns
int statsMode = 1;

const array<int> squarex = {33, 28, 23, 18, 13, 8, 8, 8, 8, 8, 8, 13, 18, 23, 28, 33, 33, 33, 33, 33};
const array<int> squarey = {34, 34, 34, 34, 34, 34, 29, 24, 19, 14, 9, 9, 9, 9, 9, 9, 14, 19, 24, 29};
const array<int> minutesArray = {0, 0, 1, 1, 2, 5, 60}; //the last stands for unlimited
const array<int> secondsArray = {30, 45, 0, 30, 0, 0, 0};
const array<int> roundsArray = {1, 25, 40, 60, 80, 100, 0};

array<uint> usedChances;
array<uint> usedCCs;
array<PlayerValue> playerValues;
array<int> moneyValues;

array<string> squareNames = {
	"||||START",
	"Diamondus Drive",
	"Lagunicus Lowland",
	"||||CHANCE",
	"Letni Loop",
	"||||JAIL",
	"Raneforus Road",
	"Exoticus Avenue",
	"||||COMMUNITY CHEST",
	"Muckamok Marsh",
	"||||FREE PARKING",
	"Ceramicus Corner",
	"Stonar Subway",
	"||||CHANCE",
	"Scraparap Street",
	"||||GO TO JAIL!",
	"Industrius Section",
	"Deserto Downtown",
	"||||COMMUNITY CHEST",
	"Holidaius Hills"
};

//*END OF OTHER DECLARATIONS*//

//*CLASSES*//

class Dice {
	uint sides;
	
	Dice() {
		sides = 6;
	}
	
	Dice(uint Sides) {
		sides = Sides;
	}
	
	int throwDice() {
		int diceResult = jjRandom() % sides + 1;
		return diceResult;
	}
}

class PlayerLoc {
	int8 pID; //playerID
	int8 finalPosition;
	int currSquare; 
	int coins;
	int jailedTurns; //if 0, equals to not in jail
	int propertiesOwned;
	string playerName;
	bool hasWildCard;
	bool isOut; //eliminated
	bool isOccupied;
	array<int> ownedSquares;
	
	PlayerLoc() {
		pID = -1;
		currSquare = 0;
		coins = 0;
		jailedTurns = 0;
		propertiesOwned = 0;
		playerName = "";
		hasWildCard = false;
		isOut = false;
		isOccupied = false;
		array<int> ownedSquares;
		finalPosition = 0;
	}
	
	PlayerLoc(int8 PID, int8 FinalPosition, int CurrSquare, int Coins, int JailedTurns, int PropertiesOwned, string PlayerName, bool HasWildCard, bool IsOut, bool IsOccupied, array<int> OwnedSquares) {
		pID = PID;
		finalPosition = FinalPosition;
		currSquare = CurrSquare;
		coins = Coins;
		jailedTurns = JailedTurns;
		propertiesOwned = PropertiesOwned;
		playerName = PlayerName;
		hasWildCard = HasWildCard;
		isOut = IsOut;
		isOccupied = IsOccupied;
		ownedSquares = OwnedSquares;
	}
}

class Square {
	int squareID;
	int8 owner; //the playerID of the owner
	int price; //price in coins
	int sellPrice;
	double upPrice;
	int rent; //rent price, when a player whose playerID doesn't match the owner enters the square, the player must pay the rent price
	int8 rentLevel;
	string name;
	
	Square() {
		squareID = 0;
		owner = -1;
		price = 0;
		sellPrice = 0;
		upPrice = 0;
		rent = 0;
		rentLevel = 0;
		name = "";
	}
	
	Square(int SquareID, int8 Owner, int Price, int SellPrice, int Rent, string Name) {
		squareID = SquareID;
		owner = Owner;
		price = Price;
		sellPrice = SellPrice;
		rent = Rent;
		name = Name;
		upPrice = Price * 0.6;
	}
	
	Square(int SquareID, int8 Owner, int Price, int SellPrice, int Rent, string Name, int RentLevel) {
		squareID = SquareID;
		owner = Owner;
		price = Price;
		sellPrice = SellPrice;
		rent = Rent;
		name = Name;
		rentLevel = RentLevel;
		upPrice = Price * 0.6;
	}
}

class PlayerValue {
	int8 pID;
	int value;
	
	PlayerValue() {
		pID = -1;
		value = 0;
	}
	
	PlayerValue(int PID, int Value) {
		pID = PID;
		value = Value;
	}
}

//*END OF CLASSES*//

//*CLIENT COMMUNICATION*//

void sendTurnStartPacket(int8 playerID) { //sent by the server
	jjSTREAM packet;
	packet.push(uint8(packet_turnStart));
	int toClientID = jjPlayers[playerID].clientID;
	jjSendPacket(packet, toClientID);
}

void sendTurnFinishPacket(int8 playerID) { //sent by the client when the player finishes the turn before timer runs out
	jjSTREAM packet;
	packet.push(uint8(packet_turnFinish));
	packet.push(playerID);
	jjSendPacket(packet);
}

void sendTurnSkipPacket(int8 playerID) { //sent by the server
	jjSTREAM packet;
	packet.push(uint8(packet_turnSkip));
	packet.push(playerID);
	int toClientID = jjPlayers[playerID].clientID;
	jjSendPacket(packet, toClientID);
}

void sendMovePacket(int8 playerID, int currSquare) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_move));
	packet.push(playerID);
	packet.push(currSquare);
	packet.push(yourPlayerNo); //which player's square shall be updated in the players-array
	jjSendPacket(packet);
}

void sendRentPacket(int8 playerID, int8 ownerID, int rent) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_rent));
	packet.push(playerID);
	packet.push(ownerID); //to whom shall the server redirect the rent
	packet.push(rent);
	jjSendPacket(packet);
}

void sendBuyPacket(int8 playerID, int squareID, int price) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_buy));
	packet.push(playerID);
	packet.push(squareID);
	packet.push(price);
	packet.push(yourPlayerNo);
	jjSendPacket(packet);
}

void sendSellPacket(int8 playerID, int squareID, int sellPrice, uint index) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_sell));
	packet.push(playerID);
	packet.push(squareID);
	packet.push(sellPrice);
	packet.push(yourPlayerNo);
	packet.push(index);
	jjSendPacket(packet);
}

void sendJailPacket(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_jail));
	packet.push(playerID);
	packet.push(yourPlayerNo); //which player's square shall be updated in the players-array
	jjSendPacket(packet);
}

void sendJailAvoidPacket(int8 playerID, int8 param) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_jailAvoid));
	packet.push(playerID);
	packet.push(param);
	jjSendPacket(packet);
}

void sendChancePacket(int8 playerID, uint chanceCase, int8 param) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_chance));
	packet.push(playerID);
	packet.push(chanceCase);
	packet.push(param);
	jjSendPacket(packet);
}

void sendCCPacket(int8 playerID, uint ccCase, int8 param) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_cc));
	packet.push(playerID);
	packet.push(ccCase);
	packet.push(param);
	jjSendPacket(packet);
}

void sendSignupReq(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_signupReq));
	packet.push(playerID);
	jjSendPacket(packet);
}

void sendElimPacket(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_elim));
	packet.push(playerID);
	packet.push(yourPlayerNo);
	jjSendPacket(packet);
}

void sendWildCardPacket(int8 playerID) { //sent by server
	jjSTREAM packet;
	packet.push(uint8(packet_wildCard));
	int toClientID = jjPlayers[playerID].clientID;
	jjSendPacket(packet, toClientID);
}

void sendWildCardUsePacket(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_wildCardUse));
	packet.push(playerID);
	packet.push(yourPlayerNo); //which player's square shall be updated in the players-array
	jjSendPacket(packet);
}

void sendCoinPacket(int8 playerID, int coins) { //sent by everyone
	jjSTREAM packet;
	packet.push(uint8(packet_coin));
	packet.push(playerID);
	packet.push(yourPlayerNo);
	packet.push(coins);
	jjSendPacket(packet);
}

void sendOption1Packet(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_option1));
	packet.push(playerID);
	jjSendPacket(packet);
}

void sendOption2Packet(int8 playerID) { //sent by client
	jjSTREAM packet;
	packet.push(uint8(packet_option2));
	packet.push(playerID);
	jjSendPacket(packet);
}

void onReceive(jjSTREAM &in packet, int clientID) {
	uint8 type;
	packet.pop(type);
	if (jjIsServer) {
		switch (type) {
			case packet_turnFinish:
			{
				int8 playerID;
				packet.pop(playerID);
				if (jjPlayers[playerID].clientID == clientID) {
					if (maxTime <= 5 * 60 * 70) {
						int roundLength = maxTime * registered + turnDelay * registered;
						
						if (roundLength == maxTime * 1 + turnDelay * 1) {
							roundElapsed = maxTime + 1;
						}
						
						else if (roundLength == maxTime * 2 + turnDelay * 2) {
							if (currentTurn == 0) roundElapsed = maxTime + 1;
							else roundElapsed = maxTime * 2 + turnDelay + 1;
						}
						
						else if (roundLength == maxTime * 3 + turnDelay * 3) {
							if (currentTurn == 0) roundElapsed = maxTime + 1;
							else if (currentTurn == 1) roundElapsed = maxTime * 2 + turnDelay + 1;
							else roundElapsed = maxTime * 3 + turnDelay * 2 + 1;
						}
						
						else if (roundLength == maxTime * 4 + turnDelay * 4) {
							if (currentTurn == 0) roundElapsed = maxTime + 1;
							else if (currentTurn == 1) roundElapsed = maxTime * 2 + turnDelay + 1;
							else if (currentTurn == 2) roundElapsed = maxTime * 3 + turnDelay * 2 + 1;
							else roundElapsed = maxTime * 4 + turnDelay * 2 + 1;
						}
					}
					
					else { //unlimited time-mode
						if (registered == 1) {
							playerTurn = 0;
							doTurn = true;
						}
						
						else if (registered == 2) {
							if (currentTurn == 0) {
								playerTurn = 1;
								doTurn = true;
							}
							
							else {
								playerTurn = 0;
								doTurn = true;
							}
						}
						
						else if (registered == 3) {
							if (currentTurn == 0) {
								playerTurn = 1;
								doTurn = true;
							}
							
							else if (currentTurn == 1) {
								playerTurn = 2;
								doTurn = true;
							}
							
							else {
								playerTurn = 0;
								doTurn = true;
							}
						}
						
						else if (registered == 4) {
							if (currentTurn == 0) {
								playerTurn = 1;
								doTurn = true;
							}
							
							else if (currentTurn == 1) {
								playerTurn = 2;
								doTurn = true;
							}
							
							else if (currentTurn == 2) {
								playerTurn = 3;
								doTurn = true;
							}
							
							else {
								playerTurn = 0;
								doTurn = true;
							}
						}
					}
				}
			}
			break;
			
			case packet_signupReq:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					handleSignups(playerID);
				}
			}
			break;
			
			case packet_move:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int receivedSquare;
					packet.pop(receivedSquare);
					int8 whichPlayer;
					packet.pop(whichPlayer);
					
					players[whichPlayer].currSquare = receivedSquare;
					
					jjSTREAM globalUpdate;
					globalUpdate.push(uint8(packet_move));
					globalUpdate.push(playerID);
					globalUpdate.push(receivedSquare);
					globalUpdate.push(whichPlayer);
					jjSendPacket(globalUpdate, -clientID); //negative toClientID, so to all except the player who sent the first packet
				}
			}
			break;
			
			case packet_dice:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int receivedDie; //Die;
					packet.pop(receivedDie);
					
					string playerName = jjPlayers[playerID].name;
					jjAlert("" + playerName + " threw number " + receivedDie, true);
				}
			}
			break;
			
			case packet_rent:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 ownerID;
					packet.pop(ownerID);
					
					int rent;
					packet.pop(rent);
					
					if (jjPlayers[ownerID].isLocal) {
						string senderName = jjPlayers[playerID].name;
						jjAlert("You receive " + rent + " coins from " + senderName, false, STRING::MEDIUM);
						
						coinElapsed = 1;
						coinFinal = rent * 2 + 1;
						giveCoins = true;
					}
					
					else { //if the owner is not the server
						jjSTREAM coinRedirect;
						coinRedirect.push(uint8(packet_rent));
						coinRedirect.push(playerID);
						coinRedirect.push(ownerID);
						coinRedirect.push(rent);
						
						int toClientID = jjPlayers[ownerID].clientID;
						jjSendPacket(coinRedirect, toClientID);
					}
				}
			}
			break;
			
			case packet_buy:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int squareID;
					packet.pop(squareID);
					int price;
					packet.pop(price);
					int8 whichPlayer;
					packet.pop(whichPlayer);
					
					players[whichPlayer].propertiesOwned++;
					players[whichPlayer].ownedSquares.insertLast(squareID);
					squares[squareID].owner = playerID;
					string playerName = jjPlayers[playerID].name;
					string squareName = squares[squareID].name;
					jjAlert("" + playerName + " has bought " + squareName + " for " + price + " coins.");
					
					jjSTREAM buyRedirect;
					buyRedirect.push(uint8(packet_buy));
					buyRedirect.push(playerID);
					buyRedirect.push(squareID);
					buyRedirect.push(price);
					buyRedirect.push(whichPlayer);
					jjSendPacket(buyRedirect, -clientID);
				}
			}
			break;
			
			case packet_sell:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int squareID;
					packet.pop(squareID);
					int sellPrice;
					packet.pop(sellPrice);
					int8 whichPlayer;
					packet.pop(whichPlayer);
					uint index;
					packet.pop(index);
					
					players[whichPlayer].propertiesOwned--;
					players[whichPlayer].ownedSquares.removeAt(index);
					squares[squareID].owner = -1;
					string playerName = jjPlayers[playerID].name;
					string squareName = squares[squareID].name;
					jjAlert("" + playerName + " has sold " + squareName + " for " + sellPrice + " coins.", true);
					
					jjSTREAM sellRedirect;
					sellRedirect.push(uint8(packet_sell));
					sellRedirect.push(playerID);
					sellRedirect.push(squareID);
					sellRedirect.push(sellPrice);
					sellRedirect.push(whichPlayer);
					sellRedirect.push(index);
					
					jjSendPacket(sellRedirect, -clientID);
				}
			}
			break;
			
			case packet_idRequest:
			{
				jjSTREAM response;
				response.push(uint8(packet_idRequest));
				
				for (uint i = 0; i < players.length(); i++) {
					PlayerLoc thisPlayer = players[i]; //get the player's id
					int8 thisID = thisPlayer.pID;
					response.push(thisID);
					int thisCS = thisPlayer.currSquare;
					response.push(thisCS);
					int thisCoins = thisPlayer.coins;
					response.push(thisCoins);
					bool thisIsOut = thisPlayer.isOut;
					response.push(thisIsOut);
					bool thisIsOccupied = thisPlayer.isOccupied;
					response.push(thisIsOccupied);
				}
				
				for (uint i = 0; i < squares.length(); i++) {
					Square thisSquare = squares[i];
					response.push(thisSquare.owner);
					response.push(thisSquare.rentLevel);
				}
				
				response.push(turnTimeLimitInt);
				
				jjSendPacket(response, clientID);
			}
			break;
			
			case packet_jail:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 whichPlayer;
					packet.pop(whichPlayer);
					
					string playerName = jjPlayers[playerID].name;
					jjAlert("" + playerName + " is now jailed!", true);
					players[whichPlayer].jailedTurns = 3;
				}
			}
			break;
			
			case packet_jailAvoid:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 param;
					packet.pop(param);
					string playerName = jjPlayers[playerID].name;
					
					if (param == 1) jjAlert("" + playerName + " used a wild card to avoid jail!", true);
					else jjAlert("" + playerName + " paid 15 coins to avoid jail!", true);
				}
			}
			break;
			
			case packet_chance:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					uint chanceCase;
					packet.pop(chanceCase);
					int8 param;
					packet.pop(param);
					
					switch (chanceCase) {
						case 1: jjAlert("" + jjPlayers[playerID].name + " finds a vacated turtle shell with 20 coins!", true);
						break;
						case 2: jjAlert("" + jjPlayers[playerID].name + " pays a fine of 15 coins!", true);
						break;
						case 3: jjAlert("" + jjPlayers[playerID].name + " moves on to Raneforus Road!", true);
						break;
						case 4: jjAlert("" + jjPlayers[playerID].name + " moves on to Holidaius Hills!", true);
						break;
						case 5: jjAlert("" + jjPlayers[playerID].name + " moves on to START!", true);
						break;
						case 6:
						{
							if (param == 0) jjAlert("" + jjPlayers[playerID].name + " has no properties to pay renovations for!", true);
							else jjAlert("" + jjPlayers[playerID].name + " pays renovation fees for " + param + " coins!", true);
						}
						break;
						case 7: jjAlert("" + jjPlayers[playerID].name + " wins 50 coins in a crossword competition!", true);
						break;
						case 8: jjAlert("" + jjPlayers[playerID].name + " moves on to Ceramicus Corner!", true);
						break;
						case 9: jjAlert("" + jjPlayers[playerID].name + " gains a wild card for JAIL!", true);
						break;
						case 10: jjAlert("" + jjPlayers[playerID].name + " is arrested!", true);
						break;
						case 11: jjAlert("" + jjPlayers[playerID].name + " gains 15 coins from a bank error!", true);
						break;
						case 12: jjAlert("" + jjPlayers[playerID].name + " loses 50 coins in a roulette! Bummer!", true);
						break;
						case 13: jjAlert("" + jjPlayers[playerID].name + " catches a space taxi and moves 3 squares forward!", true);
						break;
						case 14: jjAlert("" + jjPlayers[playerID].name + " catches a space taxi and gets 2 squares behind!", true);
						break;
						case 15: jjAlert("" + jjPlayers[playerID].name + " finds a wormhole to move ahead 5 squares!", true);
						break;
						case 16: jjAlert("Nothing seems to happen to " + jjPlayers[playerID].name + "...", true);
						break;
					}
					
					usedChances.insertLast(chanceCase);
					
					jjSTREAM chanceUpdate;
					chanceUpdate.push(uint8(packet_chance));
					chanceUpdate.push(playerID);
					chanceUpdate.push(chanceCase);
					chanceUpdate.push(param);
					jjSendPacket(chanceUpdate, -clientID);
					
					if (usedChances.length() == 16) {
						for (int i = 0; i < 16; i++) {
							usedChances.removeLast(); //empty used cases (shuffle deck)
						}
						
						jjAlert("All chance cards have been used! Shuffling deck!");
					}
				}
			}
			break;
			
			case packet_cc:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					uint ccCase;
					packet.pop(ccCase);
					int8 param;
					packet.pop(param);
					
					switch (ccCase) {
						case 1: jjAlert("" + jjPlayers[playerID].name + " wins 20 coins for the 2nd place in a beauty contest!", true);
						break;
						case 2: jjAlert("" + jjPlayers[playerID].name + " receives 20 coins from each player as a birthday gift!", true);
						break;
						case 3: jjAlert("" + jjPlayers[playerID].name + " pays 25 coins for medical expenses!", true);
						break;
						case 4: jjAlert("" + jjPlayers[playerID].name + " returns back to Letni Loop!", true);
						break;
						case 5: jjAlert("" + jjPlayers[playerID].name + " moves on to START!", true);
						break;
						case 6:	jjAlert("" + jjPlayers[playerID].name + " gains 15 coins for tax refund!", true);
						break;
						case 7: jjAlert("" + jjPlayers[playerID].name + " gains 35 coins from saving interest!", true);
						break;
						case 8: jjAlert("" + jjPlayers[playerID].name + " pays 10 coins for insurance!", true);
						break;
						case 9: jjAlert("" + jjPlayers[playerID].name + " gains a wild card for JAIL!", true);
						break;
						case 10: jjAlert("" + jjPlayers[playerID].name + " is arrested!", true);
						break;
						case 11: jjAlert("" + jjPlayers[playerID].name + " inherits 30 coins!", true);
						break;
						case 12: jjAlert("" + jjPlayers[playerID].name + " pays public school taxes for 30 coins!", true);
						break;
						case 13:
						{
							if (param == 1) jjAlert("" + jjPlayers[playerID].name + " receives 20 coins from a power up!", true);
							else jjAlert("" + jjPlayers[playerID].name + " receives a rent power up!", true);
						}
						break;
						case 14:
						{
							if (param == 1) jjAlert("" + jjPlayers[playerID].name + " receives 60 coins from a bonus!", true);
							else jjAlert("" + jjPlayers[playerID].name + " gains a free random property!", true);
						}
						break;
						case 15:
						{
							if (param == 1) jjAlert("" + jjPlayers[playerID].name + " pays 10 coins to the poor!", true);
							else jjAlert("" + jjPlayers[playerID].name + " gains 5 coins for being poor (no properties)!", true);
						}
						break;
						case 16: jjAlert("" + jjPlayers[playerID].name + " encounters a space troll!", true);
						break;
					}
					
					usedCCs.insertLast(ccCase);
					
					jjSTREAM ccUpdate;
					ccUpdate.push(uint8(packet_cc));
					ccUpdate.push(playerID);
					ccUpdate.push(ccCase);
					ccUpdate.push(param);
					jjSendPacket(ccUpdate, -clientID);
					
					if (usedCCs.length() == 16) {
						for (int i = 0; i < 16; i++) {
							usedCCs.removeLast(); //empty used cases (shuffle deck)
						}
						
						jjAlert("All community chest cards have been used! Shuffling deck!");
					}
				}
			}
			break;
			
			case packet_elim:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 whichPlayer;
					packet.pop(whichPlayer);
					players[whichPlayer].isOut = true;
					players[whichPlayer].propertiesOwned = 0;
					uint listLength = players[whichPlayer].ownedSquares.length();
					
					for (uint u = 0; u < listLength; u++) {
						squares[players[whichPlayer].ownedSquares[u]].owner = -1;
					}
					
					for (uint u = 0; u < listLength; u++) {
						players[whichPlayer].ownedSquares.removeLast();
					}
					
					deducePlayers(playerID, whichPlayer);
					
					jjAlert("" + jjPlayers[playerID].name + " is bankrupt and thus is out!", true, STRING::MEDIUM);
					jjAlert("All of " + jjPlayers[playerID].name + "'s properties have been freed to open market!", true, STRING::SMALL);
					
					jjSTREAM elimRedirect;
					elimRedirect.push(uint8(packet_elim));
					elimRedirect.push(playerID);
					elimRedirect.push(whichPlayer);
					jjSendPacket(elimRedirect, -clientID);
					
					jjChat("/forcespectate " + (playerID + 1) + " on");
				}
			}
			break;
			
			case packet_noThrow:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					jjAlert("" + jjPlayers[playerID].name + " didn't throw the dice in time. Penalty: -20 coins!", true);
				}
			}
			break;
			
			case packet_wildCardUse:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 whichPlayer;
					packet.pop(whichPlayer);
					players[whichPlayer].hasWildCard = false;
					
					if (players[whichPlayer].jailedTurns > 0) {
						jjAlert("" + jjPlayers[playerID].name + " used a wild card to get free from JAIL!", true);
						players[whichPlayer].jailedTurns = 0;
					}
				}
			}
			break;
			
			case packet_coin:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 whichPlayer;
					packet.pop(whichPlayer);
					int coins;
					packet.pop(coins);
					players[whichPlayer].coins += coins;
					
					jjSTREAM globalResponse;
					globalResponse.push(uint8(packet_coin));
					globalResponse.push(playerID);
					globalResponse.push(whichPlayer);
					globalResponse.push(coins);
					jjSendPacket(globalResponse, -clientID);
				}
			}
			break;
			
			case packet_gameStart:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					jjChat("/start");
				}
			}
			break;
			
			case packet_option1:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					if (turnTimeLimitInt < 6) {
						turnTimeLimitInt++;
						M = minutesArray[turnTimeLimitInt];
						S = secondsArray[turnTimeLimitInt];
						timer = (M * 60 + S) * 70;
						maxTime = (M * 60 + S) * 70;
					}
					
					else {
						turnTimeLimitInt = 0;
						M = minutesArray[turnTimeLimitInt];
						S = secondsArray[turnTimeLimitInt];
						timer = (M * 60 + S) * 70;
						maxTime = (M * 60 + S) * 70;
					}
					
					jjSTREAM globalResponse;
					globalResponse.push(uint8(packet_option1));
					globalResponse.push(playerID);
					jjSendPacket(globalResponse, -clientID);
				}
			}
			break;
			
			case packet_option2:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					if (roundLimitInt < 6) {
						roundLimitInt++;
					}
					
					else {
						roundLimitInt = 0;
					}
					
					jjSTREAM globalResponse;
					globalResponse.push(uint8(packet_option2));
					globalResponse.push(playerID);
					jjSendPacket(globalResponse, -clientID);
				}
			}
			break;
			
			case packet_cc2:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					if (inGame) {
						coinElapsed = 1;
						coinFinal = 41;
						takeCoins = true;
					}
					
					jjSTREAM cc2Redirect;
					cc2Redirect.push(uint8(packet_cc2));
					cc2Redirect.push(playerID);
					jjSendPacket(cc2Redirect, -clientID);
				}
			}
			break;
			
			case packet_rentChange:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int propertyID;
					packet.pop(propertyID);
					
					squares[propertyID].rentLevel++;
					squares[propertyID].rent = int(squares[propertyID].price * squares[propertyID].rentLevel * 0.4);
					squares[propertyID].upPrice = squares[propertyID].rent * 1.5;
					jjAlert("" + jjPlayers[playerID].name + " has upgraded the rent of " + squares[propertyID].name + "!", true);
					
					jjSTREAM redirect;
					redirect.push(uint8(packet_rentChange));
					redirect.push(playerID);
					redirect.push(propertyID);
					jjSendPacket(redirect, -clientID);
				}
			}
			break;
			
			case packet_freeProperty:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					uint randomProperty;
					packet.pop(randomProperty);
					int whichPlayer;
					packet.pop(whichPlayer);
					
					players[whichPlayer].propertiesOwned++;
					players[whichPlayer].ownedSquares.insertLast(randomProperty);
					squares[randomProperty].owner = playerID;
					jjAlert("" + squares[randomProperty].name + " now belongs to " + jjPlayers[playerID].name + "!", true);
					
					jjSTREAM redirect;
					redirect.push(uint8(packet_freeProperty));
					redirect.push(playerID);
					redirect.push(randomProperty);
					redirect.push(whichPlayer);
					jjSendPacket(redirect, -clientID);
				}
			}
			break;
			
			case packet_spaceTroll:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (jjPlayers[playerID].clientID == clientID) {
					int8 param;
					packet.pop(param);
					
					if (param == 0) jjAlert("" + jjPlayers[playerID].name + " pays 10 coins to the space troll to move on!", true);
					else jjAlert("" + jjPlayers[playerID].name + " escapes the space troll and takes a chance!", true);
				}
			}
			break;
		}
	}
	
	else {
		switch (type) {
			case packet_turnStart:
			{
				round++;
				wait = 0;
				isTurn = true;
				bought = false;
				printSquare = false;
				printChance = false;
				printOK = false;
				waitForChance = false;
				waitForSelect = false;
				waitForMove = false;
				waitForMoveForward = false;
				waitForMoveBack = false;
				waitForMoveQuick = false;
				waitForFinish = false;
				preAction = true;
				midAction = false;
				postAction = false;
				postTurn = false;
				viewMap = false;
				selling = false;
				upgrading = false;
				drawBackground = true;
				hasThrown = false; //change this back to false for final version
				isThrowing = false;
				//hasSelected = false; //remove this for final version
				switched = false;
				confirmed = false;
				diceConfirmed = false;
				selectionPos = 0;
				jjSamplePriority(SOUND::COMMON_BELL_FIRE);
			}
			break;
			
			case packet_turnSkip:
			{
				round++;
				wait = 0;
				isTurn = true;
				bought = false;
				printSquare = false;
				printChance = false;
				printOK = false;
				waitForChance = false;
				waitForSelect = false;
				waitForMove = false;
				waitForMoveForward = false;
				waitForMoveBack = false;
				waitForMoveQuick = false;
				waitForFinish = false;
				postAction = true;
				postTurn = false;
				viewMap = false;
				selling = false;
				upgrading = false;
				drawBackground = true;
				hasThrown = true; //change this back to false for final version
				isThrowing = false;
				switched = false;
				confirmed = false;
				diceConfirmed = true;
				selectionPos = 0;
				jjSamplePriority(SOUND::COMMON_BELL_FIRE);
			}
			break;
			
			case packet_signupResp:
			{
				int8 playerID;
				packet.pop(playerID);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				yourPlayerNo = whichPlayer;
				int coins;
				packet.pop(coins);
				players[yourPlayerNo].coins = coins;
				
				inGame = true;
				jjPlayers[playerID].warpToTile(squarex[0], squarey[0], true);
				jjSamplePriority(SOUND::EPICLOGO_EPIC2);
				jjPlayers[playerID].coins = coins;
				jjSamplePriority(SOUND::COMMON_COIN);
				isInBox = false;
				players[yourPlayerNo].pID = playerID;
				players[yourPlayerNo].playerName = jjPlayers[playerID].name;
				players[yourPlayerNo].isOccupied = true;
			}
			break;
			
			case packet_signupAnn:
			{
				int8 playerID;
				packet.pop(playerID);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				int coins;
				packet.pop(coins);
				
				players[whichPlayer].coins = coins;
				players[whichPlayer].pID = playerID;
				players[whichPlayer].playerName = jjPlayers[playerID].name;
				players[whichPlayer].isOccupied = true;
			}
			break;
			
			case packet_move:
			{
				int8 playerID;
				packet.pop(playerID);
				int receivedSquare;
				packet.pop(receivedSquare);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				
				players[whichPlayer].currSquare = receivedSquare;
			}
			break;
			
			case packet_rent:
			{
				int8 playerID;
				packet.pop(playerID);
				int8 ownerID;
				packet.pop(ownerID);
				int rent;
				packet.pop(rent);
				
				string senderName = jjPlayers[playerID].name;
				jjAlert("You receive " + rent + " coins from " + senderName, false, STRING::MEDIUM);
				
				coinElapsed = 1;
				coinFinal = rent * 2 + 1;
				giveCoins = true;
			}
			break;
			
			case packet_buy:
			{
				int8 playerID;
				packet.pop(playerID);
				int squareID;
				packet.pop(squareID);
				int price;
				packet.pop(price);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				
				players[whichPlayer].propertiesOwned++;
				players[whichPlayer].ownedSquares.insertLast(squareID);
				squares[squareID].owner = playerID;
				string playerName = jjPlayers[playerID].name;
				string squareName = squares[squareID].name;
				jjAlert("" + playerName + " has bought " + squareName + " for " + price + " coins.");
			}
			break;
			
			case packet_sell:
			{
				int8 playerID;
				packet.pop(playerID);
				int squareID;
				packet.pop(squareID);
				int sellPrice;
				packet.pop(sellPrice);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				uint index;
				packet.pop(index);
					
				players[whichPlayer].propertiesOwned--;
				players[whichPlayer].ownedSquares.removeAt(index);
				squares[squareID].owner = -1;
				string playerName = jjPlayers[playerID].name;
				string squareName = squares[squareID].name;
			}
			break;
			
			case packet_idRequest:
			{
				for (uint i = 0; i < players.length(); i++) {
					int8 thisID;
					packet.pop(thisID);
					players[i].pID = thisID;
					int thisCS;
					packet.pop(thisCS);
					players[i].currSquare = thisCS;
					int thisCoins;
					packet.pop(thisCoins);
					players[i].coins = thisCoins;
					bool thisIsOut;
					packet.pop(thisIsOut);
					players[i].isOut = thisIsOut;
					bool thisIsOccupied;
					packet.pop(thisIsOccupied);
					players[i].isOccupied = thisIsOccupied;
				}
				
				for (uint i = 0; i < squares.length(); i++) {
					int8 thisOwner;
					int8 thisLevel;
					packet.pop(thisOwner);
					packet.pop(thisLevel);
					squares[i].owner = thisOwner;
					squares[i].rentLevel = thisLevel;
					squares[i].rent = int(squares[i].price * squares[i].rentLevel * 0.4);
					squares[i].upPrice = squares[i].rent * 1.5;
				}
				
				packet.pop(turnTimeLimitInt);
				M = minutesArray[turnTimeLimitInt];
				S = secondsArray[turnTimeLimitInt];
				timer = (M * 60 + S) * 70;
				maxTime = (M * 60 + S) * 70;
			}
			break;
			
			case packet_jailbreak:
			{
				isJailed = false;
			}
			break;
			
			case packet_chance:
			{
				int8 playerID;
				packet.pop(playerID);
				uint chanceCase;
				packet.pop(chanceCase);
				int8 param;
				packet.pop(param);
				
				usedChances.insertLast(chanceCase);
				
				if (usedChances.length() == 16) {
					for (int i = 0; i < 16; i++) {
						usedChances.removeLast(); //empty used cases (shuffle deck)
					}
					
					jjAlert("All chance cards have been used! Shuffling deck!");
				}
			}
			break;
			
			case packet_cc:
			{
				int8 playerID;
				packet.pop(playerID);
				uint ccCase;
				packet.pop(ccCase);
				int8 param;
				packet.pop(param);
				
				usedCCs.insertLast(ccCase);
				
				if (usedCCs.length() == 16) {
					for (int i = 0; i < 16; i++) {
						usedCCs.removeLast(); //empty used cases (shuffle deck)
					}
					
					jjAlert("All community chest cards have been used! Shuffling deck!");
				}
			}
			break;
			
			case packet_elim:
			{
				int8 playerID;
				packet.pop(playerID);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				players[whichPlayer].isOut = true;
				players[whichPlayer].propertiesOwned = 0;
				
				uint listLength = players[whichPlayer].ownedSquares.length();
				
				for (uint u = 0; u < listLength; u++) {
					squares[players[whichPlayer].ownedSquares[u]].owner = -1;
				}
				
				for (uint u = 0; u < listLength; u++) {
					players[whichPlayer].ownedSquares.removeLast();
				}
			}
			break;
			
			case packet_wildCard:
			{
				round++;
				wait = 0;
				isTurn = true;
				bought = false;
				printSquare = false;
				printChance = false;
				printOK = false;
				waitForChance = false;
				waitForSelect = false;
				waitForMove = false;
				waitForMoveForward = false;
				waitForMoveBack = false;
				waitForMoveQuick = false;
				waitForFinish = false;
				postTurn = false;
				viewMap = false;
				selling = false;
				upgrading = false;
				promptWildCard = true;
				drawBackground = true;
				hasThrown = false;
				isThrowing = false;
				switched = false;
				confirmed = false;
				diceConfirmed = false;
				selectionPos = 0;
				jjSamplePriority(SOUND::COMMON_BELL_FIRE);
			}
			break;
			
			case packet_coin:
			{
				int8 playerID;
				packet.pop(playerID);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				int coins;
				packet.pop(coins);
				players[whichPlayer].coins += coins;
			}
			break;
			
			case packet_firstPlayer:
			{
				firstPlayer = true;
				drawBackground = true;
			}
			break;
			
			case packet_option1:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (turnTimeLimitInt < 6) {
					turnTimeLimitInt++;
					M = minutesArray[turnTimeLimitInt];
					S = secondsArray[turnTimeLimitInt];
					timer = (M * 60 + S) * 70;
					maxTime = (M * 60 + S) * 70;
				}
				
				else {
					turnTimeLimitInt = 0;
					M = minutesArray[turnTimeLimitInt];
					S = secondsArray[turnTimeLimitInt];
					timer = (M * 60 + S) * 70;
					maxTime = (M * 60 + S) * 70;
				}
			}
			break;
			
			case packet_option2:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (roundLimitInt < 6) {
					roundLimitInt++;
				}
				
				else {
					roundLimitInt = 0;
				}
			}
			break;
			
			case packet_registered:
			{
				packet.pop(registered);
			}
			break;
			
			case packet_cc2:
			{
				int8 playerID;
				packet.pop(playerID);
				
				if (inGame) {
					coinElapsed = 1;
					coinFinal = 41;
					takeCoins = true;
				}
			}
			break;
			
			case packet_rentChange:
			{
				int8 playerID;
				packet.pop(playerID);
				int propertyID;
				packet.pop(propertyID);
				
				squares[propertyID].rentLevel++;
				squares[propertyID].rent = int(squares[propertyID].price * squares[propertyID].rentLevel * 0.4);
				squares[propertyID].upPrice = squares[propertyID].rent * 1.5;
			}
			break;
			
			case packet_freeProperty:
			{
				int8 playerID;
				packet.pop(playerID);
				uint randomProperty;
				packet.pop(randomProperty);
				int8 whichPlayer;
				packet.pop(whichPlayer);
				
				players[whichPlayer].propertiesOwned++;
				players[whichPlayer].ownedSquares.insertLast(randomProperty);
				squares[randomProperty].owner = playerID;
			}
			break;
			
			case packet_endGame:
			{
				gameEnded = true;
				drawBackground = true;
				requestedPage = page_blank;
				viewMap = true;
			}
			break;
			
			case packet_players:
			{
				int8 whichPlayer;
				packet.pop(whichPlayer);
				packet.pop(playersLeft);
				
				players[whichPlayer].finalPosition = playersLeft;
			}
			break;
			
			case packet_gameEnding:
			{
				for (uint i = 0; i < players.length; i++) {
					packet.pop(players[i].finalPosition);
					
					//jjAlert("finalPosition of " + jjPlayers[players[i].pID].name + ": " + players[i].finalPosition);
				}
			}
			
			case packet_gameCancel:
			{
				gameStarted = false;
			}
		}
	}
}

//*END OF CLIENT COMMUNICATION*//

//*DRAWING HOOKS*//

bool onDrawHealth(jjPLAYER@ play, jjCANVAS@ canvas) {
	return true;
}

bool onDrawAmmo(jjPLAYER@ play, jjCANVAS@ canvas) { //changed to onDrawAmmo from onDrawHealth, so works on treasure hunt mode as well
	jjTEXTAPPEARANCE centeredText();
	centeredText.align = STRING::CENTER;
	centeredText.pipe = STRING::SPECIALSIGN;
	
	int isTSFintSigns;
		
	if (jjIsTSF) isTSFintSigns = 4;
	else isTSFintSigns = 0;

	if (statsMode == 3) { //with extended stats
		canvas.drawRectangle(20, 70, 100, 72, 72, SPRITE::TRANSLUCENT, 0); //center
		canvas.drawRectangle(20, 66, 100, 4, 72, SPRITE::TRANSLUCENT, 0); //top
		canvas.drawRectangle(120, 70, 4, 72, 72, SPRITE::TRANSLUCENT, 0); //right
		canvas.drawRectangle(20, 142, 100, 4, 72, SPRITE::TRANSLUCENT, 0); //bottom
		canvas.drawRectangle(16, 70, 4, 72, 72, SPRITE::TRANSLUCENT, 0); //left
		int drawtr = 120;
		for (int y = 66; y < 70; y++) {
			drawtr++;
			
			for (int x = 120; x < drawtr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawbr = 120;
		for (int y = 145; y > 141; y--) {
			drawbr++;
			
			for (int x = 120; x < drawbr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawbl = 19;
		for (int y = 145; y > 141; y--) {
			drawbl--;
			
			for (int x = 19; x > drawbl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawtl = 19;
		for (int y = 66; y < 70; y++) {
			drawtl--;
			
			for (int x = 19; x > drawtl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		
		canvas.drawRectangle(20, 200, jjSubscreenWidth - 40, 240, 72, SPRITE::TRANSLUCENT, 0); //center
		canvas.drawRectangle(20, 196, jjSubscreenWidth - 40, 4, 72, SPRITE::TRANSLUCENT, 0); //top
		canvas.drawRectangle(jjSubscreenWidth - 20, 200, 4, 240, 72, SPRITE::TRANSLUCENT, 0); //right
		canvas.drawRectangle(20, 440, jjSubscreenWidth - 40, 4, 72, SPRITE::TRANSLUCENT, 0); //bottom
		canvas.drawRectangle(16, 200, 4, 240, 72, SPRITE::TRANSLUCENT, 0); //left
		drawtr = jjSubscreenWidth - 20;
		for (int y = 196; y < 200; y++) {
			drawtr++;
			
			for (int x = jjSubscreenWidth - 20; x < drawtr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		drawbr = jjSubscreenWidth - 20;
		for (int y = 443; y > 439; y--) {
			drawbr++;
			
			for (int x = jjSubscreenWidth - 20; x < drawbr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		drawbl = 19;
		for (int y = 443; y > 439; y--) {
			drawbl--;
			
			for (int x = 19; x > drawbl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		drawtl = 19;
		for (int y = 196; y < 200; y++) {
			drawtl--;
			
			for (int x = 19; x > drawtl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		
		canvas.drawResizedSprite(26, 84, 67 + isTSFintSigns, 1, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 100, 67 + isTSFintSigns, 2, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 116, 67 + isTSFintSigns, 16, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 132, 67 + isTSFintSigns, 71, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		
		for (int i = 0; i < 4; i++) {
			if (players[i].pID == -1) canvas.drawString(60, 86 + 16 * i, "OFF", STRING::SMALL, centeredText);
			else {
				if (players[i].isOut) canvas.drawString(100, 86 + 16 * i, "||OUT", STRING::SMALL, centeredText);
				if (players[i].coins >= 0) canvas.drawString(60, 86 + 16 * i, "" + players[i].coins, STRING::SMALL, centeredText);
				else canvas.drawString(60, 86 + 16 * i, "||" + players[i].coins, STRING::SMALL, centeredText);
			}
		}
		
		canvas.drawString(24, 208, "Property Name", STRING::SMALL);
		canvas.drawString(jjSubscreenWidth / 20 * 9, 208, "Owner Name", STRING::SMALL, centeredText);
		canvas.drawString(jjSubscreenWidth / 10 * 7, 208, "Price", STRING::SMALL, centeredText);
		canvas.drawString(jjSubscreenWidth / 10 * 8, 208, "Rent", STRING::SMALL, centeredText);
		canvas.drawString(jjSubscreenWidth / 10 * 9, 208, "Level", STRING::SMALL, centeredText);
		array<string> squareOwnerNames(20); //same length as squares, for simplicity
		int negCounter = 0;
		int j = 0;
		for (int i = 0; i < 20; i++) {
			int8 squareOwner = squares[i].owner;
			
			if (squareOwner >= 0) {
				string squareOwnerName = jjPlayers[squareOwner].name;
				squareOwnerNames[i] = squareOwnerName;
				
				if (j % 2 == 0) {
					canvas.drawString(24, 240 + 16 * i + negCounter, "" + squares[i].name, STRING::SMALL, STRING::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 20 * 9, 240 + 16 * i + negCounter, "" + squareOwnerNames[i], STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 7, 240 + 16 * i + negCounter, "" + squares[i].price, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 8, 240 + 16 * i + negCounter, "" + squares[i].rent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 9, 240 + 16 * i + negCounter, "" + squares[i].rentLevel, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				}
				
				else {
					canvas.drawString(24, 240 + 16 * i + negCounter, "" + squares[i].name, STRING::SMALL, STRING::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 20 * 9, 240 + 16 * i + negCounter, "" + squareOwnerNames[i], STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 7, 240 + 16 * i + negCounter, "" + squares[i].price, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 8, 240 + 16 * i + negCounter, "" + squares[i].rent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 9, 240 + 16 * i + negCounter, "" + squares[i].rentLevel, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				}
				
				j++;
			}
			
			else if (squareOwner == -1) {
				if (j % 2 == 0) {
					canvas.drawString(24, 240 + 16 * i + negCounter, "" + squares[i].name, STRING::SMALL, STRING::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 7, 240 + 16 * i + negCounter, "" + squares[i].price, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 8, 240 + 16 * i + negCounter, "" + squares[i].rent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
					canvas.drawString(jjSubscreenWidth / 10 * 9, 240 + 16 * i + negCounter, "" + squares[i].rentLevel, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				}
				
				else {
					canvas.drawString(24, 240 + 16 * i + negCounter, "" + squares[i].name, STRING::SMALL, STRING::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 7, 240 + 16 * i + negCounter, "" + squares[i].price, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 8, 240 + 16 * i + negCounter, "" + squares[i].rent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
					canvas.drawString(jjSubscreenWidth / 10 * 9, 240 + 16 * i + negCounter, "" + squares[i].rentLevel, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				}
				
				j++;
			}
			
			else {
				negCounter -= 16;
			}
		}
	}
	
	if (statsMode == 2) {
		canvas.drawRectangle(20, 70, 100, 72, 72, SPRITE::TRANSLUCENT, 0); //center
		canvas.drawRectangle(20, 66, 100, 4, 72, SPRITE::TRANSLUCENT, 0); //top
		canvas.drawRectangle(120, 70, 4, 72, 72, SPRITE::TRANSLUCENT, 0); //right
		canvas.drawRectangle(20, 142, 100, 4, 72, SPRITE::TRANSLUCENT, 0); //bottom
		canvas.drawRectangle(16, 70, 4, 72, 72, SPRITE::TRANSLUCENT, 0); //left
		int drawtr = 120;
		for (int y = 66; y < 70; y++) {
			drawtr++;
			
			for (int x = 120; x < drawtr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawbr = 120;
		for (int y = 145; y > 141; y--) {
			drawbr++;
			
			for (int x = 120; x < drawbr; x++) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawbl = 19;
		for (int y = 145; y > 141; y--) {
			drawbl--;
			
			for (int x = 19; x > drawbl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		int drawtl = 19;
		for (int y = 66; y < 70; y++) {
			drawtl--;
			
			for (int x = 19; x > drawtl; x--) {
				canvas.drawPixel(x, y, 72, SPRITE::TRANSLUCENT, 0);
			}
		}
		
		canvas.drawResizedSprite(26, 84, 67 + isTSFintSigns, 1, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 100, 67 + isTSFintSigns, 2, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 116, 67 + isTSFintSigns, 16, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		canvas.drawResizedSprite(26, 132, 67 + isTSFintSigns, 71, 0, 0.5, 0.5, SPRITE::NORMAL, 0);
		
		for (int i = 0; i < 4; i++) {
			if (players[i].pID == -1) canvas.drawString(60, 86 + 16 * i, "OFF", STRING::SMALL, centeredText);
			else {
				if (players[i].isOut) canvas.drawString(100, 86 + 16 * i, "||OUT", STRING::SMALL, centeredText);
				if (players[i].coins >= 0) canvas.drawString(60, 86 + 16 * i, "" + players[i].coins, STRING::SMALL, centeredText);
				else canvas.drawString(60, 86 + 16 * i, "||" + players[i].coins, STRING::SMALL, centeredText);
			}
		}
	}
	
	else if (statsMode == 1) {
		canvas.drawString(4, 64, "Press 0 to toggle stats");
		canvas.drawString(4, 80, "Press fire to select option");
		canvas.drawString(4, 96, "Use arrow keys to switch options");
	}
	
	if (isTurn && maxTime <= 5 * 60 * 70) {
		canvas.drawString(jjSubscreenWidth - 112, 32*3, "||||||||Your turn!");
		canvas.drawString(jjSubscreenWidth - 64, 32*3.5, turnTimer);
	}
	
	if (isTurn && hasThrown && printDice) {
		canvas.drawString(jjSubscreenWidth / 2 - 8, 444, "||" + lastThrownNumber, STRING::LARGE, STRING::NORMAL); //312, 164
	}
	
	if (viewMap) {
		int isTSFintArrow;
	
		if (jjIsTSF) isTSFintArrow = 1;
		else isTSFintArrow = 0;
		
		canvas.drawRotatedSprite(jjMouseX + 16, jjMouseY + 24, 43 + isTSFintArrow, 0, 0, 288, 1, 1, SPRITE::NORMAL);
		
		if (isTurn && requestedPage != page_blank && gameRuns) {
			canvas.drawString(jjSubscreenWidth / 2, 188, "Press fire to return!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		}
	}
	
	if (isInBox && !gameEnded && !gameRuns) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "Press fire to sign up for the game!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
	}
	
	else if (inGame && !gameStarted && !gameEnded && !firstPlayer) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "Type /start to start the game!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "Hint: Use mouse to freely view the map!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
	}
	
	int isTSFintCoin;
	
	if (jjIsTSF) isTSFintCoin = 4;
	else isTSFintCoin = 0;
	
	if (inGame && !gameEnded) {
		canvas.drawSprite(jjSubscreenWidth - 66, 74, 67 + isTSFintCoin, 84, 0, 0);
		
		if (play.coins >= 0) canvas.drawString(jjSubscreenWidth - 54, 80, "x" + play.coins);
		else canvas.drawString(jjSubscreenWidth - 54, 80, "||x" + play.coins);
		
		string roundString = "Round: ";
		
		if (roundsArray[roundLimitInt] != 0) roundString = "Round: " + round + "/" + roundsArray[roundLimitInt];
		else roundString = "Round: " + round;
		
		uint length = roundString.length();
		
		canvas.drawString(jjSubscreenWidth - length * 12, 96, roundString);
	}
	
	if (printSquare) {
		Square thisSquare = squares[squareID];
		int rent = thisSquare.rent;
		string rentString;
		if (rent == 0) rentString = "";
		else rentString = "Rent: " + rent + " coins.";
		
		canvas.drawString(jjSubscreenWidth / 2, 164, "You've hit " + thisSquare.name, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		canvas.drawString(jjSubscreenWidth / 2, 212, squareFunction, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		canvas.drawString(jjSubscreenWidth / 2, 236, squareAction, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 260, squarePrice, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		canvas.drawString(jjSubscreenWidth / 2, 284, rentString, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		
		if (buyable) {
			if (selectionPos == 0) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
			
			else if (selectionPos == 1) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
			
			else if (selectionPos == 2) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
		}
		
		if (requestJailMoney) {
			if (selectionPos == 0) {
				canvas.drawString(jjSubscreenWidth / 2, 292, "Pay 15 Coins", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 328, "Don't Pay", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 364, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				
				jjTEXTAPPEARANCE darkText(STRING::DARK);
				darkText.align = STRING::CENTER;
				
				if (players[yourPlayerNo].hasWildCard) canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				else canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, darkText, 0, SPRITE::BRIGHTNESS, 64);
			}
			
			else if (selectionPos == 1) {
				canvas.drawString(jjSubscreenWidth / 2, 292, "Pay 15 Coins", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 328, "Don't Pay", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 364, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				
				jjTEXTAPPEARANCE darkText(STRING::DARK);
				darkText.align = STRING::CENTER;
				
				if (players[yourPlayerNo].hasWildCard) canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				else canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, darkText, 0, SPRITE::BRIGHTNESS, 64);
			}
			
			else if (selectionPos == 2) {
				canvas.drawString(jjSubscreenWidth / 2, 292, "Pay 15 Coins", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 328, "Don't Pay", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 364, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				
				jjTEXTAPPEARANCE darkText(STRING::DARK);
				darkText.align = STRING::CENTER;
				
				if (players[yourPlayerNo].hasWildCard) canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				else canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::SMALL, darkText, 0, SPRITE::BRIGHTNESS, 64);
			}
			
			else if (selectionPos == 3) {
				canvas.drawString(jjSubscreenWidth / 2, 292, "Pay 15 Coins", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 328, "Don't Pay", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 364, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				
				canvas.drawString(jjSubscreenWidth / 2, 400, "Use wild card", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
		}
	}
	
	if (isTurn && waitForChance) {
		canvas.drawResizedSprite(jjSubscreenWidth / 2, 380, ANIM::DOOR, 0, animFrame, 4, 4);
		
		if (drawMark) {
			canvas.drawString(jjSubscreenWidth / 2, 340, "?", STRING::LARGE, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (isTurn && waitForCC) {
		if (drawMark) {
			canvas.drawString(jjSubscreenWidth / 2, marky, "?", STRING::LARGE, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		canvas.drawResizedSprite(jjSubscreenWidth / 2, 380, ANIM::BIGBOX, 0, 0, 2, 2);
	}
	
	if (!gameEnded && isTurn && preAction && !viewMap && !selling && !upgrading) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "Round " + round, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "First Phase", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Roll The Dice", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	
		else if (selectionPos == 1) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Roll The Dice", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		else if (selectionPos == 2) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Roll The Dice", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		else if (selectionPos == 3) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Roll The Dice", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (isTurn && midAction && !viewMap && !selling && bought && !upgrading) {
		Square thisSquare = squares[squareID];
		canvas.drawString(jjSubscreenWidth / 2, 164, "You've bought " + thisSquare.name, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "You now have " + play.coins + " coins.", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
	}
	
	if (printChance) {
		canvas.drawString(jjSubscreenWidth / 2, 164, c1, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
		canvas.drawString(jjSubscreenWidth / 2, 180, c2, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 196, c3, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
	}
		
	if (printCC) {
		canvas.drawString(jjSubscreenWidth / 2, 164, c1, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
		canvas.drawString(jjSubscreenWidth / 2, 180, c2, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 196, c3, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
		
		if (spaceTroll) {
			if (selectionPos == 0) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Pay 10 Coins", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "Draw a Chance Card", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
			
			if (selectionPos == 1) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Pay 10 Coins", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "Draw a Chance Card", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
			
			if (selectionPos == 2) {
				canvas.drawString(jjSubscreenWidth / 2, 364, "Pay 10 Coins", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 400, "Draw a Chance Card", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
				canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			}
		}
	}
	
	if (printOK && !giveCoins && !takeCoins && !spaceTroll) {
		canvas.drawString(jjSubscreenWidth / 2, 364, "OK", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
	}
	
	if (isTurn && postAction && !viewMap && !selling && !upgrading) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "Round " + round, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "Second Phase", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "End Turn", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	
		else if (selectionPos == 1) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "End Turn", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		else if (selectionPos == 2) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "End Turn", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		else if (selectionPos == 3) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "End Turn", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 396, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 428, "Sell Properties", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 460, "Upgrade Properties", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (promptWildCard) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "You hold a wild card for JAIL!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "Do you want to use it now to get free?", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		if (selectionPos == 1) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		if (selectionPos == 2) {
			canvas.drawString(jjSubscreenWidth / 2, 364, "Yes", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 400, "No", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "View Map", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (selling) {
		for (uint u = 0; u < players[yourPlayerNo].ownedSquares.length(); u++) {
			if (u % 2 == 0) {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string sellPrice = squares[players[yourPlayerNo].ownedSquares[u]].sellPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + sellPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
			}
			
			else {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string sellPrice = squares[players[yourPlayerNo].ownedSquares[u]].sellPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + sellPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
			}
		}
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Selling Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
		}
		
		else if (selectionPos > 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Selling Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			
			int isTSFintArrow;
			string squareName = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].name;
			string level = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].rentLevel;
			
			uint nameLength = squareName.length();
			uint levelLength = level.length();
			
			if (jjIsTSF) isTSFintArrow = 1;
			else isTSFintArrow = 0;
			
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 3 - nameLength / 2 * 15, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 950, 1, 1, SPRITE::NORMAL);
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 15 + levelLength / 2 * 48, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 445, 1, 1, SPRITE::NORMAL);
		}
	}
	
	if (upgrading) {
		for (uint u = 0; u < players[yourPlayerNo].ownedSquares.length(); u++) {
			if (u % 2 == 0) {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string upPrice = squares[players[yourPlayerNo].ownedSquares[u]].upPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + upPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
			}
			
			else {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string upPrice = squares[players[yourPlayerNo].ownedSquares[u]].upPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + upPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
			}
		}
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Upgrading Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
		}
		
		else if (selectionPos > 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Upgrading Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			
			int isTSFintArrow;
			string squareName = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].name;
			string level = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].rentLevel;
			
			uint nameLength = squareName.length();
			uint levelLength = level.length();
			
			if (jjIsTSF) isTSFintArrow = 1;
			else isTSFintArrow = 0;
			
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 3 - nameLength / 2 * 15, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 950, 1, 1, SPRITE::NORMAL);
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 15 + levelLength / 2 * 48, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 445, 1, 1, SPRITE::NORMAL);
		}
	}
	
	if (confirmation) {
		for (uint u = 0; u < players[yourPlayerNo].ownedSquares.length(); u++) {
			if (u % 2 == 0) {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string sellPrice = squares[players[yourPlayerNo].ownedSquares[u]].sellPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + sellPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 16);
			}
			
			else {
				string squareName = squares[players[yourPlayerNo].ownedSquares[u]].name;
				string squareRent = squares[players[yourPlayerNo].ownedSquares[u]].rent;
				string sellPrice = squares[players[yourPlayerNo].ownedSquares[u]].sellPrice;
				string level = squares[players[yourPlayerNo].ownedSquares[u]].rentLevel;
				canvas.drawString(jjSubscreenWidth / 16 * 3, 216 + u * 16, "" + squareName, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 7, 216 + u * 16, "" + squareRent, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 10, 216 + u * 16, "" + sellPrice, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
				canvas.drawString(jjSubscreenWidth / 16 * 14, 216 + u * 16, "" + level, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 24);
			}
		}
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Selling Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
		}
		
		else if (selectionPos > 0) {
			canvas.drawString(jjSubscreenWidth / 2, 164, "BACK", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			canvas.drawString(jjSubscreenWidth / 16 * 3, 200, "Name", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 7, 200, "Rent", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 10, 200, "Selling Price", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			canvas.drawString(jjSubscreenWidth / 16 * 14, 200, "Level", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 0);
			
			int isTSFintArrow;
			string squareName = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].name;
			string level = squares[players[yourPlayerNo].ownedSquares[selectionPos - 1]].rentLevel;
			
			uint nameLength = squareName.length();
			uint levelLength = level.length();
			
			if (jjIsTSF) isTSFintArrow = 1;
			else isTSFintArrow = 0;
			
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 3 - nameLength / 2 * 15, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 950, 1, 1, SPRITE::NORMAL);
			canvas.drawRotatedSprite(jjSubscreenWidth / 16 * 15 + levelLength / 2 * 48, 196 + selectionPos * 16, 43 + isTSFintArrow, 0, 1, 445, 1, 1, SPRITE::NORMAL);
		}
		
		canvas.drawString(jjSubscreenWidth / 2, 424, "Are you sure?", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		
		if (confirmationPos == 0) {
			canvas.drawString(jjSubscreenWidth / 10 * 4, 460, "No", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 10 * 6, 460, "Yes", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		else {
			canvas.drawString(jjSubscreenWidth / 10 * 4, 460, "No", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 10 * 6, 460, "Yes", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (!gameEnded && printReward) {
		canvas.drawString(jjSubscreenWidth / 2, 100, "You earn 25 coins for", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		canvas.drawString(jjSubscreenWidth / 2, 124, "completing a round!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		
		if (rewardElapsed < 700) rewardElapsed++;
		else {
			printReward = false;
		}
	}
	
	if (firstPlayer && !gameStarted) {
		canvas.drawString(jjSubscreenWidth / 2, 164, "You are the first player to sign up!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 16);
		canvas.drawString(jjSubscreenWidth / 2, 188, "You may choose settings for the game.", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 24);
		
		if (selectionPos == 0) {
			canvas.drawString(jjSubscreenWidth / 4, 364, "Turn time limit", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4, 400, "Round limit", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "Start the game!", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			string timeLimitString;
			string roundLimitString;
			
			if (turnTimeLimitInt < 6) timeLimitString = formatInt(maxTime / (60 * 70), "0", 2) + ":" + formatInt((maxTime / 70) % 60, "0", 2);
			else timeLimitString = "Unlimited";
			if (roundLimitInt < 6) roundLimitString = "" + roundsArray[roundLimitInt];
			else roundLimitString = "Unlimited";
			
			canvas.drawString(jjSubscreenWidth / 4 * 3, 364, "" + timeLimitString, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4 * 3, 400, "" + roundLimitString, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		if (selectionPos == 1) {
			canvas.drawString(jjSubscreenWidth / 4, 364, "Turn time limit", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4, 400, "Round limit", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "Start the game!", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			string timeLimitString;
			string roundLimitString;
			
			if (turnTimeLimitInt < 6) timeLimitString = formatInt(maxTime / (60 * 70), "0", 2) + ":" + formatInt((maxTime / 70) % 60, "0", 2);
			else timeLimitString = "Unlimited";
			if (roundLimitInt < 6) roundLimitString = "" + roundsArray[roundLimitInt];
			else roundLimitString = "Unlimited";
			
			canvas.drawString(jjSubscreenWidth / 4 * 3, 364, "" + timeLimitString, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4 * 3, 400, "" + roundLimitString, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
		
		if (selectionPos == 2) {
			canvas.drawString(jjSubscreenWidth / 4, 364, "Turn time limit", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4, 400, "Round limit", STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 2, 436, "Start the game!", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
			
			string timeLimitString;
			string roundLimitString;
			
			if (turnTimeLimitInt < 6) timeLimitString = formatInt(maxTime / (60 * 70), "0", 2) + ":" + formatInt((maxTime / 70) % 60, "0", 2);
			else timeLimitString = "Unlimited";
			if (roundLimitInt < 6) roundLimitString = "" + roundsArray[roundLimitInt];
			else roundLimitString = "Unlimited";
			
			canvas.drawString(jjSubscreenWidth / 4 * 3, 364, "" + timeLimitString, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
			canvas.drawString(jjSubscreenWidth / 4 * 3, 400, "" + roundLimitString, STRING::SMALL, centeredText, 0, SPRITE::PALSHIFT, 8);
		}
	}
	
	if (gameEnded) {
		switch (registered) {
			case 1: 
			{
				canvas.drawString(jjSubscreenWidth / 4, 160, "1st", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 1) canvas.drawString(jjSubscreenWidth / 2, 160, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
			}
			break;
			
			case 2:
			{
				canvas.drawString(jjSubscreenWidth / 4, 160, "1st", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 1) canvas.drawString(jjSubscreenWidth / 2, 160, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 208, "2nd", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 2) canvas.drawString(jjSubscreenWidth / 2, 208, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
			}
			break;
			
			case 3: 
			{
				canvas.drawString(jjSubscreenWidth / 4, 160, "1st", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 1) canvas.drawString(jjSubscreenWidth / 2, 160, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 208, "2nd", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 2) canvas.drawString(jjSubscreenWidth / 2, 208, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 256, "3rd", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 3) canvas.drawString(jjSubscreenWidth / 2, 256, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
			}
			break;
			
			case 4:
			{
				canvas.drawString(jjSubscreenWidth / 4, 160, "1st", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 1) canvas.drawString(jjSubscreenWidth / 2, 160, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 208, "2nd", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 2) canvas.drawString(jjSubscreenWidth / 2, 208, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 256, "3rd", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 3) canvas.drawString(jjSubscreenWidth / 2, 256, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
				canvas.drawString(jjSubscreenWidth / 4, 302, "4th", STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				for (int i = 0; i < 4; i++) {
					if (players[i].finalPosition == 4) canvas.drawString(jjSubscreenWidth / 2, 302, "" + players[i].playerName, STRING::MEDIUM, centeredText, 0, SPRITE::PALSHIFT, 8);
				}
			}
			break;
		}
	}
	
	return true;
}

void onDrawLayer2(jjPLAYER@ p, jjCANVAS@ canvas) {
	array<string> squareOwnerNames(20); //same length as squares, for simplicity
	for (uint i = 0; i < squareOwnerNames.length(); i++) {
		int8 squareOwner = squares[i].owner;
		
		if (squareOwner >= 0) {
			string squareOwnerName = jjPlayers[squareOwner].name;
			squareOwnerNames[i] = squareOwnerName;
		}
		
		else {
			squareOwnerNames[i] = "";
		}
	}
	
	jjTEXTAPPEARANCE centeredText();
	centeredText.align = STRING::CENTER;
	centeredText.pipe = STRING::SPECIALSIGN;
	
	canvas.drawString(32*32, 32*32, "||||START", STRING::SMALL, STRING::NORMAL);
	
	canvas.drawString(846, 32*32, "Diamondus", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(864, 32.5*32, "Drive", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(850, 34*32, "Owned by:", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(28*32, 34.5*32, "" + squareOwnerNames[1], STRING::SMALL, centeredText);
	
	canvas.drawString(21.5*32, 32*32, "Lagunicus", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(698, 32.5*32, "Lowland", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(690, 34*32, "Owned by:", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(23*32, 34.5*32, "" + squareOwnerNames[2], STRING::SMALL, centeredText);
	
	canvas.drawString(540, 32*32, "||||CHANCE", STRING::SMALL, STRING::NORMAL);
	
	canvas.drawString(390, 32*32, "Letni", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(392, 32.5*32, "Loop", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(370, 34*32, "Owned by:", STRING::SMALL, STRING::NORMAL);
	canvas.drawString(13*32, 34.5*32, "" + squareOwnerNames[4], STRING::SMALL, centeredText);
	
	canvas.drawString(228, 32*32, "||||JAIL", STRING::SMALL, STRING::NORMAL);

[preview ends here]