Cellblock 2 2.0.0-pre6.sk

Created by BaeFell

Just so you know, we don't know the file format for every file. If it's just a bunch of random characters, it's probably a .zip or .jar.

#===============================================================#
#						_____ ____ ___  						#
#					   / ____|  _ \__ \ 						#
#					  | |	| |_) | ) |							#
#					  | |	|  _ < / / 							#
#					  | |____| |_) / /_ 						#
#					   \_____|____/____|						#
#																#
#	Welcome to Cellblock 2! A complete rewrite of Cellblock		#
#																#
#		skUnity: https://forums.skunity.com/resources/335		#
#		SpigotMC: https://www.spigotmc.org/resources/3564		#
#																#
#===============================================================#
#																#
#	Installing Cellblock:										#
#		For full help on installing Cellblock, please refer		#
#		 to ReadMe.txt which contains full instructions on		#
#		 installing Cellblock, creating CellAddons and more!	#
#																#
#===============================================================#
#																#
#	Permissions: 												#
#		* cellblock.use = General cellblock permission 		    #
#		* cellblock.admin = Used for all admin commands 		#
#																#
#===============================================================#
#																#
#	Requirements:												#
#		Skript: https://forums.skunity.com/resources/323/ 		#
#		skQuery: https://forums.skunity.com/resources/68/		#
#		Skript-Mirror: https://forums.skunity.com/resources/254/#
#																#
#===============================================================#
#																#
#					  Cellblock_2.sk 							#
#						  Authors:								#
#					nfell2009 / BaeFell 						#
#																#
#  Cellblock 2 is © Copyright to [the abovementioned] authors.  #
#  By using and purchasing this system, you are agreeing to		#
#  the License found on the resource page listed above.			#
#						 ============							#
#	 This software is intended for the use of the user who		#
#				 purchased this resource only.					#
#																#
#===============================================================#

# Changed from the default Cellblock options and upgraded?
# You can do /cb options to find your last 5 options versions and restore to them!

options:
#=> Prefixes <==========================#==================================================================================================#
										#
	Header: &4&m----------&r &c&lCellblock &4&m----------------------------
										# Shown at the top of the message block sent to players
	P: &7
										# Prefix colour
	S: &a
										# Successful action
	E: &c
										# Action failed/unsuccessful
	I: &e
										# Highlights information to the player
	M: &d
										# Used for money
	Simple: Cellblock »			
										# Just Cellblock. No colours
										#
	W: &c&lCellblock Warning &7»&c  	
										# Warning prefix
										#
	F: &c&lCellblock Fatal Error &7»&4  
										# Fatal error prefix
										#
	D: &c&lCellblock Debug &7»&e  		
										# Debug prefix
										#
#=> Cell Creation <=====================#==================================================================================================#
										#
	Wand: Stick 						
										# This is the item that you will use when creating Cells via /cb setmode
	RemoveCornerBlocks: true
										# Will set the corner blocks of a cell to air when a cell is created.
										#
#=> Default Values <====================#==================================================================================================#
										#
	DefaultPrice: 100  					
										# Fallback price for Cellblock to create Cells at
										#
	DefaultTime: 1d  					
										# No time given means Cellblock will default to 1 day
										#
	DefaultCellblock: Global			
										# All Cells will be put into "Global"
										# Whenever the block of a Cell is refrenced, it will end with block, eg:
										# "This is Cell 1. It's part of the Global cellblock"
#=> Cell Ownership <====================#==================================================================================================#
										#
	MaxBoughtCells: 100  				
										# How many Cells can a player own at one time? Set to -1 to disable buying Cells
										# To allow for unlimtied ownership, use 0
										#
	MaxRentedCells: 100  				
										# How many Cells can a player rent at one time? Set to -1 to disable buying Cells
										# To allow for unlimtied renting, use 0
										#
	AllowResellingToServer: true		
										# This lets players sell their Cells back to the server. If buying is enabled, but no selling systems
										# are enabled and limits are in place, players will be stuck with the Cell they have
										#
	AllowResellingToOthers: false		
										# If true, players which own a Cell, can put it up for sale to other players. This creates an
										# economy around Cells and can help encourage player spending
										#
	ServerResellReturn: 1				
										# The price the player paid for the Cell will be divided by this amount before being paid to the 
										# seller. Here's some handy values as to what the players get back:
										#  ________________________________________________
										# | Number | Percentage | Cell Price | Player Gets |
										# |‾‾‾‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾‾|
										# |   0    |     0%     |    100     |      0      |
										# |   1    |    100%    |    100     |     100     |
										# |   2    |     50%    |    100     |      50     |
										# |   4    |     25%    |    100     |      25     |
										# |        |            |            |             |
										#  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
										#
#=> Cell Signs <========================#==================================================================================================#
										#
										# You're able to change how the signs that Cellblock uses for Cells look. There are placeholders
										# that will be replaced with the relevant value. As Skript options don't allow for no values,
										# you can use "blank" to have a blank line.
										#
										# Placeholders:
										#	[cellname]  = the name of the Cell
										#	[owner]     = player who owns the Cell
										#	[renter]    = player renting the Cell
										#   [renttime]  = how long a Cell is rentable for
										#	[timeleft]  = how much longer the Cell has left
										#   [rentprice] = price to rent the Cell
										#   [buyprice]  = price to buy the Cell
										#
	RefreshSignsOnLoad: false
										# If you change the sign formats below, they'll only update when they're rented. You can use
										# /cb refresh to refresh the signs or set this to true and Cellblock will do it on load up.
	RemoveSignsOnDelete: false
										# When a Cell has been deleted. Use @RemoveSignsOnDelete to remove the sign instead
	Deleted-1: &7[cellname]
	Deleted-2: &c&lSorry!
	Deleted-3: &7This Cell has
	Deleted-4: &7been deleted
										# When a Cell is available to only be rented
	Rent-1: &7[cellname]
	Rent-2: &d$[rentprice]
	Rent-3: &a[renttime]
	Rent-4: &2Rent Now
										# When a Cell is available to only be bought
	Buy-1: [cellname]
	Buy-2: blank
	Buy-3: &d$[buyprice]
	Buy-4: &2Buy Now
										# When a Cell is available to rented or bought
	RentBuy-1: &7[cellname]
	RentBuy-2: &dRent $[rentprice]
	RentBuy-3: &a[renttime]
	RentBuy-4: &dBuy $[buyprice]
										# When a Cell is currently being rented
	Rented-1: &7[cellname]
	Rented-2: &d[timeleft]
	Rented-3: &6Rented By
	Rented-4: &9[renter]
										# When a Cell has been bought
	Bought-1: &7[cellname]
	Bought-2: blank
	Bought-3: &6Owned By
	Bought-4: &9[owner]
										# How would you like the rent time/time left on signs to appear?
										# Putting a single character will be the single value. For example:
										#	d  = 1
										#	dd = 01
										# Placeholders:
										#	d/dd = day
										#   h/hh = hour
										#	m/mm = minutes
										# If you want to use letters, example showing what each part of the time string means, you put
										# an exclamation mark in front. For example:
										#	dd!dhh!hmm!mss!s will show as 01d07h17m55s
										# !d = d // !h = s // !m = m // !s = s
	TimeOnSignFormat: dd!dhh!hmm!mss!s

	SignClickToRent: right click
										# You can have this value as either left click or right click. This will be used for when a player
										# interacts with a sign. 
	SignClickToBuy: left click
										# The same as SignClickToRent, but this time for buying. Don't let both options have the same value
										# or Cellblock will not work properly!
										#
#=> Cell Teleportation <================#==================================================================================================#
										#
										# IMPORTANT:
										# 	Cellblock makes no attempts of checking if a player should be allowed to teleport. If you
										#	believe there should be some default checks in place, please suggest these to BaeFell. 
										#	Currently, there are none. If you need specific checks then contact BaeFell to get a CellAddon
										#	created which can manage that for you. For example, Combat Tags are ignored unless the plugin
										#	providing the tag is checking for teleportation and cancels it.
										#
	GotoCommandEnabled: true 
										# Players can do /cb goto <cell> and be teleported to that Cell. This location is figured out by
										# Cellblock. The location will be the location of the block in front of the sign that is the
										# closet to location 1 or location 2 of a Cell.
										#
	HomeCommandEnabled: true 
										# This command allows players to do /cb home [1,2,3...]. 
										#
#=> Time Management <===================#==================================================================================================#
										#
	CompensateForDowntime: false		    
										# Cellblock will compensate for server downtime
										# Every minute Cellblock is taking note of the time, when the server loads up,
										# Cellblock will take the difference between the last recorded time and the 
										# current time. That difference will be applied to every actively rented Cellblock
										#
	LoopEvery: second
										# You can swap between Cellblock looping every second or minute to update Cell times. It is less
										# intensive using every minute.
										#
#=> Data Saving <=======================#==================================================================================================#
										#
										# Settings to control how Cellblock will save data
										# The biggest amount of data saving is done by Cell resetting. Cellblock has to store 
										# how the Cell looked to reset it when a user is done. This means Cellblock has to remember all
										# the original locations and blocks of a Cell. Having many Cells will slow down Skript when it
										# loads and will impact your variables.csv size.
										#
										# Cellblock will use the saving system in the order they're listed in. By setting multiple ones
										# to true will just result in Cellblock using the one system. If you change the system, Cellblock
										# will automatically attempt to convert to the other system but will delete old data. You can 
										# disable this in the first option; AutoConvert. You can always use /cb saving convert - which
										# will automatically convert from the old system to the first selected system.
										#
	AutoConvert: true                   
										# Automatically detect and convert old save system data to new save system data. Deletes old data
										#
	TurnOffReset: false 				
										# Cellblock will NOT save any reset data. Cells will stay the same when they expire
										# This might allow players to profit from expired Cells
										#
	UseJsonStorage: true
										# [WARNING! Experimental data saving technique!] => This is new in Cellblock 2
										# [For your information: this storage method is likely the best for cell reset data]
										# Skript's variable storage system can suffer from performance issues when loading a lot of data.
										# Having a lot of cells will create a lot of block data variables. Using JSON is a quicker way
										# of storing cell data. 
										#
	BlocksToLocations: false 		    
										# [WARNING! Experimental data saving technique!] => This is new in Cellblock 2
										# [For your information: there is no data on the performance impact this storage option might have]
										# Instead of Cellblock matching every location to a block for Cell resets; Cellblock
										# will save all locations a block, convert them to a string and then parse it when needed.
										# This will then be saved between server restarts
										# 
	UseCellMapping: false				
										# [WARNING! Experimental data saving technique!] => This is new in Cellblock 2
										# [For your information: cell mapping will likely be better than BlocksToLocations/LocationsToBlocks]
										# Mapping Cells means that Cellblock will attempt to find Cells that have the same
										# default look. This means that Cellblock will save only the Cell to refer to instead
										# of every block in a Cell. This is great for servers using repeating Cells
										# BlocksToLocations overrides UseCellMapping
										#
	LocationsToBlocks: false     		
										# [For your information: LocationsToBlocks is not recommended if you're using a lot of cells]
										# This was how Cellblock originally saved reset data. It'd simply save the locations and the blocks
										# at those locations. When resetting, Cellblock would loop them and reset the Cell. This option 
										# has been optimised to now ignore air and instead loops from the 2 set points instead of looping
										# the data itself. This means Cellblock will just assume if the data doesn't exist, then it's air.
										#
										# Priorities for which method Cellblock will use is how they're listed.
										#	1) TurnOffReset
										#	2) UseJsonStorage
										#	3) BlocksToLocations
										#	4) UseCellMapping
										#	5) LocationsToBlocks
										#
	ProtectExistingBlocks: true         
										# Requires any reset mode to be enabled. Cellblock will protect the blocks of the cell that exist
										# when the Cell was created. This means that players cannot destroy blocks that they didn't place.
										# This should be left as true to prevent people from farming Cells or escaping the prison.
	SaveOptions: true
										# Everytime Cellblock boots up, it'll save the current options setup. This can be restored to later.
										# Cellblock will store the last 5 options to prevent a build up of data. Turning this off will not
										# clear any data.
										# 	Clear any options data: /cb options clear
										# 	Option backups can be viewed by doing: /cb options
										# 	View a specific option by doing: /cb options <id>
										# 	Restore to a specific option by doing: /cb options <id> restore
										#
#=> End of config <=====================#==================================================================================================#
										#
	Debug: false 						
										# Debug mode?
										# This will show more detailed information to console from Cellblock. It is safe to enable debug 
										# when running Cellblock in a live server setting, you'll just have more messages sent to console
										# Debug is intended for when Cellblock is being created or when testing a feature. It won't always
										# give debug information for everything. Only some parts of Cellblock have debug codes
										#

# TODO List:
# - Finish documenting Cellblock to ReadMe
# - Ensure EVERYTHING has come from Cellblock
# - Update Cellblock_Cells_Create_Cell to support:
#   - if the cell name is "cell" to just make it "Cell_<Number>" from the block it's in

import:
	java.nio.file.Files
	java.io.File
	java.lang.System
	java.lang.String
	ch.njol.skript.lang.function.Functions
	ch.njol.skript.lang.ExpressionList
	ch.njol.skript.lang.function.FunctionEvent
	org.bukkit.Bukkit
	org.apache.commons.lang.StringUtils
	ch.njol.skript.util.Timespan
	com.google.gson.JsonArray
	com.google.gson.JsonElement
	com.google.gson.JsonObject
	com.google.gson.JsonParser
	java.io.FileWriter
	java.io.BufferedReader
	java.io.FileReader
	java.io.PrintWriter
	java.lang.StringBuilder
	ch.njol.skript.Skript
	java.io.OutputStreamWriter
	java.io.FileOutputStream
	java.nio.charset.Charset
	java.util.UUID

# Essentials Cellblock functions
# Placed at the top to be loaded first
# (CB:EFUNCTION)/(CB:ESSENTIALS)

# Core

function Cellblock_Debug(msg: string):
	if {@Debug} is true:
		send "[CB2][DEBUG] -> %{_msg}%" to console
		loop all players:
			if {cb2::player::%uuid of loop-player%::debug} is true:
				send "{@D} -> %{_msg}%" to loop-value

function Cellblock_Console(msg: string):
	send {_msg} to console

# File management

function Cellblock_Utilities_Fix_Path(path: string) :: string:
	if System.getProperty("file.separator") is "/":
		return {_path}.replace("\" and "/")
	return {_path}.replace("/" and "\")

function Cellblock_Utilities_File_Exists(path: string) :: boolean:
	return new File(Cellblock_Utilities_Fix_Path({_path})).exists()

function Cellblock_Utilities_Read_File(path: string) :: strings:
	return ...Files.readAllLines(new File(Cellblock_Utilities_Fix_Path({_path})).toPath())

function Cellblock_Utilities_Set_Line(path: string, line: integer, content: text):
	set {_content::*} to Cellblock_Utilities_Read_File(Cellblock_Utilities_Fix_Path({_path}))
	set {_line} to "%{_line}%"
	set {_fw} to try new FileWriter(Cellblock_Utilities_Fix_Path({_path}) and false)
	loop {_content::*}:
		if loop-index is {_line}:
			{_fw}.write({_content})
		else:
			{_fw}.write(loop-value)
		{_fw}.write(System.getProperty("line.separator"))
	{_fw}.close()

function Cellblock_Utilities_Set_Line_UTF(path: string, line: integer, content: text):
	set {_content::*} to Cellblock_Utilities_Read_File(Cellblock_Utilities_Fix_Path({_path}))
	set {_line} to "%{_line}%"
	set {_fw} to new OutputStreamWriter(new FileOutputStream({_path}) and Charset.forName("UTF-8").newEncoder())

	loop {_content::*}:
		if loop-index is {_line}:
			{_fw}.write({_content})
		else:
			{_fw}.write(loop-value)
		{_fw}.write(System.getProperty("line.separator"))
	{_fw}.close()

# Functions

effect (cb|cellblock) call effect function %string% with argument[s] %-objects%:
	trigger:
		if raw exprs-2 is an instance of ExpressionList:
			set {_looped::*} to ...(raw exprs-2).getExpressions()
		else:
			set {_looped::*} to raw exprs-2

		loop {_looped::*}:
			add loop-value.getArray(event) to {_params::*}

		set {_function} to Functions.getFunction(exprs-1)
		set {_event} to new FunctionEvent({_function})
		{_function}.execute({_event} and [{_params::*}])

expression (cb|cellblock) call function %string% with argument[s] %-objects%:
	get:
		if raw exprs-2 is an instance of ExpressionList:
			set {_looped::*} to ...(raw exprs-2).getExpressions()
		else:
			set {_looped::*} to raw exprs-2

		loop {_looped::*}:
			add loop-value.getArray(event) to {_params::*}

		set {_function} to Functions.getFunction(exprs-1)
		set {_event} to new FunctionEvent({_function})
		set {_res} to {_function}.execute({_event} and [{_params::*}])
		if "%{_res}%" is "" or "<none>":
			return {_unset_variable}
		return {_res}

# Sending messages

function Cellblock_Send_Message(player: player, message: text):
	send "" to {_player}
	send "{@Header}" to {_player}
	send "" to {_player}
	send {_message} to {_player}
	send "" to {_player}

function Cellblock_Send_Error(player: player, message: text):
	Cellblock_Send_Message({_player}, "{@E}%{_message}%")

function Cellblock_Send_Success(player: player, message: text):
	Cellblock_Send_Message({_player}, "{@S}%{_message}%")

function Cellblock_API_Send_Message(args: objects):
	replace every "{I}" in {_args::3} with "{@I}"
	replace every "{E}" in {_args::3} with "{@E}"
	replace every "{S}" in {_args::3} with "{@S}"
	replace every "{P}" in {_args::3} with "{@P}"
	replace every "{M}" in {_args::3} with "{@M}"
	replace every "{Header}" in {_args::3} with "{@Header}"
	if {_args::1} is "success":
		Cellblock_Send_Success({_args::2}, {_args::3})
	else if {_args::1} is "error":
		Cellblock_Send_Error({_args::2}, {_args::3})
	else if {_args::1} is "message":
		send "%{_args::3}%" to {_args::2}
	else:
		Cellblock_Send_Message({_args::2}, {_args::3})

function Cellblock_API_Send_Message_2(player: player, message: text, type: text):
	set {_args::*} to {_type}, {_player} and {_message}
	Cellblock_API_Send_Message({_args::*})

# Utilities

function Cellblock_Utilities_String_To_Time(time: string) :: timespan:
	set {_split::*} to {_time} split at ""
	set {_d} to 0
	set {_h} to 0
	set {_m} to 0
	set {_s} to 0
	loop {_split::*}:
		if loop-value is "d":
			set {_d} to {_nu}
			delete {_nu}
		else if loop-value is "h":
			set {_h} to {_nu}
			delete {_nu}
		else if loop-value is "m":
			set {_m} to {_nu}
			delete {_nu}
		else if loop-value is "s":
			set {_s} to {_nu}
			delete {_nu}
		else:
			set {_n} to loop-value parsed as integer
			if {_n} is set:
				if {_nu} is set:
					set {_nu} to "%{_nu}%%{_n}%"
				else:
					set {_nu} to "%{_n}%"
	return "%{_d}% days %{_h}% hours %{_m}% minutes %{_s}% seconds" parsed as timespan

expression:
	return type: number
	patterns:
		day[s] (of|from) %timespan%
	get:
		set {_time} to (expr-1.getTicks()/20)
		set {_d} to rounded down ((({_time}/60)/60)/24) # seconds => minutes => hours => days
		return {_d}

expression:
	return type: number
	patterns:
		hour[s] (of|from) %timespan%
	get:
		set {_time} to (expr-1.getTicks()/20)
		set {_d} to rounded down ((({_time}/60)/60)/24)
		remove {_d}*60*60*24 from {_time}
		set {_h} to rounded down ((({_time}/60)/60))
		return {_h}


expression:
	return type: number
	patterns:
		minute[s] (of|from) %timespan%
	get:
		set {_time} to (expr-1.getTicks()/20)
		set {_d} to rounded down ((({_time}/60)/60)/24)
		remove {_d}*60*60*24 from {_time}
		set {_h} to rounded down ((({_time}/60)/60))
		remove {_h}*60*60 from {_time}
		set {_m} to rounded down ((({_time}/60)))
		return {_m}

expression:
	return type: number
	patterns:
		second[s] (of|from) %timespan%
	get:
		set {_time} to (expr-1.getTicks()/20)
		set {_d} to rounded down ((({_time}/60)/60)/24)
		remove {_d}*60*60*24 from {_time}
		set {_h} to rounded down ((({_time}/60)/60))
		remove {_h}*60*60 from {_time}
		set {_m} to rounded down ((({_time}/60)))
		remove {_m}*60 from {_time}
		set {_s} to rounded down ((({_time})))
		return {_s}

function Cellblock_Utilities_Time_To_String(time: timespan) :: string:
	if days of {_time} is greater than 0:
		set {_r} to "%days of {_time}%d"
	if hours of {_time} is greater than 0:
		set {_r} to "%{_r}%%hours of {_time}%h"
	if minutes of {_time} is greater than 0:
		set {_r} to "%{_r}%%minutes of {_time}%m"
	if seconds of {_time} is greater than 0:
		set {_r} to "%{_r}%%seconds of {_time}%m"
	return {_r}

function Cellblock_Utilities_Time_To_Clock_String(time: timespan, format: string = "not-set") :: string:
	set {_d} to "%days of {_time}%"
	if length of {_d} is 1:
		set {_dd} to "0%{_d}%"
	else:
		set {_dd} to {_d}

	set {_h} to "%hours of {_time}%"
	if length of {_h} is 1:
		set {_hh} to "0%{_h}%"
	else:
		set {_hh} to {_h}

	set {_m} to "%minutes of {_time}%"
	if length of {_m} is 1:
		set {_mm} to "0%{_m}%"
	else:
		set {_mm} to {_m}

	set {_s} to "%seconds of {_time}%"
	if length of {_s} is 1:
		set {_ss} to "0%{_s}%"
	else:
		set {_ss} to {_s}
	if {_format} is "not-set":
		set {_f} to "{@TimeOnSignFormat}"
	else:
		set {_f} to {_format}
	replace every "!d" in {_f} with ":CB-1:"
	replace every "!h" in {_f} with ":CB-2:"
	replace every "!m" in {_f} with ":CB-3:"
	replace every "!s" in {_f} with ":CB-4:"
	replace every "dd" in {_f} with "%{_dd}%"
	replace every "d" in {_f} with "%{_d}%"
	replace every "hh" in {_f} with "%{_hh}%"
	replace every "h" in {_f} with "%{_h}%"
	replace every "mm" in {_f} with "%{_mm}%"
	replace every "m" in {_f} with "%{_m}%"
	replace every "ss" in {_f} with "%{_ss}%"
	replace every "s" in {_f} with "%{_s}%"
	replace every ":CB-1:" in {_f} with "d"
	replace every ":CB-2:" in {_f} with "h"
	replace every ":CB-3:" in {_f} with "m"
	replace every ":CB-4:" in {_f} with "s"
	return {_f}

function Cellblock_Utilities_Zero_Seconds(time: timespan) :: timespan:
	Cellblock_Debug("%days of {_time}% %hours of {_time}% %minutes of {_time}% 0 seconds")
	return "%days of {_time}% %hours of {_time}% %minutes of {_time}% 0 seconds" parsed as timespan

function Cellblock_Utilities_Parse_Cellblock_Location(locations: string, cell: string) :: location:
	set {_coords::*} to {_locations} split at ":"
	set {_location} to location at (0, 0, 0) in world "world"
	loop {_coords::*}:
		set {_coords::%loop-index%} to loop-value parsed as number
	set x coord of {_location} to {_coords::1}
	set y coord of {_location} to {_coords::2}
	set z coord of {_location} to {_coords::3}
	set world of {_location} to {cb2::cells::%{_cell}%::world}
	return {_location}

function Cellblock_Utilities_Block_Behind(source: block) :: block:
	set {_facing} to facing of {_source}
	if {_facing} is not set:
		return block behind {_source}
	else if {_facing} is north:
		return block south of {_source}
	else if {_facing} is east:
		return block west of {_source}
	else if {_facing} is south:
		return block north of {_source}
	else if {_facing} is west:
		return block east of {_source}
	else if {_facing} is above:
		return block below {_source}
	else if {_facing} is below:
		return block above {_source}
	else:
		return {_source}

function Cellblock_Utilities_Block_In_Front(source: block) :: block:
	set {_facing} to facing of {_source}
	if {_facing} is not set:
		return block in front of {_source}
	else if {_facing} is north:
		return block north of {_source}
	else if {_facing} is east:
		return block east of {_source}
	else if {_facing} is south:
		return block south {_source}
	else if {_facing} is west:
		return block west of {_source}
	else if {_facing} is above:
		return block above {_source}
	else if {_facing} is below:
		return block below {_source}

function Cellblock_Utilities_Block_In_Direction(source: block, dire: direction) :: block:
	set {_location} to location of {_source}
	if {_dire} is north:
		subtract 1 from z coord of {_location}
	else if {_dire} is east:
		add 1 to x coord of {_location}
	else if {_dire} is south:
		add 1 to z coord of {_location}
	else if {_dire} is west:
		subtract 1 from x coord of {_location}
	else if {_dire} is above:
		add 1 to y coord of {_location}
	else if {_dire} is below:
		subtract 1 from y coord of {_location}
	return block at {_location}

function Cellblock_Utilities_Cell_At_Location(l: location) :: string:
	if {cb2::celldata::locs::%{_l}%} is set:
		return {cb2::celldata::locs::%{_l}%}

function Cellblock_Utilities_Cell_At_Player(p: player) :: string:
	set {_loc} to location of block above block below {_p}
	if {cb2::celldata::locs::%{_loc}%} is set:
		return {cb2::celldata::locs::%{_loc}%}

# Cellblock API Functions
# Placed at the top as Cellblock utiltises its own API
# (CB:API)

# Sets the Help command's data for the description
function Cellblock_API_Help_Registry_Description(command: string, description: string):
	set {cb2::api::commands::%{_command}%::description} to {_description}

# Shown to the user when doing /cb help <command>
function Cellblock_API_Help_Registry_Pattern(command: string, pattern: string):
	set {cb2::api::commands::%{_command}%::pattern} to {_pattern}

# Explains each part of the command pattern
function Cellblock_API_Help_Register_Pattern_Explained(command: string, explained: string):
	set {cb2::api::commands::%{_command}%::explained::*} to {_explained} split at "//"

function Cellblock_API_Help_Register_Examples(command: string, examples: string):
	set {cb2::api::commands::%{_command}%::examples::*} to {_examples} split at "//"

# Register a new command for Cellblock
#	Note: only 1 sub-command can exist a time
#
#	command:	string // the sub-command to be register
#	function:	string // the function to be called when the command is ran
#	permission: string // a permission to use the command. defaults to cellblock.command which is the same as the /cb command
function Cellblock_API_Register_Command(command: string, function: string, permission: string = "cellblock.command"):
	set {cb2::api::commands::%{_command}%} to {_command}
	set {cb2::api::commands::%{_command}%::command} to {_command}
	set {cb2::api::commands::%{_command}%::function} to {_function}
	if {_permission} is "admin":
		set {_permission} to "cellblock.command.admin"
	else if {_permission} is "default":
		set {_permission} to "cellblock.command"
	set {cb2::api::commands::%{_command}%::permission} to {_permission}
	Cellblock_Debug("{@Simple} Registered a command:")
	Cellblock_Debug("{@Simple}	 Command: %{_command}%")
	Cellblock_Debug("{@Simple}	 Function: %{_function}%")
	Cellblock_Debug("{@Simple}	 Permission: %{_permission}%")

# Register an event listener for Cellblock
#
#	event:	string  // a valid event string 
#	function: string  // the function to be called when an event happens
#	override: boolean // should this override any existing event listeners? There can only be 1 overriding listener. Defaults to false.
function Cellblock_API_Register_Listener(event: string, function: string, override: boolean = false):
	if {_override} is true:
		delete {cb2::api::listeners::%{_event}%::*}
	set {cb2::api::listeners::%{_event}%::%{_function}%} to {_function}
	Cellblock_Debug("{@Simple} Registered an event listener:")
	Cellblock_Debug("{@Simple}	Event: %{_event}%")
	Cellblock_Debug("{@Simple}	Function: %{_function}%")
	Cellblock_Debug("{@Simple}	Override: %{_override}%")

function Cellblock_API_Fire_Event(event: string, args: objects, source: string = "Unknown") :: boolean:
	Cellblock_Debug("%{_event}% has been fired from %{_source}% Listeners (%size of {cb2::api::listeners::%{_event}%::*}%): %{cb2::api::listeners::%{_event}%::*}%")
	loop {cb2::api::listeners::%{_event}%::*}:
		if {_continue} is not set:
			set {_continue} to cellblock call function loop-value with arguments {_args::*} and {_source}
		else:
			cellblock call function loop-value with arguments {_args::*} and {_source}
	Cellblock_Debug("Continue result: %{_continue}% (Class: %{_continue}.getClass()%)")
	if {_continue} is not set:
		return true
	if "%{_continue}%" is "true":
		return true
	if "%{_continue}%" is "false":
		return false
	return true

function Cellblock_API_Reload_Helper(script: string):
	set {cb2::reload::%{_script}%} to {_script}
	Cellblock_Debug("%{_script}% has set to be reloaded when Cellblock is")

function Cellblock_API_Parse_CBTags(path: string):
	if Cellblock_Utilities_File_Exists({_path}) is true:
		set {_lines::*} to Cellblock_Utilities_Read_File({_path})
		loop {_lines::*}:
			if {_register::currentlyIn} is set:
				loop {_structure::*}:
					if loop-value-1.startsWith("## => %StringUtils.capitalize(loop-index-2)%"):
						set {_split::*} to loop-value-1 split at " => %StringUtils.capitalize(loop-index-2)%: "
						# 1 = #
						# 2 = value
						set {_cbtag::%loop-index-2%} to {_split::2}

			# Commands
			if loop-value is "## => CBTag Register Command - Start":
				delete {_structure::*}
				delete {_register::*}
				set {_register::line defined} to loop-index
				set {_register::currentlyIn} to "command"

				set {_structure::command} to true
				set {_structure::function} to true
				set {_structure::permission} to false
				set {_structure::permission::default} to "cellblock.command"

				set {_structure::help-description} to false
				set {_structure::help-pattern} to false
				set {_structure::help-pattern-explained} to false
				set {_structure::help-examples} to false
			else if loop-value is "## => CBTag Register Event Listener - Start":
				delete {_structure::*}
				delete {_register::*}
				set {_register::line defined} to loop-index
				set {_register::currentlyIn} to "event"

				set {_structure::event} to true
				set {_structure::function} to true
				set {_structure::override} to false
				set {_structure::override::default} to false
			else if loop-value is "## => CBTag Register - End":
				loop {_structure::*}:
					if loop-value-2 is true:
						if {_cbtag::%loop-index-2%} is not set:
							Cellblock_Debug("While reading the CBTags of file located at '%{_path}%', %{_register::currentlyIn}% tags were found but weren't complete!")
							Cellblock_Debug("=> Line defined: %{_register::line defined}%")
							Cellblock_Debug("=> Missing required value: %loop-index-2%")
							Cellblock_Debug("=> Set values:")
							loop {_cbtag::*}:
								Cellblock_Debug("==> %loop-index-3%: %loop-value-3%")
							set {_failed} to true
					else:
						if {_cbtag::%loop-index-2%} is not set:
							if {_structure::%loop-index-2%::default} is set:
								set {_cbtag::%loop-index-2%} to {_structure::%loop-index-2%::default}
							else:
								set {_cbtag::%loop-index-2%} to ""
				if {_failed} is not set:
					if {_register::currentlyIn} is "command":
						Cellblock_API_Register_Command({_cbtag::command}, {_cbtag::function}, {_cbtag::permission})
						if {_cbtag::help-description} is not "":
							Cellblock_API_Help_Registry_Description({_cbtag::command}, {_cbtag::help-description})
						if {_cbtag::help-pattern} is not "":
							Cellblock_API_Help_Registry_Pattern({_cbtag::command}, {_cbtag::help-pattern})
						if {_cbtag::help-pattern-explained} is not "":
							Cellblock_API_Help_Register_Pattern_Explained({_cbtag::command}, {_cbtag::help-pattern-explained})
						if {_cbtag::help-examples} is not "":
							Cellblock_API_Help_Register_Examples({_cbtag::command}, {_cbtag::help-examples})
					else if {_register::currentlyIn} is "event":
						Cellblock_API_Register_Listener({_cbtag::event}, {_cbtag::function}, {_cbtag::override})
				delete {_failed}
				delete {_structure::*}
				delete {_register::*}
	else:
		Cellblock_Debug("Tried to read the CBTags of file located at '%{_path}%', but that file doesn't exist!")

# Cellblock Utils - Commands
# (CB:UTILCMD)

function Cellblock_API_Execute_Command(command: string, player: player, args: strings):
	Cellblock_Debug("Executing: %{_command}% // %{_player}% // %{_args::*}% // %{cb2::api::commands::%{_command}%::function}%")
	if {cb2::api::commands::%{_command}%::command} is set:
		set {_function} to {cb2::api::commands::%{_command}%::function}
		cellblock call function {_function} with arguments {_player} and {_args::*}
	else:
		Cellblock_Console("{@Simple} Attempted to execute the command '%{_command}%' but it isn't a registered command")

# Cellblock Utils - Cellblocks
# (CB:UTILCELLBLOCK)
	
function Cellblock_Cellblocks_Block_Exists(block: string) :: boolean:
	if {cb2::cellblocks::%{_block}%} is set:
		return true
	else:
		return false

function Cellblock_Cellblocks_Get_Block(block: string) :: strings:
	return {cb2::cellblocks::%{_block}%::*}

function Cellblock_Cellblocks_Add_To_Block(block: string, cell: string) :: strings:
	return {cb2::cellblocks::%{_block}%::%{_cell}%}

function Cellblock_Cellblocks_Create_Block(block: string):
	set {cb2::cellblocks::%{_block}%} to {_block}

function Cellblock_Cellblocks_Delete_Block(block: string):
	delete {cb2::cellblocks::%{_block}%}

# Cellblock Utils - Cell Signs

										# When a Cell is available to only be rented
#	Rent-1: &7[cellname]
#	Rent-2: &d$[rentprice]
#	Rent-3: &a[renttime]
#	Rent-4: &2Rent Now
#										# When a Cell is available to only be bought
#	Buy-1: [cellname]
#	Buy-2: blank
#	Buy-3: &d$[buyprice]
#	Buy-4: &2Buy Now
#										# When a Cell is available to rented or bought
#	RentBuy-1: &7[cellname]
#	RentBuy-2: &dRent $[rentprice]
#	RentBuy-3: &a[renttime]
#	RentBuy-4: &dBuy $[buyprice]
#										# When a Cell is currently being rented
#	Rented-1: &7[cellname]
#	Rented-2: &d[renttime]
#	Rented-3: &6Rented By
#	Rented-4: &9[renter]
#										# When a Cell has been bought
#	Bought-1: &7[cellname]
#	Bought-2: blank
#	Bought-3: &6Owned By
#	Bought-4: &9[owner]
#	Bought-4: [owner]

#	[cellname]  = the name of the Cell
#	[owner]     = player who owns the Cell
#	[renter]    = player renting the Cell
#   [renttime]  = how long a Cell is rentable for
#	[timeleft]  = how much longer the Cell has left
#   [rentprice] = price to rent the Cell
#   [buyprice]  = price to buy the Cell


# Add a sign to a Cell so it can be updated, uses location not the block itself
function Cellblock_Cells_Add_Sign(cell: string, loc: location):
	Cellblock_Debug("Adding sign to %{_cell}%. The block is %block at {_loc}% and is located at %{_loc}%")
	set {cb2::cells::%{_cell}%::signs::%{_loc}%} to {_loc}
	set {cb2::celldata::signs::%{_loc}%} to {_cell}
	Cellblock_Debug("Block at loc is a %block at {_loc}%")
	if block at {_loc} is any wall sign:
		set {_oloc} to Cellblock_Utilities_Block_Behind(block at {_loc})
		set {_oloc} to location of {_oloc}
		set {cb2::celldata::signbacks::%{_oloc}%} to {_cell}
		Cellblock_Debug("oloc: %{_oloc}%")
		Cellblock_Debug("Adding the signback for the sign. Block behind: %Cellblock_Utilities_Block_Behind(block at {_loc})%. Saved variable value %{cb2::celldata::signbacks::%{_oloc}%}%")
	else:
		set {_oloc} to location of block below block at {_loc}
		set {cb2::celldata::signbacks::%{_oloc}%} to {_loc}
	# just making sure to update the goto location when new signs are added or deleted
	delete {cb2::celldata::cells::%{_cell}%::goto}

# Sets the inputted line of every sign of a Cell
function Cellblock_Cells_Set_Sign(cell: string, line: integer, text: string):
	replace every "[cellname]" in {_text} with "%{_cell}%"
	replace every "[owner]" in {_text} with "%player from {cb2::cells::%{_cell}%::owner}%"
	replace every "[renter]" in {_text} with "%player from {cb2::cells::%{_cell}%::renter}%"
	replace every "[renttime]" in {_text} with Cellblock_Utilities_Time_To_Clock_String({cb2::cells::%{_cell}%::time})
	replace every "[timeleft]" in {_text} with Cellblock_Utilities_Time_To_Clock_String({cb2::cells::%{_cell}%::expires})
	replace every "[rentprice]" in {_text} with "%{cb2::cells::%{_cell}%::rent-price}%"
	replace every "[buyprice]" in {_text} with "%{cb2::cells::%{_cell}%::buy-price}%"
	if {_text} is "blank":
		set {_text} to ""
	#Cellblock_Debug("Setting line %{_line}% of %{_cell}% to %{_text}%")
	loop {cb2::cells::%{_cell}%::signs::*}:
		#Cellblock_Debug("%block at loop-value%")
		set line {_line} of block at loop-value to "%{_text}%"

# Updates a sign to whatever its correct values are
function Cellblock_Cells_Update_Sign(cell: string):
	if {cb2::cells::%{_cell}%::deleting} is set:
		Cellblock_Cells_Set_Sign({_cell}, 1, "{@Deleted-1}")
		Cellblock_Cells_Set_Sign({_cell}, 2, "{@Deleted-2}")
		Cellblock_Cells_Set_Sign({_cell}, 3, "{@Deleted-3}")
		Cellblock_Cells_Set_Sign({_cell}, 4, "{@Deleted-4}")
	else if {cb2::cells::%{_cell}%::rented} is true:
		# Cell is currently being rented
		Cellblock_Cells_Set_Sign({_cell}, 1, "{@Rented-1}")
		Cellblock_Cells_Set_Sign({_cell}, 2, "{@Rented-2}")
		Cellblock_Cells_Set_Sign({_cell}, 3, "{@Rented-3}")
		Cellblock_Cells_Set_Sign({_cell}, 4, "{@Rented-4}")
	else if {cb2::cells::%{_cell}%::bought} is true:
		# Cell has been bought, but shows renting over buying
		Cellblock_Cells_Set_Sign({_cell}, 1, "{@Bought-1}")
		Cellblock_Cells_Set_Sign({_cell}, 2, "{@Bought-2}")
		Cellblock_Cells_Set_Sign({_cell}, 3, "{@Bought-3}")
		Cellblock_Cells_Set_Sign({_cell}, 4, "{@Bought-4}")
	else if {cb2::cells::%{_cell}%::rentable} is true:
		# Cell can be rented or bought
		if {cb2::cells::%{_cell}%::buyable} is true:
			# Cell can be rented and bought
			Cellblock_Cells_Set_Sign({_cell}, 1, "{@RentBuy-1}")
			Cellblock_Cells_Set_Sign({_cell}, 2, "{@RentBuy-2}")
			Cellblock_Cells_Set_Sign({_cell}, 3, "{@RentBuy-3}")
			Cellblock_Cells_Set_Sign({_cell}, 4, "{@RentBuy-4}")
		else:
			# Cell can be rented
			Cellblock_Cells_Set_Sign({_cell}, 1, "{@Rent-1}")
			Cellblock_Cells_Set_Sign({_cell}, 2, "{@Rent-2}")
			Cellblock_Cells_Set_Sign({_cell}, 3, "{@Rent-3}")
			Cellblock_Cells_Set_Sign({_cell}, 4, "{@Rent-4}")
	else if {cb2::cells::%{_cell}%::buyable}:
		# Cell can be bought
		Cellblock_Cells_Set_Sign({_cell}, 1, "{@Buy-1}")
		Cellblock_Cells_Set_Sign({_cell}, 2, "{@Buy-2}")
		Cellblock_Cells_Set_Sign({_cell}, 3, "{@Buy-3}")
		Cellblock_Cells_Set_Sign({_cell}, 4, "{@Buy-4}")
	else:
		Cellblock_Debug("Invalid state for: %{_cell}%")

# Cellblock Utils - Cells
# (CB:UTILCELLS)
	
function Cellblock_Cells_Cell_Exists(cell: string) :: boolean:
	if {cb2::cells::%{_cell}%::cell} is set:
		return true
	else:
		return false

function Cellblock_Cells_Is_Mapped(cell: string) :: boolean:
	if {cb2::cells::%{_cell}%::mapped::status} is true:
		return true
	else:
		return false

function Cellblock_Cells_Map_Cell(cell: string):
	set {_blocks::*} to blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}
	delete {cb2::cells::%{_cell}%::reset::mapped::*}
	loop {cb2::cells::*}:
		if loop-value is not {_cell}: # dont map to the cell wanting to be mapped
			loop {cb2::cells::*}:
				if {cb2::cells::%loop-value-2%::reset::mapped::cell} is {_cell}:
					set {_dontMap} to true
			if {_dontMap} is not set:
				if {cb2::cells::%loop-value%::reset::mapped::cell} is not set: # dont map to a cell using another cell as a map, find the original cell. So instead of it being cell1 -> cell2 -> cell3, it's goes cell1 -> cell 2; cell1 -> cell3
					set {_c} to 0
					loop blocks within {cb2::cells::%loop-value%::loc1} to {cb2::cells::%loop-value%::loc2}:
						add 1 to {_c}
						if {_blocks::%{_c}%} is not type of loop-block:
							set {_failed} to true
							exit loop
					if {_failed} is not set:
						set {cb2::cells::%{_cell}%::reset::mapped::status} to true
						set {cb2::cells::%{_cell}%::reset::mapped::cell} to loop-value
						stop
					delete {_failed}
	if {cb2::cells::%{_cell}%::reset::mapped::status} is not set: # sets the reset data for the cell as no matching ones found
		set {cb2::cells::%{_cell}%::reset::mapped::status} to true
		loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
			if loop-block is not air:
				set {cb2::cells::%{_cell}%::reset::ltb::locs::%location of loop-block%} to location of loop-block
				set {cb2::cells::%{_cell}%::reset::ltb::blocks::%location of loop-block%} to type of loop-block

# Cellblock Utils - Files
# (CB:FILES)

function Cellblock_Utils_Files_Write(file: object, content: text):
	set {_writer} to new FileWriter({_file})
	{_writer}.write({_content})
	{_writer}.close()

# Cellblock Utils - JSON
# (CB:JSON)

function Cellblock_JSON_Create():
	Cellblock_Debug("Cellblock_JSON_Create ran")
	set {_file} to new File("%{cb2::cellblock::data::path}%cells.json")
	{_file}.createNewFile()
	set {cb2::cellblock::json::cells} to {_file}
	Cellblock_Debug("Cellblock_JSON_Create Finished")

function Cellblock_JSON_Load():
	Cellblock_Debug("Cellblock_JSON_Load ran")
	delete {cb2::cellblock::json::loaded}
	set {_filecontentarray::*} to Cellblock_Utilities_Read_File({cb2::cellblock::json::cells}.getPath())
	set {_filecontent} to join {_filecontentarray::*} using ""
	if {_filecontent} is not set:
		set {_parsed} to new JsonObject()
	else:
		set {_parsed} to new JsonParser().parse({_filecontent}).getAsJsonObject()
	set {cb2::celldata::json::parsed} to {_parsed}
	Cellblock_Debug("Cellblock_JSON_Load Finished")

function Cellblock_JSON_Serialise_Cell(cell: string):
	set {_array} to new JsonArray()
	loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
		if loop-block is not air:
			set {cb2::celldata::cells::%{_cell}%::reset::locations::%location of loop-block%} to location of loop-block
			set {cb2::celldata::cells::%{_cell}%::reset::blocks::%location of loop-block%} to type of loop-block

			set {_data} to new JsonObject()
			{_data}.addProperty("x" and "%x coord of loop-block%")
			{_data}.addProperty("y" and "%y coord of loop-block%")
			{_data}.addProperty("z" and "%z coord of loop-block%")
			{_data}.addProperty("b" and "%type of loop-block%")
			{_array}.add({_data})

	set {cb2::json::to-save::%{_cell}%} to {_array}

function Cellblock_JSON_Unserialise_Cell(cell: string):
	if {cb2::celldata::json::parsed}.has({_cell}) is true:
		if {cb2::celldata::json::parsed}.get({_cell}).has("reset") is true:
			set {_celldata::*} to ...{cb2::celldata::json::parsed}.get({_cell}).get("reset")
			set {_c} to 0
			loop {_celldata::*}:
				set {_x} to loop-value.get("x").getAsDouble()
				set {_y} to loop-value.get("y").getAsDouble()
				set {_z} to loop-value.get("z").getAsDouble()
				set {_l} to location({_x}, {_y}, {_z}, {cb2::cells::%{_cell}%::world})
				set {_i} to loop-value.get("b").getAsString() parsed as item type
				set {cb2::celldata::cells::%{_cell}%::reset::locations::%{_l}%} to {_l}
				set {cb2::celldata::cells::%{_cell}%::reset::blocks::%{_l}%} to {_i}
			Cellblock_Debug("Unserialed the cell: %{_cell}%")

function Cellblock_JSON_Save():
	if {@UseJsonStorage} is not true:
		stop

	Cellblock_Debug("Starting to save JSON data to file...")

	loop {cb2::json::to-save::*}:
		if {cb2::celldata::json::parsed}.has(loop-index):
			set {_cell_obj} to {cb2::celldata::json::parsed}.get(loop-index)
		else:
			set {_cell_obj} to new JsonObject()
		{_cell_obj}.add("reset" and loop-value)
		{cb2::celldata::json::parsed}.add(loop-index and {_cell_obj})
	delete {cb2::json::to-save::*}
	Cellblock_Utils_Files_Write({cb2::cellblock::json::cells} and {cb2::celldata::json::parsed}.toString())

	Cellblock_Debug("JSON has been saved!")

function Cellblock_JSON_Delete_Cell(cell: string):
	if {cb2::celldata::json::parsed}.has({_cell}) is true:
		{cb2::celldata::json::parsed}.remove({_cell})

		Cellblock_Utils_Files_Write({cb2::cellblock::json::cells} and {cb2::celldata::json::parsed}.toString())

every 10 minutes:
	Cellblock_JSON_Save()

# Saves the reset blocks to the CellData variables
function Cellblock_Cells_Set_Reset(cell: string):
	delete {cb2::celldata::cells::%{_cell}%::reset::*}
	Cellblock_Debug("Cellblock_Cells_Set_Reset(%{_cell}%) ran. reset-type: %{cb2::cells::%{_cell}%::reset-type}%")
	if {cb2::cells::%{_cell}%::reset-type} is "UseJsonStorage":
		Cellblock_JSON_Unserialise_Cell({_cell})
	else if {cb2::cells::%{_cell}%::reset-type} is "BlocksToLocations":
		loop {cb2::cells::%{_cell}%::reset::btl::blocks::*}:
			set {_allCoords::*} to loop-value split at ";"
			loop {_allCoords::*}:
				set {_location} to Cellblock_Utilities_Parse_Cellblock_Location(loop-value-2, {_cell})
				set {_item} to loop-index-1 parsed as itemtype
				set {cb2::celldata::cells::%{_cell}%::reset::locations::%{_location}%} to {_location}
				set {cb2::celldata::cells::%{_cell}%::reset::blocks::%{_location}%} to {_item}
		set {cb2::cells::%{_cell}%::reset-type} to "BlocksToLocations"
	else if {cb2::cells::%{_cell}%::reset-type} is "CellMapping":
		if {cb2::cells::%{_cell}%::reset::mapped::status} is true:
			if {cb2::cells::%{_cell}%::reset::mapped::cell} is not set:
				# not mapped, falls back to location to block
				loop {cb2::cells::%{_cell}%::reset::ltb::locs::*}:
					set {cb2::celldata::cells::%{_cell}%::reset::locations::%loop-value%} to loop-value
					set {cb2::celldata::cells::%{_cell}%::reset::blocks::%loop-value%} to {cb2::cells::%{_cell}%::reset::ltb::blocks::%loop-value%}
			else:
				# it is mapped!
				loop {cb2::cells::%{cb2::cells::%{_cell}%::reset::mapped::cell}%::reset::ltb::locs::*}:
					set {cb2::celldata::cells::%{_cell}%::reset::locations::%loop-value%} to loop-value
					set {cb2::celldata::cells::%{_cell}%::reset::blocks::%loop-value%} to {cb2::cells::%{cb2::cells::%{_cell}%::reset::mapped::cell}%::reset::ltb::blocks::%loop-value%}
		else:
			# cell mapping is enabled but it's not mapped?
			Cellblock_Cells_Map_Cell({_cell})
			Cellblock_Cells_Set_Reset({_cell})
	else if {cb2::cells::%{_cell}%::reset-type} is "LocationsToBlocks":
		loop {cb2::cells::%{_cell}%::reset::ltb::locs::*}:
			set {cb2::celldata::cells::%{_cell}%::reset::locations::%loop-value%} to loop-value
			set {cb2::celldata::cells::%{_cell}%::reset::blocks::%loop-value%} to {cb2::cells::%{_cell}%::reset::ltb::blocks::%loop-value%}

# Saves the current blocks of a Cell to the cell itself. This data won't be deleted between restarts
function Cellblock_Cells_Save_Reset(cell: string):
	if {cb2::cellblock::last-save-system} is "TurnOffReset":
		set {cb2::cells::%{_cell}%::reset-type} to "TurnOffReset"
	else if {cb2::cellblock::last-save-system} is "CellMapping":
		set {cb2::cells::%{_cell}%::reset-type} to "CellMapping"
		Cellblock_Cells_Map_Cell({_cell})
	else if {cb2::cellblock::last-save-system} is "UseJsonStorage":
		set {cb2::cells::%{_cell}%::reset-type} to "UseJsonStorage"
		Cellblock_JSON_Serialise_Cell({_cell})
	else:
		loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
			if loop-block is not air:
				set {cb2::celldata::cells::%{_cell}%::locs::%location of loop-value%} to location of loop-value
				set {cb2::celldata::cells::%{_cell}%::blocks::%location of loop-value%} to type of loop-value
				if {cb2::cellblock::last-save-system} is "BlocksToLocations":
					set {_b} to "%type of loop-value%"
					if {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} is set:
						set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%{cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%}%;%x coord of location of loop-value%:%y coord of location of loop-value%:%z coord of location of loop-value%"
					else:
						set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%x coord of location of loop-value%:%y coord of location of loop-value%:%z coord of location of loop-value%"
				else if loop-block is not air:
					set {cb2::cells::%{_cell}%::reset::ltb::locs::%location of loop-block%} to location of loop-block
					set {cb2::cells::%{_cell}%::reset::ltb::blocks::%location of loop-block%} to type of loop-block
		if {cb2::cellblock::last-save-system} is "BlocksToLocations":
			set {cb2::cells::%{_cell}%::reset-type} to "BlocksToLocations"
		else:
			set {cb2::cells::%{_cell}%::reset-type} to "LocationsToBlocks"

function Cellblock_Cells_Save_Convert(to: string):
	loop {cb2::cells::*}:
		set {_cell} to loop-value
		if {cb2::cells::%{_cell}%::reset-type} is not set:
			set {cb2::cells::%{_cell}%::reset-type} to {_to}
		if {cb2::cells::%{_cell}%::reset-type} is "CellMapping":
			delete {cb2::cells::%{_cell}%::reset::mapped::*}
		if {cb2::cells::%{_cell}%::reset-type} is "TurnOffReset": # no reset data to convert too, so creating new ones
			if {_to} is "BlocksToLocations":
				set {cb2::cells::%{_cell}%::reset-type} to "BlocksToLocations"
				loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
					set {_b} to "%type of loop-value-2%"
					if {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} is set:
						set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%{cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%}%;%x coord of location of loop-value-2%:%y coord of location of loop-value-2%:%z coord of location of loop-value-2%"
					else:
						set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%x coord of location of loop-value-2%:%y coord of location of loop-value-2%:%z coord of location of loop-value-2%"
			else if {_to} is "CellMapping":
				set {cb2::cells::%{_cell}%::reset-type} to "CellMapping"
				Cellblock_Cells_Map_Cell({_cell})
			else if {_to} is "LocationsToBlocks":
				set {cb2::cells::%{_cell}%::reset-type} to "LocationsToBlocks"
				loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
					if loop-block is not air:
						set {cb2::cells::%{_cell}%::reset::ltb::locs::%location of loop-block%} to location of loop-block
						set {cb2::cells::%{_cell}%::reset::ltb::blocks::%location of loop-block%} to type of loop-block
			else if {_to} is "UseJsonStorage":
				set {cb2::cells::%{_cell}%::reset-type} to "UseJsonStorage"
				loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
					if loop-block is not air:
						set {cb2::cells::%{_cell}%::reset::ltb::locs::%location of loop-block%} to location of loop-block
						set {cb2::cells::%{_cell}%::reset::ltb::blocks::%location of loop-block%} to type of loop-block
		else if {_to} is "TurnOffReset": # deleting any reset data
			delete {cb2::cells::%{_cell}%::reset::*}
			delete {cb2::celldata::cells::%{_cell}%::reset::*}
			set {cb2::cells::%{_cell}%::reset-type} to "TurnOffReset"
		else if {_to} is "UseJsonStorage":
			Cellblock_Cells_Set_Reset({_cell})
			set {cb2::cells::%{_cell}%::reset-type} to "UseJsonStorage"
			Cellblock_JSON_Serialise_Cell({_cell})
		else if {_to} is "BlocksToLocations":
			Cellblock_Cells_Set_Reset({_cell})
			set {cb2::cells::%{_cell}%::reset-type} to "BlocksToLocations"
			loop {cb2::celldata::cells::%{_cell}%::reset::locations::*}:
				set {_b} to {cb2::celldata::cells::%{_cell}%::reset::block::%loop-value-2%}
				if {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} is set:
					set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%{cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%}%;%x coord of location of loop-value-2%:%y coord of location of loop-value-2%:%z coord of location of loop-value-2%"
				else:
					set {cb2::cells::%{_cell}%::reset::btl::blocks::%{_b}%} to "%x coord of location of loop-value-2%:%y coord of location of loop-value-2%:%z coord of location of loop-value-2%"
		else if {_to} is "CellMapping": # Changing to Cell Mapping has its own function
			set {cb2::cells::%{_cell}%::reset-type} to "CellMapping"
			Cellblock_Cells_Map_Cell({_cell})
		else if {_to} is "LocationsToBlocks":
			Cellblock_Cells_Set_Reset({_cell})
			set {cb2::cells::%{_cell}%::reset-type} to "LocationsToBlocks"
			loop {cb2::celldata::cells::%{_cell}%::reset::locations::*}:
				set {cb2::cells::%{_cell}%::reset::ltb::locs::%loop-value-2%} to loop-value-2
				set {cb2::cells::%{_cell}%::reset::ltb::blocks::%loop-value-2%} to {cb2::celldata::cells::%{_cell}%::reset::block::%loop-value-2%}		
	loop {cb2::cells::*}:
		Cellblock_Cells_Set_Reset(loop-value)

#
#	Function to create a cell
#
#		buyable/rentable never change (true/false)
#		bought/rented change when bought or rented (true/false)
#		owner when created, server, when owned, uuid of player
#		renter when created, not set, when rented, uuid of player
#
function Cellblock_Cells_Create_Cell(loc1: location, loc2: location, cell: string, price: number, time: timespan, cellblock: string, buyprice: number):
	set {cb2::cells::%{_cell}%} to {_cell}
	set {cb2::cells::%{_cell}%::cell} to {_cell}
	set {cb2::cells::%{_cell}%::world} to world of {_loc1}
	if {@RemoveCornerBlocks} is true:
		set block at {_loc1} to air
		set block at {_loc2} to air
	set {cb2::cells::%{_cell}%::loc1} to {_loc1}
	set {cb2::cells::%{_cell}%::loc2} to {_loc2}
	set {cb2::cells::%{_cell}%::rentable} to false
	set {cb2::cells::%{_cell}%::buyable} to false
	set {cb2::cells::%{_cell}%::owner} to "server"
	if {_buyprice} is greater than 0:
		set {cb2::cells::%{_cell}%::buyable} to true
		set {cb2::cells::%{_cell}%::bought} to false
		set {cb2::cells::%{_cell}%::buy-price} to {_buyprice}
	if {_price} is greater than 0:
		set {cb2::cells::%{_cell}%::rentable} to true
		set {cb2::cells::%{_cell}%::rented} to false
		set {cb2::cells::%{_cell}%::rent-price} to {_price}
		set {cb2::cells::%{_cell}%::time} to {_time}
	Cellblock_Debug("Cell %{_cell}%, has %{_time}% provided")
	if {_time} is 0 days:
		if {_price} is greater than 0:
			set {_nprice} to {_price}
		else if {_buyprice} is greater than 0:
			set {_nprice} to {_buyprice}
		if {_nprice} is set:
			set {cb2::cells::%{_cell}%::buyable} to true
			set {cb2::cells::%{_cell}%::bought} to false
			set {cb2::cells::%{_cell}%::buy-price} to {_nprice}
	set {cb2::cells::%{_cell}%::price} to {_price}
	set {cb2::cells::%{_cell}%::cellblock} to {_cellblock}
	loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
		set {cb2::celldata::cells::%{_cell}%::locs::%location of loop-block%} to location of loop-block
		set {cb2::celldata::cells::%{_cell}%::blocks::%location of loop-block%} to type of loop-block
		set {cb2::celldata::locs::%location of loop-block%} to {_cell}
	Cellblock_Debug("Creating a Cell called: %{_cell}%")
	Cellblock_Cellblocks_Create_Block({_cellblock})
	Cellblock_Debug("Saving blocks to CellData...")
	Cellblock_Cells_Save_Reset({_cell})
	Cellblock_Flags_Set_Defaults({_cell})
	if {cb2::cells::%{_cell}%::reset-type} is not "UseJsonStorage":
		# JSON Storage doesn't save straight away, but serializing it will set the cell data
		Cellblock_Cells_Set_Reset({_cell})

# Just checks to see if the options {@MaxBoughtCells} and {@MaxRentedCells} stop a player
function Cellblock_Cells_Can_Have(cell: string, p: player, type: string) :: boolean:
	set {_u} to uuid of {_p}
	if {_type} is "buy":
		if {@MaxBoughtCells} is -1:
			return false
		if {@MaxBoughtCells} is 0:
			return true
		set {_cells} to size of {cb2::player::%{_u}%::bought::*}
		#set {_cells} to size of {cb2::celldata::cells::test8::locs::*}
		if {_cells} is less than {@MaxBoughtCells}:
			return false
		else:
			return true
	else:
		if {@MaxRentedCells} is -1:
			return false
		if {@MaxRentedCells} is 0:
			return true
		set {_cells} to size of {cb2::player::%{_u}%::renting::*}
		if {_cells} is less than {@MaxRentedCells}:
			return false
		else:
			return true

function Cellblock_Cells_Reset_Cell(cell: string):
	set {_args::*} to {_cell} and ""
	Cellblock_API_Fire_Event("Cell Reset", {_args::*}, script)
	loop blocks within {cb2::cells::%{_cell}%::loc1} to {cb2::cells::%{_cell}%::loc2}:
		clear inventory of loop-block
		if {cb2::celldata::cells::%{_cell}%::reset::locations::%location of loop-block%} is not set:
			set block at location of loop-block to air
		else:
			set block at location of loop-block to {cb2::celldata::cells::%{_cell}%::reset::blocks::%location of loop-value%}

function Cellblock_Cells_Cell_Expired(cell: string):
	loop {cb2::player::%{cb2::cells::%{_cell}%::renter}%::cells::homes::*}:
		if loop-value is {_cell}:
			delete {cb2::player::%{cb2::cells::%{_cell}%::renter}%::cells::homes::%loop-index%}
			exit loop
	delete {cb2::player::%{cb2::cells::%{_cell}%::renter}%::cells::renting::%{_cell}%}
	set {cb2::cells::%{_cell}%::rented} to false
	delete {cb2::cells::%{_cell}%::expires}
	delete {cb2::cells::%{_cell}%::expiresat}
	delete {cb2::celldata::active-cells::%{_cell}%}
	delete {cb2::cells::%{_cell}%::renter}
	Cellblock_Cells_Update_Sign({_cell})
	Cellblock_Cells_Reset_Cell({_cell})
	Cellblock_Flags_Set_Defaults({_cell})

function Cellblock_Cells_Delete_Cell(cell: string):
	set {_args::*} to {_cell} and ""
	set {_continue} to Cellblock_API_Fire_Event("Cell Delete", {_args::*}, script)
	if {_continue} is false:
		stop
	loop {cb2::player::%{cb2::cells::%{_cell}%::renter}%::cells::homes::*}:
		if loop-value is {_cell}:
			delete {cb2::player::%{cb2::cells::%{_cell}%::renter}%::cells::homes::%loop-index%}
			exit loop
	loop {cb2::player::%{cb2::cells::%{_cell}%::owner}%::cells::bought::*}:
		if loop-value is {_cell}:
			delete {cb2::player::%{cb2::cells::%{_cell}%::owner}%::cells::bought::%loop-index%}
			exit loop

	loop {cb2::celldata::cells::%{_cell}%::locs::*}:
		delete {cb2::celldata::locs::%loop-value%}

	if {cb2::cells::%{_cell}%::reset-type} is "UseJsonStorage":
		Cellblock_JSON_Delete_Cell({_cell})

	delete {cb2::cells::%{_cell}%}

	if Cellblock_Cells_Is_Mapped({_cell}) is true:
		loop {cb2::cells::*}:
			if {cb2::cells::%loop-value%::reset::mapped::cell} is {_cell}:
				delete {cb2::cells::%loop-value%::reset::mapped::cell}
				delete {cb2::cells::%loop-value%::reset::mapped::status}
				set {_remap::%loop-value%} to loop-value
		loop {_remap::*}:
			Cellblock_Cells_Map_Cell(loop-value)

	delete {cb2::celldata::active-cells::%{_cell}%}
	if {@RemoveSignsOnDelete} is true:
		loop {cb2::cells::%{_cell}%::signs::*}:
			set block at {cb2::celldata::signs::%loop-value%} to air
	else:
		set {cb2::cells::%{_cell}%::deleting} to true
		Cellblock_Cells_Update_Sign({_cell})
	loop {cb2::cells::%{_cell}%::signs::*}:
		delete {cb2::celldata::signs::%loop-value%}
	delete {cb2::celldata::cells::%{_cell}%}
	delete {cb2::cells::%{_cell}%::*}

function Cellblock_Cells_Sell_Cell(cell: string, p: player, type: string) :: object:
	if {_type} is "server":
		if {@AllowResellingToServer} is true:
			set {_amount} to {cb2::cells::%{_cell}%::buy-price}/{@ServerResellReturn}
			add {_amount} to balance of player from {cb2::cells::%{_cell}%::owner}

			Cellblock_Debug("buy-price: %{cb2::cells::%{_cell}%::buy-price}%")
			Cellblock_Debug("ServerResellReturn: {@ServerResellReturn}")
			Cellblock_Debug("Divided: %{cb2::cells::%{_cell}%::buy-price}/{@ServerResellReturn}%")
			Cellblock_Debug("Amount: %{_amount}%")

			delete {cb2::player::%{cb2::cells::%{_cell}%::owner}%::cells::bought::%{_cell}%}
			set {_u} to uuid of {_p}
			set {cb2::cells::%{_cell}%::bought} to false
			delete {cb2::cells::%{_cell}%::owner}
			Cellblock_Cells_Reset_Cell({_cell})
			Cellblock_Cells_Homes_Remove({_cell}, {_p})
			return {_amount}
		else:
			return false
	else:
		if {@AllowResellingToOthers} is true:
			set {cb2::marketplace::cells::%{_cell}%} to {_cell}
			set {cb2::cells::%{_cell}%::buyable} to true
			return true
		else:
			return false

function Cellblock_Cells_Buy_Cell(cell: string, p: player) :: boolean:
	set {_args::*} to {_p} and {_cell}
	set {_continue} to Cellblock_API_Fire_Event("Cell Buy", {_args::*}, script)
	if {_continue} is false:
		stop
	if {cb2::cells::%{_cell}%::buyable} is true:
		if {cb2::cells::%{_cell}%::bought} is false:
			if balance of {_p} is greater than or equal to {cb2::cells::%{_cell}%::buy-price}:
				if {cb2::cells::%{_cell}%::owner} is "server":
					# owner is the server - transfer ownership from server to player
					# money taken, not given anywhere else
					subtract {cb2::cells::%{_cell}%::buy-price} from balance of {_p}
				else:
					# owner is a player - transfer ownership from player to player
					# money taken, given to that player
					subtract {cb2::cells::%{_cell}%::buy-price} from balance of {_p}
					add {cb2::cells::%{_cell}%::buy-price} to balance of player from {cb2::cells::%{_cell}%::owner}
					delete {cb2::player::%{cb2::cells::%{_cell}%::owner}%::cells::bought::%{_cell}%}
				set {_u} to uuid of {_p}
				set {cb2::cells::%{_cell}%::bought} to true
				set {cb2::cells::%{_cell}%::owner} to uuid of {_p}
				set {cb2::player::%{_u}%::cells::bought::%{_cell}%} to {_cell}
				add {_cell} to {cb2::player::%{_u}%::cells::homes::*}
				Cellblock_Cells_Reset_Cell({_cell})
				Cellblock_Flags_Set_Defaults({_cell})
				return true
	return false

function Cellblock_Cells_Rent_Cell(cell: string, p: player) :: boolean:
	set {_args::*} to {_p} and {_cell}
	set {_continue} to Cellblock_API_Fire_Event("Cell Rent", {_args::*}, script)
	if {_continue} is false:
		stop
	if {cb2::cells::%{_cell}%::owner} is uuid of {_p}:
		return false
	if {cb2::cells::%{_cell}%::rentable} is true:
		if {cb2::cells::%{_cell}%::rented} is false:
			if balance of {_p} is greater than {cb2::cells::%{_cell}%::rent-price}:
				Cellblock_Debug("%{_p}% has balance of %balance of {_p}%")
				if {cb2::cells::%{_cell}%::owner} is "server":
					# owner is the server - server still owns the cell
					# money taken, not given anywhere else
					subtract {cb2::cells::%{_cell}%::rent-price} from balance of {_p}
				else:
					# owner is a player - player who owns the cell still owns it
					# money taken, given to that player
					subtract {cb2::cells::%{_cell}%::rent-price} from balance of {_p}
					add {cb2::cells::%{_cell}%::rent-price} to balance of player from {cb2::cells::%{_cell}%::owner}
				Cellblock_Debug("%{_p}% has balance of %balance of {_p}%")
				set {_u} to uuid of {_p}
				set {cb2::cells::%{_cell}%::rented} to true
				set {cb2::cells::%{_cell}%::renter} to uuid of {_p}
				set {cb2::cells::%{_cell}%::expires} to {cb2::cells::%{_cell}%::time}
				set {cb2::cells::%{_cell}%::expiresat} to now
				add {cb2::cells::%{_cell}%::time} to {cb2::cells::%{_cell}%::expiresat}
				add {_cell} to {cb2::player::%{_u}%::cells::homes::*}
				set {cb2::player::%{_u}%::cells::renting::%{_cell}%} to {_cell}
				set {cb2::celldata::active-cells::%{_cell}%} to {_cell}
				Cellblock_Flags_Set_Defaults({_cell})
				return true
	return false

function Cellblock_Cells_Extend_Cell(cell: string, p: player) :: boolean:
	if balance of {_p} is greater than {cb2::cells::%{_cell}%::rent-price}:
		Cellblock_Debug("%{_p}% has balance of %balance of {_p}%")
		Cellblock_Debug("")
		if {cb2::cells::%{_cell}%::owner} is "server":
			subtract {cb2::cells::%{_cell}%::rent-price} from balance of {_p}
		else:
			subtract {cb2::cells::%{_cell}%::rent-price} from balance of {_p}
			add {cb2::cells::%{_cell}%::rent-price} to balance of player from {cb2::cells::%{_cell}%::owner}
		Cellblock_Debug("%{_p}% has balance of %balance of {_p}%")
		set {_u} to uuid of {_p}
		delete {cb2::celldata::active-cells::%{_cell}%}
		add {cb2::cells::%{_cell}%::time} to {cb2::cells::%{_cell}%::expires}
		add {cb2::cells::%{_cell}%::time} to {cb2::cells::%{_cell}%::expiresat}
		set {cb2::celldata::active-cells::%{_cell}%} to {_cell}
		return true
	return false

function Cellblock_Cells_Homes_Remove(cell: string, p: player):
	set {_u} to uuid of {_p}
	loop {cb2::player::%{_u}%::cells::homes::*}:
		if loop-value is {_cell}:
			delete {cb2::player::%{_u}%::cells::homes::%loop-index%}
			exit loop
	
# Loading Cellblock
# (CB:LOADING)

every {@LoopEvery}:
	if {cb2::cellblock::running} is false:
		stop

	set {cb2::cellblock::last-time} to now

	loop {cb2::celldata::active-cells::*}:
		if {cb2::cells::%loop-value%::renter} is set:
			subtract 1 {@LoopEvery} from {cb2::cells::%loop-value%::expires}
			if {cb2::cells::%loop-value%::expires} is less than 1 {@LoopEvery}:
				Cellblock_Cells_Cell_Expired(loop-value)
			else:
				Cellblock_Cells_Update_Sign(loop-value)

# Internal functions
# Not advised to be used outside of Cellblock

function Cellblock_internal_Clear_Data():
	Cellblock_Debug("Cellblock_internal_Clear_Data ran")
	loop {cb2::temp::baechat::channels::*}:
		delete {bchat::channels::%loop-value%::*}
	delete {cb2::temp::*}
	delete {cb2::celldata::*}
	delete {cb2::api::*}
	delete {cb2::cellblocks::*}
	delete {cb2::cellblock::shutdown_check}
	delete {cb2::cellblock::json::*}
	Cellblock_Debug("Cellblock_internal_Clear_Data Finished")

function Cellblock_internal_Restore_Options(path: string, id: integer):
	if {cb2::options::saves::%{_id}%::saved-at} is not set:
		Cellblock_Debug("Failed to restore to %{_id}% because it doesn't exist.")
		stop
	if Cellblock_Utilities_File_Exists({_path}) is true:
		set {_lines::*} to Cellblock_Utilities_Read_File({_path})
		loop {_lines::*}:
			set {_line} to loop-value
			set {_trimmed_line} to loop-value.trim()
			if {_end_next} is true:
				stop
			if {_inoptions} is true:
				if {_trimmed_line}.startsWith("Debug") is true:
					set {_end_next} to true

				if {_trimmed_line}.startsWith("##") is false:
					if {_trimmed_line} is not "":
						set {_values::*} to {_trimmed_line} split at ": "
						Cellblock_Debug("Setting %loop-index% to %{cb2::options::saves::%{_id}%::%{_values::1}%}%")
						Cellblock_Utilities_Set_Line_UTF({_path}, (loop-index parsed as integer), {cb2::options::saves::%{_id}%::%{_values::1}%})
			if {_trimmed_line} is "options:":
				set {_inoptions} to true

function Cellblock_internal_Save_Options(path: string):
	loop 5, 4, 3, 2 and 1:
		set {_next} to loop-number + 1
		loop {cb2::options::saves::%loop-number%::*}:
			Cellblock_Debug("%loop-number%/%{_next}%: %loop-index% -> %loop-value-2%")
			set {cb2::options::saves::%{_next}%::%loop-index%} to loop-value-2
		wait 1 second
	delete {cb2::options::saves::6::*}
	if Cellblock_Utilities_File_Exists({_path}) is true:
		set {_lines::*} to Cellblock_Utilities_Read_File({_path})
		set {cb2::options::saves::1::saved-at} to "%now% (Version: %{cb2::cellblock::version}%)"
		loop {_lines::*}:
			set {_line} to loop-value
			set {_trimmed_line} to loop-value.trim()
			if {_end_next} is true:
				stop
			if {_inoptions} is true:
				if {_trimmed_line}.startsWith("Debug") is true:
					set {_end_next} to true

				if {_trimmed_line}.startsWith("##") is false:
					if {_trimmed_line} is not "":
						set {_values::*} to {_trimmed_line} split at ": "
						set {cb2::options::saves::1::%{_values::1}%} to {_line}
						Cellblock_Debug("%{_values::1}% -> %{_line}%")
			if {_trimmed_line} is "options:":
				set {_inoptions} to true

function Cellblock_internal_Load_Data():
	Cellblock_Debug("Cellblock_internal_Load_Data ran")
	Cellblock_API_Parse_CBTags("./plugins/Skript/scripts/%script%.sk")
	if {@SaveOptions} is true:
		Cellblock_internal_Save_Options("./plugins/Skript/scripts/%script%.sk")
	if {@CompensateForDowntime} is true:
		if {cb2::cellblock::last-time}:
			set {_dif} to difference between now and {cb2::cellblock::last-time}
			if {_dif} is greater than a minute:
				set {_dif} to Cellblock_Utilities_Zero_Seconds({_dif})
	loop {cb2::cells::*}:
		loop blocks within {cb2::cells::%loop-value%::loc1} to {cb2::cells::%loop-value%::loc2}:
			set {cb2::celldata::cells::%loop-value-1%::locs::%location of loop-block%} to location of loop-block
			set {cb2::celldata::cells::%loop-value-1%::blocks::%location of loop-block%} to type of loop-block
			set {cb2::celldata::locs::%location of loop-block%} to loop-value-1
		loop {cb2::cells::%loop-value%::signs::*}:
			set {cb2::celldata::signs::%loop-value-2%} to loop-value-1
			if block at loop-value-2 is any wall sign:
				set {_oloc} to Cellblock_Utilities_Block_Behind(block at loop-value-2)
				set {_oloc} to location of {_oloc}
				set {cb2::celldata::signbacks::%{_oloc}%} to loop-value-1
			else:
				set {_oloc} to location of block below block at {_loc}
				set {cb2::celldata::signbacks::%{_oloc}%} to loop-value-1
		if {@RefreshSignsOnLoad} is true:
			Cellblock_Cells_Update_Sign(loop-value)
		if {cb2::cells::%loop-value%::expires} is set:
			if {_dif} is set:
				add {_dif} to {cb2::cells::%loop-value%::expires}
				set {cb2::celldata::active-cells::%loop-value%} to loop-value
			else if now is greater than {cb2::cells::%loop-value%::expires}:
				Cellblock_Cells_Cell_Expired(loop-value)
			else:
				set {cb2::celldata::active-cells::%loop-value%} to loop-value
		if {cb2::cells::%loop-value%::reset-type} is not set:
			set {cb2::cells::%loop-value%::reset-type} to {cb2::cellblock::last-save-system}
		Cellblock_Debug("")
		Cellblock_Cells_Set_Reset(loop-value)
	set {cb2::celldata::flags::break} to true
	set {cb2::celldata::flags-extra::break::description} to "Let others break blocks in your cell. This won't let them break any blocks."
	set {cb2::celldata::flags-extra::break::everyone-default} to false
	set {cb2::celldata::flags::place} to true
	set {cb2::celldata::flags-extra::place::description} to "Let others place blocks in your cell. Remember to give the player the {@I}break flag {@P}otherwise they can't break their blocks"
	set {cb2::celldata::flags-extra::place::everyone-default} to false
	set {cb2::celldata::flags::goto} to true
	set {cb2::celldata::flags-extra::goto::description} to "Enabled by default, lets users teleport to your cell"
	set {cb2::celldata::flags-extra::goto::everyone-default} to true
	set {cb2::celldata::flags::chest} to true
	set {cb2::celldata::flags-extra::chest::description} to "The chest flag lets others access any block with an inventory in your cell"
	set {cb2::celldata::flags-extra::chest::everyone-default} to false
	set {cb2::celldata::flags::use} to true
	set {cb2::celldata::flags-extra::use::description} to "Give access to doors, switches and other usable blocks"
	set {cb2::celldata::flags-extra::use::everyone-default} to true
	set {cb2::celldata::flags::rent} to true
	set {cb2::celldata::flags-extra::rent::description} to "Allow others to extend the rent time of your cell"
	set {cb2::celldata::flags-extra::rent::everyone-default} to false
	set {cb2::celldata::flags::move} to true
	set {cb2::celldata::flags-extra::move::description} to "Enabled by default, lets users walk onto your cell"
	set {cb2::celldata::flags-extra::move::everyone-default} to true
	set {cb2::celldata::flags::admin} to true
	set {cb2::celldata::flags-extra::admin::warning} to "The admin flag allows FULL ACCCESS to your Cell. By granting this flag, you are accepting full responsibility for anything that the other player does to your Cell."
	set {cb2::celldata::flags-extra::admin::restricted} to true
	set {cb2::celldata::flags-extra::admin::everyone-default} to false
	set {cb2::celldata::flags::manageflags} to true
	set {cb2::celldata::flags-extra::manageflags::warning} to "The manage flags flag allows the other player to grant flags to any other player (except 'everyone'). This could be used to steal or grief your Cell."
	set {cb2::celldata::flags-extra::manageflags::restricted} to true
	set {cb2::celldata::flags-extra::manageflags::everyone-default} to false
	set {cb2::cellblock::data::path} to "./plugins/Cellblock/data/"
	set {cb2::cellblock::data::folder} to new File({cb2::cellblock::data::path})
	if {cb2::cellblock::data::folder}.exists() is false:
		{cb2::cellblock::data::folder}.mkdirs()
	loop all players:
		if {cb2::uuids::%uuid of loop-player%} is not set:
			set {cb2::uuids::%uuid of loop-player%} to uuid of loop-player
	Cellblock_Debug("Cellblock_internal_Load_Data Finished")

function Cellblock_Modify_Skript_Config():
	set {_config::*} to Cellblock_Utilities_Read_File("./plugins/Skript/config.sk")
	set {_indefault} to false
	loop {_config::*}:
		if loop-value.trim().equalsIgnoreCase("default:") is true:
			set {_indefault} to true
		else if {_indefault} is true:
			if loop-value.trim().startsWith("pattern: (?!cb2::celldata::*)") is true:
				stop
			if loop-value.trim() is "pattern: .*":
				Cellblock_Utilities_Set_Line_UTF("./plugins/Skript/config.sk", loop-index parsed as integer, "		pattern: (?!cb2::celldata::*).*")
				Cellblock_Console("Cellblock has modified the Skript config to prevent CellData from being saved.")
				execute console command "sk reload config"
				stop
			else if loop-value.trim().startsWith("pattern: ") is true:
				set {_split::*} to loop-value split at ": "
				Cellblock_Utilities_Set_Line_UTF("./plugins/Skript/config.sk", loop-index parsed as integer, "		pattern: (?!cb2::celldata::*)%{_split::2}%")
				execute console command "sk reload config"
				Cellblock_Console("Cellblock has modified the Skript config to prevent CellData from being saved. The default pattern wasn't detected, Cellblock has still modified the pattern.")
				stop

function Cellblock_internal_Process_Update():
	if {cb2::cellblock::update::27072020} is not set:
		loop {cb2::cells::*}:
			if {cb2::cells::%loop-value%::bought} is true:
				add loop-value to {cb2::player::%{cb2::cells::%loop-value%::owner}%::cells::homes::*}

on script load:
	set {cb2::cellblock::running} to false
	Cellblock_Console("{@Header}")
	Cellblock_Console(" ")
	Cellblock_Console("{@Simple} Intilising Cellblock 2 (%script%.sk)...")
	Cellblock_Console("{@Simple} Checking for required addons: skQuery and skript-mirror")
	set {_f} to "%File%"
	if {_f} is not set:
		Cellblock_Console("{@F} Failed to find plugin skript-mirror. Cellblock has been disabled as this is a required plugin")
		Cellblock_Console("{@F} Download skript-mirror: &ahttps://forums.skunity.com/resources/254/")
		execute console command "sk disable %script%"
	else if Bukkit.getPluginManager().getPlugin("SkQuery") is null:
		Cellblock_Console("{@F} ERROR! Failed to find plugin skQuery. Cellblock has been disabled as this is a required plugin")
		Cellblock_Console("{@F} Download skQuery: &ahttps://forums.skunity.com/resources/68/")
		execute console command "sk disable %script%"
	Cellblock_Console("{@Simple} Clearing any temporary data")
	Cellblock_internal_Clear_Data()
	Cellblock_Modify_Skript_Config()
	Cellblock_JSON_Create()
	Cellblock_JSON_Load()
	Cellblock_internal_Load_Data()
	Cellblock_internal_Process_Update()
	if {cb2::cellblock::last-save-system} is not set:
		if {@TurnOffReset} is true:
			set {cb2::cellblock::last-save-system} to "TurnOffReset"
		else if {@UseJsonStorage} is true:
			set {cb2::cellblock::last-save-system} to "UseJsonStorage"
		else if {@BlocksToLocations} is true:
			set {cb2::cellblock::last-save-system} to "BlocksToLocations"
		else if {@UseCellMapping} is true:
			set {cb2::cellblock::last-save-system} to "CellMapping"
		else if {@LocationsToBlocks} is true:
			set {cb2::cellblock::last-save-system} to "LocationsToBlocks"
		else:
			set {cb2::cellblock::last-save-system} to "TurnOffReset"
	else if {@TurnOffReset} is true:
		if {cb2::cellblock::last-save-system} is not "TurnOffReset":
			Cellblock_Cells_Save_Convert("TurnOffReset")
	else if {@UseJsonStorage} is true:
		if {cb2::cellblock::last-save-system} is not "UseJsonStorage":
			Cellblock_Cells_Save_Convert("UseJsonStorage")
	else if {@BlocksToLocations} is true:
		if {cb2::cellblock::last-save-system} is not "BlocksToLocations":
			Cellblock_Cells_Save_Convert("BlocksToLocations")
	else if {@UseCellMapping} is true:
		if {cb2::cellblock::last-save-system} is not "CellMapping":
			Cellblock_Cells_Save_Convert("CellMapping")
	else if {@LocationsToBlocks} is true:
		if {cb2::cellblock::last-save-system} is not "LocationsToBlocks":
			Cellblock_Cells_Save_Convert("LocationsToBlocks")
	set {cb2::cellblock::running} to true
	set {cb2::cellblock::version} to "2.0.0-pre6"
	set {cb2::cellblock::version_int} to 29072020
	set {cb2::cellblock::script} to script
	if {cb2::cellblock::shutdown_check} is set:
		Cellblock_Console("&cCellblock was not shut down properly!")
		Cellblock_Console("&cFailing to shutdown properly may cause Skript to save temporary variables used by Cellblock")
		Cellblock_Console("&cThis will increase your load time of your server. Cellblock has cleared the old temporary variables")
		Cellblock_Console("&cHowever, it is advised to shut Cellblock down properly to prevent load time increases") 
		Cellblock_Console("&cThe reason this might happen is because of a crash or not running the /stop command")
		Cellblock_Console("&cCellblock loads a lot of data as temporary variables and deletes it on shutdown")
	set {cb2::cellblock::shutdown_check} to true


	if {cb2::reloaded} is set:
		set {_cb2_reload::*} to {cb2::reload::*}
		delete {cb2::reload::*}
		if size of {_cb2_reload::*} is greater than 0:
			send "" to {cb2::reloaded}
			send "{@S} Reloading CellAddons..." to {cb2::reloaded}
			loop {_cb2_reload::*}:
				send "{@S} Reloading CellAddon: {@I}%loop-value%" to {cb2::reloaded}
				execute console command "/sk reload %loop-value%"
				send "{@S} Finished reloading: {@I}%loop-value%" to {cb2::reloaded}
				send "" to {cb2::reloaded}
			send "{@S} Reloading finished" to {cb2::reloaded}
			send "" to {cb2::reloaded}
			Cellblock_Debug("Reloading the following: %{_cb2_reload::*}%")
			delete {cb2::reloaded}
		else:
			Cellblock_Debug("No registered CellAddons to reload!")
	loop {cb2::on-load::scripts::*}:
		execute console command "/sk enable %loop-value%"
	delete {cb2::on-load::scripts::*}

on join:
	if size of {cb2::player::%uuid of player%::messages::*} is greater than 0:
		loop {cb2::player::%uuid of player%::messages::*}:
			message "%loop-value%"

# Loading Cellblock
# (CB:UNLOADING)

on script unload:
	Cellblock_Console("{@Simple} Cellblock is preparing for shutdown")
	Cellblock_JSON_Save()
	Cellblock_internal_Clear_Data()
	set {cb2::cellblock::running} to false
	Cellblock_Console("{@Simple} Cellblock is now ready to shutdown")

on command:
	if command is "sk" or "skript":
		if arguments is "reload Cellblock", "reload Cellblock_2", "reload Cellblock 2" or "reload %script%":
			if player has permission "skript.admin":
				Cellblock_Send_Success(player, "Reloading Cellblock...")
				set {cb2::reloaded} to player

# Cellblock Main Command
# (CB:CMD)

command /cellblock [<text>] [<text>] [<text>] [<text>] [<text>] [<text>]:
	aliases: /cb, /cell, /ce, /cells
	trigger:
		if player has permission "cellblock.command":
			set {_command} to arg 1
			if {cb2::api::commands::%{_command}%::command} is set:
				if player has permission "%{cb2::api::commands::%{_command}%::permission}%":
					set {_args::*} to arg 1, arg 2, arg 3, arg 4, arg 5 and arg 6
					Cellblock_API_Execute_Command({_command}, player, {_args::*})
				else:
					Cellblock_Send_Error(player, "You need the permission node {@I}%{_permission}% {@E}to run this command.")
			else:
				Cellblock_Send_Error(player, "Hmm... that command doesn't exist!")
		else:
			Cellblock_Send_Error(player, "You need the permission node {@I}cellblock.command {@E}to run this command.")

# Core Commands
# (CB:CORECMDS)

				
# Help
# => CBTag Register Command - Start
# => Command: help
# => Function: Cellblock_Commands_Core_Help
# => Help-description: This command! Shows all of the commands and a description of them
# => CBTag Register - End
function Cellblock_Commands_Core_Help(player: player, args: strings):
	if {_args::2} is not set:
		Cellblock_Send_Message({_player}, "{@P}Cellblock Help Menu » you can get more information on the commands below by doing /cb help <command>")
		loop {cb2::api::commands::*}:
			if {cb2::api::commands::%loop-value%::description} is set:
				if {_player} has permission {cb2::api::commands::%loop-value%::permission}:
					send "{@I} %loop-value% {@P}» {@I}%{cb2::api::commands::%loop-value%::description}%" to {_player}
	else:
		set {_command} to {_args::2}
		if {cb2::api::commands::%{_command}%} is not set:
			Cellblock_Send_Error({_player}, "{@P} That command doesn't exist")
		else if {_player} has permission {cb2::api::commands::%{_command}%::permission}:
			Cellblock_Send_Message({_player}, "{@P}Information on the {@I}%{_command}% {@P}command")
			if {_args::3} is not set:
				if {cb2::api::commands::%{_command}%::description} is set:
					Cellblock_API_Send_Message_2({_player}, "{@P} Description of {@I}%{_command}% {@P}» {@I}%{cb2::api::commands::%{_command}%::description}%", "message")
				if {cb2::api::commands::%{_command}%::pattern} is set:
					Cellblock_API_Send_Message_2({_player}, "{@P} Pattern for {@I}%{_command}% {@P}» {@I}/cb %{_command}% %{cb2::api::commands::%{_command}%::pattern}%", "message")
				if size of {cb2::api::commands::%{_command}%::explained::*} is greater than 0:
					Cellblock_API_Send_Message_2({_player}, "{@P}Do {@I}/cb help %{_command}% {@I}usage {@P}to see how to use this command", "message")
				if size of {cb2::api::commands::%{_command}%::examples::*} is greater than 0:
					Cellblock_API_Send_Message_2({_player}, "{@P}Do {@I}/cb help %{_command}% {@I}examples {@P}for command examples", "message")
			else if {_args::3} is "pattern", "patterns" or "usage":
				send "{@P} Pattern of {@I}%{_command}%{@P} explained »" to {_player}
				loop {cb2::api::commands::%{_command}%::explained::*}:
					Cellblock_API_Send_Message_2({_player}, "{@I} %loop-value%", "message")
			else if {_args::3} is "example" or "examples":
				send "{@P} Examples of how to use {@I}%{_command}% {@P}»" to {_player}
				loop {cb2::api::commands::%{_command}%::examples::*}:
					Cellblock_API_Send_Message_2({_player}, "{@I} /cb {@I}%{_command}% {@I}%loop-value%", "message")


# => CBTag Register Command - Start
# => Command: refresh
# => Function: Cellblock_Commands_Admin_Refresh
# => Permission: admin
# => Help-description: Refreshes all the signs across Cellblock
# => CBTag Register - End
function Cellblock_Commands_Admin_Refresh(player: player, args: strings):
	loop {cb2::cells::*}:
		Cellblock_Cells_Update_Sign(loop-value)
	Cellblock_Send_Success({_p}, "Updated the signs of {@I}%size of {cb2::cells::*}% {@S}cells")

# => CBTag Register Command - Start
# => Command: options
# => Function: Cellblock_Commands_Admin_Options
# => Permission: admin
# => Help-description: View previous options and restore Cellblock to that
# => CBTag Register - End
function Cellblock_Commands_Admin_Options(player: player, args: strings):
	if {_args::2} is not set:
		Cellblock_Send_Success({_player}, "Here are the {@I}last 5 {@S}options saves by Cellblock")
		loop 5 times:
			if {cb2::options::saves::%loop-number%::saved-at} is set:
				send "  {@I}%loop-number%{@I}) {@P}%{cb2::options::saves::%loop-number%::saved-at}%" to {_player}
		send "" to {_player}
		send "{@P}To view and restore, use {@I}/cb options <id>{@P}. Eg: {@I}/cb options 4" to {_player}
		send "" to {_player}
	else if {_args::2} is "clear":
		delete {cb2::options::*}
		Cellblock_Send_Success({_player}, "Successfully removed all saved options data")
	else if {cb2::options::saves::%{_args::2}%::saved-at} is not set:
		Cellblock_Send_Error({_player}, "That's not a a valid ID")
	else if {_args::3} is "restore":
		Cellblock_Send_Success({_player}, "Restoring your Cellblock options back...")
		Cellblock_internal_Restore_Options("./plugins/Skript/scripts/%script%.sk", {_args::2} parsed as integer)
		Cellblock_Send_Success({_player}, "Finished restoration! Please exit the file and reopen it to view changes.")
	else:
		Cellblock_Send_Success({_player}, "Values for options save {@I}%{_args::2}%")
		loop {cb2::options::saves::%{_args::2}%::*}:
			set {_val} to "%loop-value%".trim()
			send "  {@P}%coloured {_val}%" to {_player}
		send "" to {_player}
		send "{@P}To restore to this options save, do {@I}/cb options %{_args::2}% restore" to {_player}
		send "" to {_player}


# => CBTag Register Command - Start
# => Command: set
# => Function: Cellblock_Commands_Admin_Set
# => Permission: admin
# => Help-description: Set specific values of a cell
# => Help-pattern: <time|expires|rent-price|buy-price|owner|renter|cellblock> <value> [cell]
# => CBTag Register - End
function Cellblock_Commands_Admin_Set(player: player, args: strings):
	if {_args::4} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_player})
		if {_cell} is not set:
			Cellblock_Send_Error({_player}, "You must be stood in a cell or specify a cell to update")
			stop
	else:
		set {_cell} to {_args::4}

	set {_prev} to {cb2::cells::%{_cell}%::%{_args::2}%}
	set {_ret} to Cellblock_Cells_Set_Cell({_cell}, {_args::2}, {_args::3})
	if {_ret} is false:
		Cellblock_Send_Error({_player}, "Invalid data type provided for {@I}%{_args::2}%")
	else:
		Cellblock_Send_Success({_player}, "Successfully updated {@I}%{_args::2}% {@S}of {@I}%{_cell}%{@S}!")
		send "{@P}%{_args::2}% {@P}was {@I}%{_prev}% {@P}and is now {@I}%{_ret}%" to {_player}
		send "" to {_player}
		Cellblock_Cells_Update_Sign({_cell})

function Cellblock_Cells_Set_Cell(cell: string, property: string, value: object) :: object:
	if {_property} is "time" or "expires":
		set {_value} to Cellblock_Utilities_String_To_Time({_value})
	else if {_property} is "rent-price" or "buy-price":
		set {_value} to {_value} parsed as number
	else if {_property} is "owner" or "renter":
		set {_value} to {_value} parsed as offline player
		set {_value} to uuid of {_value}
	if {_value} is not set:
		return false
	set {cb2::cells::%{_cell}%::%{_property}%} to {_value}
	return {_value}

on left click with {@Wand}:
	if {cb2::temp::%uuid of player%::setmode} is true:
		set {cb2::temp::%uuid of player%::loc1} to event-location
		Cellblock_Send_Success(player, "Location 1 has been set!")
		message "{@I} %event-location%"
		cancel event
				
# SetMode
# => CBTag Register Command - Start
# => Command: setmode
# => Function: Cellblock_Commands_Admin_SetMode
# => Permission: admin
# => Help-description: Turn the Cell setmode on or off
# => Help-pattern: [on/off/true/false]
# => CBTag Register - End
function Cellblock_Commands_Admin_SetMode(player: player, args: strings):
	set {_uuid} to uuid of {_player}
	if {cb2::temp::%{_uuid}%::setmode} is true:
		set {cb2::temp::%{_uuid}%::setmode} to false
		Cellblock_Send_Success({_player}, "Turned off cell creation. Using a {@I}{@Wand} {@S}will just do its default behaviour.")
	else:
		set {cb2::temp::%{_uuid}%::setmode} to true
		Cellblock_Send_Success({_player}, "Using a {@I}{@Wand}{@S}, left click your first point and right click your second point. You can then create a cell")
		send "{@P} To turn this off, simply do: {@I}/cb setmode" to {_player}

on left click with {@Wand}:
	if {cb2::temp::%uuid of player%::setmode} is true:
		set {cb2::temp::%uuid of player%::loc1} to event-location
		Cellblock_Send_Success(player, "Location 1 has been set!")
		message "{@I} %event-location%"
		cancel event

on right click with {@Wand}:
	if {cb2::temp::%uuid of player%::setmode} is true:
		if event-location is set:
			set {cb2::temp::%uuid of player%::loc2} to event-location
			Cellblock_Send_Success(player, "Location 2 has been set!")
			message "{@I} %event-location%"
			cancel event

# Override Mode
# => CBTag Register Command - Start
# => Command: override
# => Function: Cellblock_Commands_Admin_Override
# => Permission: admin
# => Help-description: Turn override mode on or off
# => Help-pattern: [on/off/true/false]
# => CBTag Register - End
function Cellblock_Commands_Admin_Override(player: player, args: strings):
	set {_uuid} to uuid of {_player}
	if {cb2::temp::%{_uuid}%::override} is true:
		set {cb2::temp::%{_uuid}%::override} to false
		Cellblock_Send_Success({_player}, "{@P} Turned off override mode. You can only make actions on Cells you own")
	else:
		set {cb2::temp::%{_uuid}%::override} to true
		Cellblock_Send_Success({_player}, "{@P} You can now make Administrative actions on ALL Cells")
		send "{@P} To turn this off, simply do: {@I}/cb override" to {_player}

# Force reset a cell
# => CBTag Register Command - Start
# => Command: reset
# => Function: Cellblock_Commands_Admin_Reset
# => Permission: admin
# => Help-description: Force reset a cell
# => Help-pattern: [cell]
# => CBTag Register - End
function Cellblock_Commands_Admin_Reset(player: player, args: strings):
	set {_uuid} to uuid of {_player}
	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_player})
		if {_cell} is not set:
			Cellblock_Send_Error({_player}, "Couldn't find a cell at your location")
			stop
	else if Cellblock_Cells_Cell_Exists({_args::2}) is true:
		set {_cell} to {_args::2}
	else:
		Cellblock_Send_Error({_player}, "%{_args::2}% doesn't exist, so can't be reset")
		stop
	Cellblock_Send_Success({_player}, "{@P} Resetting the cell, %{_cell}%")
	Cellblock_Cells_Reset_Cell({_cell})

	
# => CBTag Register Command - Start
# => Command: evict
# => Function: Cellblock_Commands_Admin_Evict
# => Permission: admin
# => Help-description: Evict a player from a cell or all of their cells
# => Help-pattern: <cell|player> <[cell]|player>
# => CBTag Register - End
function Cellblock_Commands_Admin_Evict(player: player, args: strings):
	set {_uuid} to uuid of {_player}
	if {_args::2} is "cell":
		if {_args::3} is not set:
			set {_cell} to Cellblock_Utilities_Cell_At_Player({_player})
			if {_cell} is not set:
				Cellblock_Send_Error({_player}, "Couldn't find a cell at your location")
				stop
		else:
			set {_cell} to {_args::3}
		Cellblock_Send_Success({_player}, "Evicting the player from {@I}%{_cell}%")
		Cellblock_Cells_Evict_Cell({_cell})
	else if {_args::3} is not set:
		Cellblock_Send_Error({_player}, "You need to say which player you'd like to evict")
		stop
	else:
		set {_p} to {_args::3} parsed as offline player
		if {_p} is not set:
			Cellblock_Send_Error({_player}, "{@I}%{_args::3}% {@E}isn't a valid player!")
			stop
		Cellblock_Send_Success({_player}, "Evicting the player {@I}%{_p}% {@S}from all of their cells")
		Cellblock_Cells_Evict_Player({_p})

function Cellblock_Cells_Evict_Cell(cell: string):
	if {cb2::cells::%{_cell}%::owner} is set:
		set {_p} to {cb2::cells::%{_cell}%::owner}
		delete {cb2::player::%{cb2::cells::%{_cell}%::owner}%::cells::bought::%{_cell}%}
		set {_u} to uuid of {_p}
		set {cb2::cells::%{_cell}%::bought} to false
		delete {cb2::cells::%{_cell}%::owner}
	Cellblock_Cells_Cell_Expired({_cell})
	Cellblock_Cells_Reset_Cell({_cell})


function Cellblock_Cells_Evict_Player(p: player):
	set {_u} to uuid of {_p}
	loop {cb2::player::%{_u}%::cells::homes::*}:
		Cellblock_Cells_Evict_Cell(loop-value)
	

# => CBTag Register Command - Start
# => Command: delete
# => Function: Cellblock_Commands_Admin_Delete
# => Permission: admin
# => Help-description: Delete a Cell. Add true to the end to reset the Cell. By defualt, Cellblock won't reset the Cell
# => Help-pattern: [cell] [reset=false]
# => CBTag Register - End
function Cellblock_Commands_Admin_Delete(player: player, args: strings):
	set {_uuid} to uuid of {_player}
	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_player})
		if {_cell} is not set:
			Cellblock_Send_Error({_player}, "{@P} Couldn't find a cell at your location")
			stop
	else:
		set {_cell} to {_args::2}

	Cellblock_Send_Success({_player}, "{@P} Deleting the cell, {@I}%{_cell}%")
	if {_args::3} is "true":
		Cellblock_Cells_Reset_Cell({_cell})
	Cellblock_Cells_Delete_Cell({_cell})
	Cellblock_Send_Success({_player}, "{@I}%{_cell}% {@S}has been deleted from Cellblock")

# => CBTag Register Command - Start
# => Command: create
# => Function: Cellblock_Commands_Admin_Create
# => Permission: admin
# => Help-description: Create a new Cell. Use "default" for price, time or block to use the value set in options. Setting time to 0 will set it to bought, not rented. You can set a rent price and a buy price to allow players to buy a Cell or rent it.
# => Help-pattern: <cell name> [rent-price] [time] [block] [buy-price]
# => Help-pattern-explained: <cell name> {P}= a name for the Cell. Use "cell" and Cellblock will name it "Cell" with a number from the Cellblock it is within. Eg: "Cell_10"//[rent-price] {P}= the one time payment to rent a Cell. Value of 0 will not allow it be rented//[time] {P}= How long the Cell is rented/renewed for. 0d will set the Cell to be bought, not rented.//[block] {P}= The Cellblock the Cell will exist in. "default" value will use what is defined in the options; {@DefaultCellblock}//[buy-price] {P}= How much the Cell can be bought for
# => Help-examples: test1 100 1d {P}= creates a Cell that can only be rented. Uses default Cellblock option//test1 100 0d {P}= creates a Cell that can only be bought//test1 0 0d default 200 {P}= creates a Cell that can only be bought//test1 100 1d default 200 {P}= creates a Cell that can be bought OR rented
# => CBTag Register - End
function Cellblock_Commands_Admin_Create(p: player, args: strings):
	set {_u} to uuid of {_p}
	Cellblock_Send_Message({_p}, "{@P}Starting Cell creation...")
	if {cb2::temp::%{_u}%::loc1} is not set:
		send "{@E} You need to have Location 1 set. Use {@I}/cb setmode {@E}and a {@I}{@Wand} to set the 2 locations" to {_p}
		stop
	
	if {cb2::temp::%{_u}%::loc2} is not set:
		send "{@E} You need to have Location 2 set. Use {@I}/cb setmode {@E}and a {@I}{@Wand} to set the 2 locations" to {_p}
		stop

	if {_args::2} is not set:
		send "{@E} You need to put a name for the cell!" to {_p}
		send "{@I} &c<cell name> [price] [time] [block]" to {_p}
		stop

	if Cellblock_Cells_Cell_Exists({_args::2}) is true:
		send "{@E} A Cell already exists with that name. If you'd like to redefine it, you can do {@I}/cb redefine %{_args::2}%" to {_p}
		stop

	if {_args::3} is not set:
		send "{@E} You haven't provided a price so will default to {@I}{@DefaultPrice}" to {_p}
		set {_args::3} to "{@DefaultPrice}"
	set {_price} to {_args::3} parsed as number
	if {_price} is not set:
		send "{@E} The price you provided is not a valid number. Cell creation failed!" to {_p}
		stop

	if {_args::4} is not set:
		send "{@E} You haven't provided a time so will default to {@I}{@DefaultTime}" to {_p}
		set {_args::4} to "{@DefaultTime}"
	if {_args::4} is "0":
		set {_time} to 0 days
	else:
		set {_time} to Cellblock_Utilities_String_To_Time({_args::4})
	if {_time} is not set:
		send "{@E} The provided time isn't valid. Double check what you entered. It must follow the format of {@I}<number><type>{@E}. Eg: 2d5h, 5h5m..." to {_p}
		stop
	set {_time} to Cellblock_Utilities_Zero_Seconds({_time})

	if {_args::5} is not set:
		send "{@E} You haven't provided a cellblock so will default to {@I}{@DefaultCellblock} cellblock" to {_p}
		set {_args::5} to "{@DefaultCellblock}"
	else if {_args::5} is "default":
		set {_args::5} to "{@DefaultCellblock}"

	if {_args::6} is set:
		set {_buyprice} to {_args::6} parsed as number
		if {_buyprice} is not set:
			send "{@E} The price to buy the Cell that you provided is not a valid number. Buying has been disabled" to {_p}
			set {_buyprice} to 0
	
	#						 location 1													name 				rent time
	#																location 2						price 			  cellblock
	Cellblock_Cells_Create_Cell({cb2::temp::%{_u}%::loc1}, {cb2::temp::%{_u}%::loc2}, {_args::2}, {_price}, {_time}, {_args::5}, {_buyprice})
	if Cellblock_Cells_Cell_Exists({_args::2}) is true:
		send "{@I} %{_args::2}% {@S}was successfully created!" to {_p}
		send "{@P} The next sign you place with the word 'cell' as line 1 will create a Cell Sign for {@I}%{_args::2}%" to {_p}
		set {cb2::temp::%{_u}%::lastcell} to {_args::2}
	else:
		send "{@E} Something went wrong trying to create that Cell. Please try again" to {_p}

on sign change:
	if line 1 is "cell":
		if line 2 is "":
			if {cb2::temp::%uuid of player%::lastcell} is set:
				Cellblock_Cells_Add_Sign({cb2::temp::%uuid of player%::lastcell}, location of event-block)
				Cellblock_Send_Success(player, "Successfully added that sign to  {@I}%{cb2::temp::%uuid of player%::lastcell}%")
				wait 1 second
				Cellblock_Cells_Update_Sign({cb2::temp::%uuid of player%::lastcell})
			else:
				cancel event
				Cellblock_Send_Error(player, "Creating a Cell Sign must have the Cell you want it to be registered to on Line 2")
		else if Cellblock_Cells_Cell_Exists(line 2):
			Cellblock_Cells_Add_Sign(line 2, location of event-block)
			Cellblock_Send_Success(player, "Successfully added that sign to {@I}%line 2%")
			wait 1 second
			Cellblock_Cells_Update_Sign(line 2)
		else:
			cancel event
			Cellblock_Send_Error(player, "Creating a Cell Sign must have the Cell you want it to be registered to on Line 2")

on break:
	if {cb2::celldata::signs::%event-location%} is set:
		if {cb2::temp::%uuid of player%::override} is not true:
			cancel event
			Cellblock_Send_Error(player, "This sign is a Cell Sign and is protected")
		else:
			set {_cell} to {cb2::celldata::signs::%event-location%}
			set {_blockbehind} to Cellblock_Utilities_Block_Behind(block at event-location)
			set {_blockbehind} to location of {_blockbehind}
			delete {cb2::celldata::signbacks::%{_blockbehind}%}
			delete {cb2::cells::%{_cell}%::signs::%event-location%}
			delete {cb2::celldata::signs::%event-location%}
			Cellblock_Send_Success(player, "That sign has been deleted from Cellblock")
			# just making sure to update the goto location when new signs are added or deleted
			delete {cb2::celldata::cells::%{_cell}%::goto}
	else if {cb2::celldata::signbacks::%event-location%} is set:
		if {cb2::temp::%uuid of player%::override} is not true:
			cancel event
			Cellblock_Send_Error(player, "This block is supporting a Cell Sign and is protected")
		else:
			set {_signloc} to {cb2::celldata::signbacks::%event-location%}
			set {_cell} to {cb2::celldata::signs::%{_signloc}%}
			delete {cb2::cells::%{_cell}%::signs::%{_signloc}%}
			delete {cb2::celldata::signbacks::%event-location%}
			delete {cb2::celldata::signs::%{_signloc}%}
			Cellblock_Send_Success(player, "That sign has been deleted from Cellblock")
			# just making sure to update the goto location when new signs are added or deleted
			delete {cb2::celldata::cells::%{_cell}%::goto}


# Renting/Buying Cells

# => CBTag Register Command - Start
# => Command: unrent
# => Function: Cellblock_Commands_Unrent_Cell
# => Help-description: Unrent a cell
# => Help-pattern: [cell]
# => CBTag Register - End
function Cellblock_Commands_Unrent_Cell(p: player, args: strings):
	set {_u} to uuid of {_p}

	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::2}

	if {cb2::cells::%{_cell}%::renter} is {_u}:
		Cellblock_Cells_Cell_Expired({_cell})
		Cellblock_Send_Success({_p}, "You're no longer renting {@I}%{_cell}%")
	else:
		Cellblock_Send_Error({_p}, "You can't unrent a cell that you don't own")


# => CBTag Register Command - Start
# => Command: rent
# => Function: Cellblock_Commands_Rent_Cell
# => Help-description: Rent a Cell
# => Help-pattern: <cell name>
# => CBTag Register - End
function Cellblock_Commands_Rent_Cell(p: player, args: strings):
	set {_u} to uuid of {_p}

	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::2}

	if {cb2::cells::%{_cell}%::owner} is {_u}:
		Cellblock_Send_Error({_p}, "You own {@I}%{_cell}% {@E}already, so can't rent it.")
		stop

	if {cb2::cells::%{_cell}%::renter} is {_u}:
		Cellblock_API_Execute_Command("extend", {_p}, {_args::*})
		stop

	if {cb2::cells::%{_cell}%::rentable} is false:
		Cellblock_Send_Error({_p}, "{@I}%{_cell}% can't be rented at the moment!")
		stop

	if {cb2::cells::%{_cell}%::rented} is true:
		Cellblock_Send_Error({_p}, "{@I}%{_cell}% is already being rented")
		stop

	if balance of {_p} is less than {cb2::cells::%{_cell}%::rent-price}:
		Cellblock_Send_Error({_p}, "You can't afford to rent {@I}%{_cell}%{@E}. The rental price is {@M}%{cb2::cells::%{_cell}%::rent-price}%{@E}, while you only have {@M}%balance of {_p}%")
		stop

	set {_res} to Cellblock_Cells_Rent_Cell({_cell}, {_p})
	if {_res} is true:
		Cellblock_Send_Success({_p}, "Congrats! You're now renting {@I}%{_cell}%{@S}! You can visit it by doing {@I}/cb goto %{_cell}%")
		send "{@M}%{cb2::cells::%{_cell}%::rent-price}% {@S}has been taken from your balance." to {_p}

# => CBTag Register Command - Start
# => Command: extend
# => Function: Cellblock_Commands_Extend_Cell
# => Help-description: Extend the rent time of a Cell
# => Help-pattern: <cell name>
# => CBTag Register - End
function Cellblock_Commands_Extend_Cell(p: player, args: strings):
	set {_u} to uuid of {_p}

	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::2}

	if {cb2::cells::%{_cell}%::owner} is {_u}:
		Cellblock_Send_Error({_p}, "You own {@I}%{_cell}% {@E}already, so can't extend its time.")
		stop

	if {cb2::cells::%{_cell}%::renter} is not {_u}:
		if Cellblock_Flags_Can_Do({_cell}, {_p}, "rent") is false:
			Cellblock_Send_Error({_p}, "You don't have permission to extend the rent time of {@I}%{_cell}%")
			stop			

	if balance of {_p} is less than {cb2::cells::%{_cell}%::rent-price}:
		Cellblock_Send_Error({_p}, "You can't afford to extend the rent of {@I}%{_cell}%{@E}. The rental price is {@M}%{cb2::cells::%{_cell}%::rent-price}%{@E}, while you only have {@M}%balance of {_p}%")
		stop

	set {_res} to Cellblock_Cells_Extend_Cell({_cell}, {_p})
	if {_res} is true:
		send "" to {_p}
		send "{@Header}" to {_p}
		send "" to {_p}
		send "{@S}You've extended the rent time of {@I}%{_cell}%{@S}!" to {_p}
		send "{@M}%{cb2::cells::%{_cell}%::rent-price}% {@S}has been taken from your balance." to {_p}
		send "" to {_p}

on {@SignClickToRent} on sign:
	if {cb2::temp::%uuid of player%::sign-rent} is set:
		if {cb2::temp::%uuid of player%::override} is true:
			stop
		else:
			cancel event
		set {_args::*} to "rent" and {cb2::temp::%uuid of player%::sign-rent}
		Cellblock_Commands_Rent_Cell(player, {_args::*})
		delete {cb2::temp::%uuid of player%::sign-rent}
	else if {cb2::celldata::signs::%event-location%} is set:
		if {cb2::temp::%uuid of player%::override} is true:
			stop
		else:
			cancel event
		set {_cell} to {cb2::celldata::signs::%event-location%}
		if Cellblock_Cells_Cell_Exists({_cell}) is true:
			if {cb2::cells::%{_cell}%::rentable} is true:
				if {cb2::cells::%{_cell}%::rented} is false:
					Cellblock_Send_Success(player, "{@I} %{_cell}%{@S} is available to rent! It'll cost {@M}%{cb2::cells::%{_cell}%::rent-price}%{@S} to rent it for {@M}%{cb2::cells::%{_cell}%::time}%{@S}. To rent the Cell, {@I}{@SignClickToRent} the sign again!")
					set {cb2::temp::%uuid of player%::sign-rent} to {cb2::celldata::signs::%event-location%}
					if {cb2::cells::%{_cell}%::buyable} is true:
						if {cb2::cells::%{_cell}%::bought} is false:
							message "{@P} You can also buy this Cell! You can {@I}{@SignClickToBuy}{@P} on the sign for more information"
				else if {cb2::cells::%{_cell}%::buyable} is true:
					if {cb2::cells::%{_cell}%::rented} is false:
						Cellblock_Send_Error(player, "This Cell can't be rented, but you can buy it! Just {@I}{@SignClickToBuy} on the sign{@E} for more information")
				else:
					if {cb2::cells::%{_cell}%::renter} is not uuid of player:
						if Cellblock_Flags_Can_Do({_cell}, {_p}, "rent") is false:
							Cellblock_Send_Error(player, "{@I}%{_cell}% {@E}is being rented already. You can't rent it!")
							stop
					set {_args::*} to "extend", {_cell} and "sign"
					Cellblock_API_Execute_Command("extend", player, {_args::*})
		else:
			Cellblock_Send_Error(player, "The Cell, {@I}%{_cell}%{@E}, attached to that sign doesn't exist!")

on {@SignClickToBuy} on sign:
	if {cb2::temp::%uuid of player%::sign-buy} is set:
		if {cb2::temp::%uuid of player%::override} is true:
			stop
		else:
			cancel event
		make player execute command "/cb buy %{cb2::temp::%uuid of player%::sign-buy}%"
		delete {cb2::temp::%uuid of player%::sign-buy}
	else if {cb2::celldata::signs::%event-location%} is set:
		if {cb2::temp::%uuid of player%::override} is true:
			stop
		else:
			cancel event
		set {_cell} to {cb2::celldata::signs::%event-location%}
		if Cellblock_Cells_Cell_Exists({_cell}) is true:
			if {cb2::cells::%{_cell}%::buyable} is true:
				if {cb2::cells::%{_cell}%::bought} is false:
					Cellblock_Send_Success(player, "{@I} %{_cell}% is up for sale! It'll cost {@M}%{cb2::cells::%{_cell}%::buy-price}% to buy it. To buy the Cell, {@I}{@SignClickToBuy}{@S} the sign again!")
					set {cb2::temp::%uuid of player%::sign-buy} to {cb2::celldata::signs::%event-location%}
					if {cb2::cells::%{_cell}%::rentable} is true:
						if {cb2::cells::%{_cell}%::rented} is false:
							message "{@P} This Cell can also be rented! You can {@I}{@SignClickToRent}{@P} on the sign for more information"
				else if {cb2::cells::%{_cell}%::rentable} is true:
					if {cb2::cells::%{_cell}%::rented} is false:
						Cellblock_Send_Error(player, "You can't buy this Cell, but it can be rented! You can {@SignClickToRent} on the sign for more information")
			else if {cb2::cells::%{_cell}%::bought} is true:
				Cellblock_Send_Error(player, "{@I}%{_cell}%{@E} has already been bought. You can't buy it!")
			else:
				Cellblock_Send_Error(player, "This Cell doesn't have a price to buy it. That means you can't buy it. ")
		else:
			Cellblock_Send_Error(player, "The Cell, {@I}%{_cell}%{@E}, attached to that sign doesn't exist!")


# => CBTag Register Command - Start
# => Command: buy
# => Function: Cellblock_Commands_Buy_Cell
# => Help-description: Buy a Cell
# => Help-pattern: {I}<cell name>
# => CBTag Register - End
function Cellblock_Commands_Buy_Cell(p: player, args: strings):
	set {_u} to uuid of {_p}

	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_player})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::2}

	if {cb2::cells::%{_cell}%::owner} is {_u}:
		Cellblock_Send_Error({_p}, "You can't buy a Cell that you own!")
		stop
	set {_current} to {cb2::cells::%{_cell}%::owner}

	if {cb2::cells::%{_cell}%::buyable} is false:
		Cellblock_Send_Error({_p}, "{@I}%{_cell}%{@E} can't be bought at the moment!")
		stop

	if {cb2::cells::%{_cell}%::bought} is true:
		Cellblock_Send_Error({_p}, "This Cell has already been bought by another player")
		stop

	if balance of {_p} is less than {cb2::cells::%{_cell}%::buy-price}:
		Cellblock_Send_Error({_p}, "You can't afford to buy {@I}%{_cell}%}{@E}. The price to buy it is {@M}%{cb2::cells::%{_cell}%::buy-price}%{@E}, while you only have {@I}%balance of {_p}%")
		stop

	set {_res} to Cellblock_Cells_Buy_Cell({_cell}, {_p})
	if {_res} is true:
		Cellblock_Send_Success({_p}, "Congrats! You're now the owner of {@I}%{_cell}%{@S}! You can visit it by doing {@I}/cb goto %{_cell}%")
		Cellblock_Debug("Cell: %{_cell}%")
		Cellblock_Debug("Old Owner: %{_current}%")
		Cellblock_Debug("Owner: %{cb2::cells::%{_cell}%::owner}%")
		Cellblock_Debug("Player: %player from {cb2::cells::%{_cell}%::owner}%")
		if player from {cb2::cells::%{_cell}%::owner} is online:
			Cellblock_Send_Success(player from {_current}, "Your Cell, {@I}%{_cell}%{@S}, has now been sold! You've been paid {@M}%{cb2::cells::%{_cell}%::buy-price}%!")
		else:
			add "{@S} Your Cell, {@I}%{_cell}%{@S}, has now been sold! You've been paid {@M}%{cb2::cells::%{_cell}%::buy-price}%!" to {cb2::player::%{_current}%::messages::*}
	else:
		Cellblock_Send_Error({_p}, "Looks like something went wrong while trying to buy that Cell. Try again!")

function Cellblock_Cells_Teleport_Player(cell: string, p: player):
	if {cb2::celldata::cells::%{_cell}%::goto} is set:
		teleport {_p} to {cb2::celldata::cells::%{_cell}%::goto}
	else:
		if {cb2::cells::%{_cell}%::signs::*} is empty:
			Cellblock_Debug("Got told to teleport %{_p}% to %{_cell}%, but it has no signs to utilise!")
			stop
		loop {cb2::cells::%{_cell}%::signs::*}:
			set {_distances::1::%loop-value%} to distance between loop-value and {cb2::cells::%{_cell}%::loc1}
			set {_signs::1::%loop-value%} to loop-value
			set {_distances::2::%loop-value%} to distance between loop-value and {cb2::cells::%{_cell}%::loc2}
			set {_signs::2::%loop-value%} to loop-value
		loop {_distances::1::*}:
			if {_top1} is not set:
				set {_top1} to loop-value
				set {_sign1} to {_signs::1::%loop-index%}
			else if loop-value is less than {_top1}:
				set {_top1} to loop-value
				set {_sign1} to {_signs::1::%loop-index%}
		loop {_distances::2::*}:
			if {_top2} is not set:
				set {_top2} to loop-value
				set {_sign2} to {_signs::2::%loop-index%}
			else if loop-value is less than {_top2}:
				set {_top2} to loop-value
				set {_sign2} to {_signs::2::%loop-index%}
		if {_top1} is less than {_top2}:
			Cellblock_Debug("%{_sign1}%")
			set {_loc} to Cellblock_Utilities_Block_In_Front(block at {_sign1})
			if {_loc} is not air:
				set {_loc} to block at {_sign1}
		else:
			Cellblock_Debug("%{_sign2}%")
			set {_loc} to Cellblock_Utilities_Block_In_Front(block at {_sign2})
			if {_loc} is not air:
				set {_loc} to block at {_sign2}
		subtract 1 from y coord of {_loc}
		Cellblock_Debug("%{_loc}%")
		set {cb2::celldata::cells::%{_cell}%::goto} to location of {_loc} 
		#while {_exit} is not set:
			#if block at {cb2::celldata::cells::%{_cell}%::goto} is air:
			#	subtract 1 from y coord of {cb2::celldata::cells::%{_cell}%::goto}
			#else:
				#set {_exit} to true
		#add 1 to y coord of {cb2::celldata::cells::%{_cell}%::goto}
		teleport {_p} to {cb2::celldata::cells::%{_cell}%::goto}
		Cellblock_Debug("%{cb2::celldata::cells::%{_cell}%::goto}%")

# => CBTag Register Command - Start
# => Command: goto
# => Function: Cellblock_Commands_Goto_Cell
# => Help-description: Goto a Cell
# => Help-pattern: <cell name>
# => CBTag Register - End
function Cellblock_Commands_Goto_Cell(p: player, args: strings):
	if {@GotoCommandEnabled} is false:
		stop

	if {_args::2} is not set:
		Cellblock_Send_Error({_p}, "Where would you like to go? You need to provide a player's name or a Cell ID to goto")
		stop

	Cellblock_Cells_Goto({_p}, {_args::2})

function Cellblock_Cells_Goto(p: player, cell: string):
	if Cellblock_Cells_Cell_Exists({_cell}) is true:
		if Cellblock_Flags_Can_Do({_cell}, {_p}, "goto") is true:
			send "{@P} Teleporting you to %{_cell}%..." to {_p}
			Cellblock_Cells_Teleport_Player({_cell}, {_p})
			stop
		else:
			Cellblock_Send_Error({_p}, "You can't goto %{_cell}% because you don't have permission")
			stop


# => CBTag Register Command - Start
# => Command: info
# => Function: Cellblock_Commands_Info_Cell
# => Help-description: Get information on a cell
# => Help-pattern: [cell]
# => CBTag Register - End
function Cellblock_Commands_Info_Cell(p: player, args: strings):
	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "Couldn't find a cell at your location")
			stop
	else:
		set {_cell} to {_args::2}

	Cellblock_Send_Message({_p}, "{@P}Here's the info on {@I}%{_cell}%")
	if {cb2::cells::%{_cell}%::renter} is set:
		send "{@P} Rented by: {@I}%player from {cb2::cells::%{_cell}%::renter}%" to {_p}
	if {cb2::cells::%{_cell}%::owner} is "server":
		send "{@P} Owned by: {@I}The Server" to {_p}
	else if {cb2::cells::%{_cell}%::owner} is set:
		send "{@P} Owned by: {@I}%player from {cb2::cells::%{_cell}%::owner}%" to {_p}
	send "{@P} Can be:" to {_p}
	if {cb2::cells::%{_cell}%::rentable} is true:
		if {cb2::cells::%{_cell}%::rented} is true:
			send "{@P}    Rented: {@E}no (owned already)" to {_p}
		else:
			send "{@P}    Rented: {@S}yes" to {_p}
	else:
		send "{@P}    Rented: {@E}no" to {_p}

	if {cb2::cells::%{_cell}%::buyable} is true:
		if {cb2::cells::%{_cell}%::bought} is true:
			send "{@P}    Bought: {@E}no (owned already)" to {_p}
		else:
			send "{@P}    Bought: {@S}yes" to {_p}
	else:
		send "{@P}    Bought: {@E}no" to {_p}

	
	send "{@P} Priced at:" to {_p}
	if {cb2::cells::%{_cell}%::rent-price} is set:
		send "{@P}    For rent: {@M}%{cb2::cells::%{_cell}%::rent-price}% {@P}for {@I}%{cb2::cells::%{_cell}%::time}%" to {_p}
	if {cb2::cells::%{_cell}%::buy-price} is set:
		send "{@P}    To buy: {@M}%{cb2::cells::%{_cell}%::buy-price}%" to {_p}
	send "{@P} Inside block: {@I}%{cb2::cells::%{_cell}%::cellblock}%" to {_p}
	send "{@P} Total size: {@I}%size of {cb2::celldata::cells::%{_cell}%::locs::*}% {@P}blocks" to {_p}
	send "" to {_p}

# => CBTag Register Command - Start
# => Command: home
# => Function: Cellblock_Commands_Home_Cell
# => Help-description: Go to your home cell
# => Help-pattern: [home number]
# => CBTag Register - End
function Cellblock_Commands_Home_Cell(p: player, args: strings):
	if {@HomeCommandEnabled} is not true:
		Cellblock_Send_Error({_p}, "The home command has been disabled")
		stop

	set {_u} to uuid of {_p}
	if size of {cb2::player::%{_u}%::cells::homes::*} is 0:
		Cellblock_Send_Error({_p}, "You don't own any cells to go home to")
		stop
	if {_args::2} is not set:
		set {_goto} to first element out of {cb2::player::%{_u}%::cells::homes::*}
	else:
		if {cb2::player::%{_u}%::cells::homes::%{_args::2}%} is set:
			set {_goto} to {cb2::player::%{_u}%::cells::homes::%{_args::2}%}
		else:
			loop {cb2::player::%{_u}%::cells::homes::*}:
				if loop-value is {_args::2}:
					set {_goto} to loop-value
					exit loop
		if {_goto} is not set:
			Cellblock_Send_Error({_p}, "Invalid home number or address! Keep in mind, you only have %size of {cb2::player::%{_u}%::cells::homes::*}% homes. Do /cb homes to see them")
			stop

	Cellblock_Cells_Goto({_p}, {_goto})
	
# => CBTag Register Command - Start
# => Command: homes
# => Function: Cellblock_Commands_Homes
# => Help-description: List your homes
# => CBTag Register - End
function Cellblock_Commands_Homes(p: player, args: strings):
	set {_u} to uuid of {_p}
	if size of {cb2::player::%{_u}%::cells::homes::*} is 0:
		Cellblock_Send_Error({_p}, "You don't have any home cells! Buy or rent a cell first")
	else:
		Cellblock_Send_Success({_p}, "Here are your cells and their home ID's (total: {@I}%size of {cb2::player::%{_u}%::cells::homes::*}%{@S}):")
		loop {cb2::player::%{_u}%::cells::homes::*}:
			if {_first} is not set:
				set {_first} to loop-index
				set {_firstid} to loop-value
			send "{@P}      %loop-index%{@P}) {@I}%loop-value%" to {_p}
		send "" to {_p}
		send "{@P} You can use the Home ID, Cell Name or nothing at all" to {_p}
		send "{@I} /cb home {@P}OR {@I}/cb home %{_first}% {@P}OR {@I}/cb home %{_firstid}%" to {_p}

# => CBTag Register Command - Start
# => Command: sell
# => Function: Cellblock_Commands_Sell_Cell
# => Help-description: Sell the specified Cell to the server or on the Cell Marketplace
# => Help-pattern: <cell name> [server]
# => CBTag Register - End
function Cellblock_Commands_Sell_Cell(p: player, args: strings):
	set {_u} to uuid of {_p}

	if {@AllowResellingToServer} is false:
		{@AllowResellingToOthers} is false:
			Cellblock_Send_Error({_p}, "Reselling is disabled. You'll need to speak to a staff member as to why")
			stop

	if {_args::3} is set:
		if {_args::3} is "server":
			if {@AllowResellingToServer} is false:
				Cellblock_Send_Error({_p}, "Reselling to the server is disabled. Your Cell will be put onto the Cell Marketplace instead")
				set {_type} to "marketplace"
			else:
				set {_type} to "server"
		else:
			Cellblock_Send_Error({_p}, "The 3rd argument can only be 'server'. You put {@I}%{_args::3}%{@E}, which isn't valid")
			stop

	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::2}

	if {cb2::cells::%{_cell}%::owner} is not {_u}:
		Cellblock_Send_Error({_p}, "You can't sell a Cell that you don't own!")
		stop

	if {cb2::cells::%{_cell}%::sellable} is false:
		Cellblock_Send_Error({_p}, "{@I}%{_cell}%{@E} can't be sold!")
		stop

	set {_res} to Cellblock_Cells_Sell_Cell({_cell}, {_p}, {_type})
	if {_res} is false:
		Cellblock_Send_Error({_p}, "Something went wrong while trying to sell your Cell. Please try again.")
	else if {_type} is "server":
		Cellblock_Send_Success({_p}, "Your Cell, {@I}%{_cell}%, was sold back to the server. You have been paid {@M}%{_res}%.")
	else if {_res} is true:
		Cellblock_Send_Success({_p}, "Your Cell, {@I}%{_cell}%, is now up for sale. Other players can buy it from you")

# Cell Flags

function Cellblock_Flags_Set_Defaults(cell: string):
	delete {cb2::cells::%{_cell}%::flags::*}
	loop {cb2::celldata::flags::*}:
		set {cb2::cells::%{_cell}%::flags::%loop-index%::everyone} to {cb2::celldata::flags-extra::%loop-index%::everyone-default}


function Cellblock_Flags_Do_Flag(cell: string, p: object, flag: string, action: string):
	set {_p} to uuid of {_p}
	if {_action} is "true", "t" or "set":
		set {cb2::cells::%{_cell}%::flags::%{_flag}%::%{_p}%} to true
	else if {_action} is "false" or "f":
		set {cb2::cells::%{_cell}%::flags::%{_flag}%::%{_p}%} to false
	else:
		delete {cb2::cells::%{_cell}%::flags::%{_flag}%::%{_p}%}

function Cellblock_Flags_Valid_Flag(flag: string) :: boolean:
	if {cb2::celldata::flags::%{_flag}%} is true:
		return true
	else:
		return false

# Cell flags
function Cellblock_Flags_Can_Do(cell: string, p: player, flag: string) :: boolean:
	set {_u} to uuid of {_p}

	# Override mode overrides everything, so always true
	if {cb2::temp::%{_u}%::override} is true:
		#Cellblock_Debug("(1) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		return true
	if {cb2::cells::%{_cell}%::owner} is "server":
		#Cellblock_Debug("(2) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# Cell is owned by the server
		if {cb2::cells::%{_cell}%::renter} is {_u}:
			#Cellblock_Debug("(3) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
			return true
	if {cb2::cells::%{_cell}%::owner} is {_u}:
		#Cellblock_Debug("(4) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# Cell is owned by a player
		if {cb2::cells::%{_cell}%::renter} is {_u}:
			#Cellblock_Debug("(5) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
			# Only the owner+renter get full access
			return true
	if {cb2::cells::%{_cell}%::owner} is not set:
		if {cb2::cells::%{_cell}%::renter} is {_u}:
			#Cellblock_Debug("(5.1) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
			# Only the owner+renter get full access
			return true
	if {cb2::cells::%{_cell}%::flags::admin::%{_u}%} is true:
		#Cellblock_Debug("(6) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# the admin flag grants full access to a cell
		return true
	if {cb2::cells::%{_cell}%::flags::%{_flag}%::%{_u}%} is false:
		#Cellblock_Debug("(7) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# a false flag always returns false
		return false
	if {cb2::cells::%{_cell}%::flags::%{_flag}%::%{_u}%} is true:
		#Cellblock_Debug("(8) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# true flag, returns true
		return true
	if {cb2::cells::%{_cell}%::flags::%{_flag}%::everyone} is false:
		#Cellblock_Debug("(9) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# a false flag always returns false
		return false
	if {cb2::cells::%{_cell}%::flags::%{_flag}%::everyone} is true:
		#Cellblock_Debug("(10) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
		# true flag, returns true
		return true
	#Cellblock_Debug("(11) Cellblock_Flags_Can_Do: [cell] => [%{_cell}%] : [p] => [%{_p}%] : [flag] => [%{_flag}%]")
	return false

on join:
	set {cb2::temp::uuids::%player%} to uuid of player
	set {cb2::uuids::%uuid of player%} to uuid of player

on quit:
	delete {cb2::temp::uuids::%player%}

# => CBTag Register Command - Start
# => Command: flags
# => Function: Cellblock_Commands_Flags
# => Help-description: See Cellblock flags and flags of a cell
# => Help-pattern: <[cell]/list/info> [flag]
# => CBTag Register - End
function Cellblock_Commands_Flags(p: player, args: strings):
	if {_args::2} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You either need to be in a cell, provide a cell name or use the sub-command {@I}/cb flags list")
			stop
	else:
		set {_cell} to {_args::2}

	if {_args::2} is "list":
		Cellblock_Send_Success({_p}, "Here's a list of usable flags:")
		set {_c} to 0
		loop {cb2::celldata::flags::*}:
			if loop-value is true:
				add 1 to {_c}
				message "{@P}%{_c}% {@P}» {@I}%loop-index%" to {_p}
		send "" to {_p}
	else if {_args::2} is "info":
		if {_args::3} is set:
			if {cb2::celldata::flags::%{_args::3}%} is set:
				Cellblock_Send_Success({_p}, "Here's information on the flag, {@I}%{_args::3}%")
				if {cb2::celldata::flags-extra::%{_args::3}%::restricted} is true:
					send "{@E}This flag is restricted, so only the cell owner can change it" to {_p}
				if {cb2::celldata::flags-extra::%{_args::3}%::warning} is set:
					send "{@E}%{cb2::celldata::flags-extra::%{_args::3}%::warning}%" to {_p}
				if {cb2::celldata::flags-extra::%{_args::3}%::description} is set:
					send "{@P}%{cb2::celldata::flags-extra::%{_args::3}%::description}%" to {_p}
				send "" to {_p}
			else:
				Cellblock_Send_Error({_p}, "That flag doesn't exist! See a list of flags with {@I}/cb flags list")
		else:
			Cellblock_Send_Error({_p}, "You need to say what flag you'd like more information on. To see them all, do {@I}/cb flags list")
	else:
		# cell flags
		Cellblock_Send_Success({_p}, "Here's the flag information for {@I}%{_cell}%")
		loop {cb2::celldata::flags::*}:
			if loop-value is true:
				add 1 to {_c}
				loop {cb2::cells::%{_cell}%::flags::%loop-index%::*}:
					if loop-index-2 is "everyone":
						set {_u} to "everyone"
					else:
						set {_u} to player from {cb2::uuids::%loop-index-2%}

					if loop-value-2 is true:
						add "{@P}[%{_u}% {@S}(true){@P}]" to {_players::*}
					else:
						add "{@P}[%{_u}% {@E}(false){@P}]" to {_players::*}
				if size of {_players::*} is greater than 0:
					message "{@I}    %loop-index% {@P}» {@I}%{_players::*}%" to {_p}
					set {_sent} to true
				delete {_players::*}
		if {_sent} is not set:
			send "{@E}There are no flags set for {@I}%{_cell}%" to {_p}
		send "" to {_p}

# => CBTag Register Command - Start
# => Command: flag
# => Function: Cellblock_Commands_Manage_Flags
# => Help-description: Manage the flags of your Cell
# => Help-pattern: <flag> <player/everyone> <t/f/r> [cell]
# => CBTag Register - End
function Cellblock_Commands_Manage_Flags(p: player, args: strings):
	set {_u} to uuid of {_p}

	# 1 = flag
	# 2 = <flag>
	# 3 = <player/everyone>
	# 4 = <t/f/r/>
	# 5 = [cell]
	if {_args::2} is not set:
		Cellblock_Send_Error({_p}, "You need to provide which flag you'd like to manage")
		stop
	else if Cellblock_Flags_Valid_Flag({_args::2}) is false:
		Cellblock_Send_Error({_p}, "The flag {@I}%{_args::2}% {@E}isn't valid! For a list of valid flags please do {@I}/cb flags list")
		stop
	else if {_args::3} is not set:
		Cellblock_Send_Error({_p}, "Please provide {@I}a player name {@E}or use {@I}everyone {@E}for whom you want to manage")
		stop
	else if {_args::4} is not set:
		Cellblock_Send_Error({_p}, "The 4th argument needs to be {@I}true/t {@E}(to give that flag), {@I}false/f {@E}(disable that flag) or {@I}remove/r {@E}(remove that flag)")
		stop
	else if {_args::4} is not "true", "t", "set", "false", "f", "remove" or "r":
		Cellblock_Send_Error({_p}, "The 4th argument needs to be {@I}true/t {@E}(to give that flag), {@I}false/f {@E}(disable that flag) or {@I}remove/r {@E}(remove that flag)")
		stop
	else if {_args::5} is not set:
		set {_cell} to Cellblock_Utilities_Cell_At_Player({_p})
		if {_cell} is not set:
			Cellblock_Send_Error({_p}, "You didn't provide a Cell and no Cell was found at your location")
			stop
	else:
		set {_cell} to {_args::5}
		if Cellblock_Cells_Cell_Exists({_cell}) is false:
			Cellblock_Send_Error({_p}, "That Cell doesn't exist!")
			stop

	if {_args::3} is "everyone":
		set {_offlineplayer} to "everyone"
		set {_otherplayer} to "everyone"
	else:
		set {_offlineplayer} to {_args::3} parsed as offline player
		if {_offlineplayer} is not set:
			Cellblock_Send_Error({_p}, "The player name {@I}%{_args::3}%{@E}, isn't valid!")
			stop
		else if {cb2::temp::uuids::%{_offlineplayer}%} is set:
			set {_otherplayer} to {cb2::temp::uuids::%{_offlineplayer}%}
		else:
			set {_otherplayer} to uuid of {_offlineplayer}

	if {cb2::celldata::flags-extra::%{_args::2}%::restricted} is true:
		if Cellblock_Flags_Can_Do({_cell}, {_p}, "owner") is false:
			Cellblock_Send_Error({_p}, "The flag {@I}%{_args::2}% {@E}is restricted. You don't have permission to manage this flag")
			stop

	if Cellblock_Flags_Can_Do({_cell}, {_p}, "manageflags") is true:
		send "{@Header}" to {_p}
		send "" to {_p}
		if {cb2::celldata::flags-extra::%{_args::2}%::warning} is set:
			send "{@E} %{cb2::celldata::flags-extra::%{_args::2}%::warning}%" to {_p}
		Cellblock_Flags_Do_Flag({_cell}, {_otherplayer}, {_args::2}, {_args::4})
		if {_args::4} is "true" or "t":
			send "{@I} %{_offlineplayer}% {@S}has been given the flag {@I}%{_args::2}%{@S}" to {_p}
		else if {_args::4} is "false" or "f":
			send "{@I} %{_offlineplayer}% {@S}removed {@I}%{_args::2}%{@S} in your Cell" to {_p}
		else if {_args::4} is "remove" or "r":
			send "{@I} removed the flag {@I}%{_args::2}%{@S} from {@I}%{_offlineplayer}% {@S}in your Cell" to {_p}
		send "" to {_p}
	else:
		Cellblock_Send_Error({_p}, "You can't manage the flags for {@I}%{_cell}%")


		
# Protecting Cells from any damage

on burn:
	set {_cell} to Cellblock_Utilities_Cell_At_Location(event-location)
	if {cb2::celldata::cells::%{_cell}%::reset::locations::%event-location%} is set:
		cancel event
		loop blocks in radius 2 around event-location:
			if loop-block is fire:
				set loop-block to air
	else if {cb2::celldata::signs::%event-location%} is set:
		cancel event
	else if {cb2::celldata::signbacks::%event-location%} is set:
		cancel event

# Protects ALL blocks that have a registered location with Cellblock from explosions
on explode:
	set {_blocks::*} to ...event.blockList()
	loop {_blocks::*}:
		set {_location} to location of loop-value
		if {cb2::celldata::locs::%{_location}%} is set:
			event.blockList().remove(loop-value)
		else if {cb2::celldata::signs::%loop-value%} is set:
			event.blockList().remove(loop-value)
		else if {cb2::celldata::signbacks::%loop-value%} is set:
			event.blockList().remove(loop-value)

on piston retract:
	if event-block is sticky piston or extended sticky piston:
		set {_location} to Cellblock_Utilities_Block_In_Front(event-block)
		set {_location} to Cellblock_Utilities_Block_In_Front({_location})
		set {_location} to location of {_location}
		set {_cell} to Cellblock_Utilities_Cell_At_Location({_location})
		if {cb2::celldata::cells::%{_cell}%::reset::locations::%{_location}%} is set:
			if {cb2::celldata::cells::%{_cell}%::reset::blocks::%{_location}%} is not air:
				set {_facing} to facing of event-block
				set event-block to air
				cancel event
				set event-block to sticky piston
				set facing of event-block to {_facing}
		else if {cb2::celldata::signs::%{_location}%} is set:
			set {_facing} to facing of event-block
			set event-block to air
			cancel event
			set event-block to sticky piston
			set facing of event-block to {_facing}
		else if {cb2::celldata::signbacks::%{_location}%} is set:
			set {_facing} to facing of event-block
			set event-block to air
			cancel event
			set event-block to sticky piston
			set facing of event-block to {_facing}

on piston extend:
	set {_facing} to facing of event-block
	set {_block} to event-block
	loop 12 times:
		if {_block} is air:
			stop
		set {_block} to Cellblock_Utilities_Block_In_Direction({_block}, {_facing})
		set {_location} to location of {_block}
		set {_cell} to Cellblock_Utilities_Cell_At_Location({_location})
		if {cb2::celldata::cells::%{_cell}%::reset::locations::%{_location}%} is set:
			if {cb2::celldata::cells::%{_cell}%::reset::blocks::%{_location}%} is not air:
				cancel event
				stop
		else if {cb2::celldata::signs::%{_location}%} is set:
			cancel event
			stop
		else if {cb2::celldata::signbacks::%{_location}%} is set:
			cancel event
			stop

on break:
	set {_cell} to Cellblock_Utilities_Cell_At_Location(event-location)
	if {_cell} is set:
		if {cb2::celldata::cells::%{_cell}%::reset::locations::%event-location%} is set:
			if {cb2::temp::%uuid of player%::override} is not true:
				Cellblock_Send_Error(player, "You can't break that block as it's part of the Cell")
				cancel event
		else if Cellblock_Flags_Can_Do({_cell}, player, "break") is false:
			Cellblock_Send_Error(player, "You don't have permission to break that block")
			cancel event

on place:
	set {_cell} to Cellblock_Utilities_Cell_At_Location(event-location)
	if {_cell} is set:
		if Cellblock_Flags_Can_Do({_cell}, player, "place") is false:
			cancel event
			Cellblock_Send_Error(player, "You can't place that here")

on right click:
	set {_cell} to Cellblock_Utilities_Cell_At_Location(event-location)
	if {_cell} is set:
		if event-block can hold 1 air:
			if Cellblock_Flags_Can_Do({_cell}, player, "chest") is false:
				cancel event
				Cellblock_Send_Error(player, "You can't access that block")
		else:
			if Cellblock_Flags_Can_Do({_cell}, player, "use") is false:
				cancel event
				Cellblock_Send_Error(player, "You can't use that block")