Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

drink.sprak
string MOVE_DATA = '' # '{"Sebastian_inventory":{"things":{0:"RustyModder",1:"Typer1Modifier",2:"Screwdriver_ScrewDriver"}}}'
bool WILL_TOGGLE_MODIFIER_COPY = false
array WHATS_IN = []
array WHERES = []
string NUMERIC_DATA = '' # '{"Sebastian":{"cash":999,"walkSpeed":10,"sleepiness":0,"wellspring":10,"corruption":0,"drunkenness":0,"smelliness":0}}'
bool COPYING = false
bool SAVING = false
string KEY_COPY_TARGET = "copy_target"
string KEY_NUMERIC_DATA = "numeric_data"
string KEY_SAY = "output_drink"

void main()
	DisconnectAll()
	array results = []
	array outputs = []
	if MOVE_DATA != ""
		loop move(MOVE_DATA)
			Append(results, @)
		end
	end
	if Count(WHERES) > 0
		loop get_rooms_of(WHERES)
			Append(results, @)
		end
	end
	if NUMERIC_DATA != ""
		ARRAY_BUFFER = set_data(NUMERIC_DATA, KEY_NUMERIC_DATA)
		Append(results, ARRAY_BUFFER)
	end
	if Count(results) > 0
		outputs = format_results(results)
	end
	if Count(WHATS_IN) > 0
		STRING_BUFFER = get_things_in(WHATS_IN)
		Append(outputs, STRING_BUFFER)
	end
	if WILL_TOGGLE_MODIFIER_COPY
		STRING_BUFFER = toggle_modifier_copy(KEY_COPY_TARGET)
		Append(outputs, STRING_BUFFER)
	end
	if Count(outputs) > 0
		say(concatenate(outputs, " "), COPYING, SAVING, KEY_SAY)
	end
	DisconnectAll()
end

array ARRAY_BUFFER
array CONNECTION_CACHE = []
array SUPPLIER_CACHE = []
string STRING_BUFFER

main()

# Functions

string concatenate(array strings, string separator)
	string output = ""
	loop strings
		output += @ + separator
	end
	return output
end

string format_result(array either)
	if either[0]
		return either[1]
	end
	return "ERROR: " + either[1]
end

array format_results(array results)
	array output = []
	loop results
		Append(output, format_result(@))
	end
	return output
end

string room_of(string thing)
	if !HasIndex(CONNECTION_CACHE, "GetRoom")
		array overrides = []
		overrides["more_skip_types"] = ["drink"]
		CONNECTION_CACHE["GetRoom"] = supply_unwrapped(overrides, "GetRoom")
	end
	return CONNECTION_CACHE["GetRoom"].GetRoom(thing)
end

bool thing_exists(string thing)
	return room_of(thing) != ""
end

array invalid_thing(string thing)
	return Left('"' + thing + '" is not a valid thing.')
end

number cached_connection(string function)
	if !HasIndex(CONNECTION_CACHE, function)
		CONNECTION_CACHE[function] = supply_unwrapped([], function)
	end
	return CONNECTION_CACHE[function]
end

string cached_supplier(string function)
	if !HasIndex(SUPPLIER_CACHE, function)
		SUPPLIER_CACHE[function] = supplier_of_unwrapped([], function)
	end
	return SUPPLIER_CACHE[function]
end

bool is_person(string person)
	return cached_connection("GetTypeOfThing").GetTypeOfThing(person) == "character"
end

string move_to_thing(string destination, array move_these)
	array output = []
	loop move_these
		if is_person(@)
			string TingrunnerAPI_thing = cached_supplier("MovePerson")
			cached_connection("SetPosition").SetPosition(TingrunnerAPI_thing, @)
			Connect(TingrunnerAPI_thing).MovePerson(@, destination)
		else
			cached_connection("SetPosition").SetPosition(@, destination)
		end
		Append(output, 'Moved "' + @ + '" to "' + destination + '".')
	end
	return concatenate(output, " ")
end

array move(string serialised_schedule)
	array schedule = deserialise(serialised_schedule)
	array destinations = GetIndexes(schedule)
	loop destination in destinations
		if thing_exists(destination)
			array task = schedule[destination]
			loop task["things"]
				if !thing_exists(@)
					return [invalid_thing(@)]
				end
			end
		else
			array things = cached_connection("GetThingsInRoom").GetThingsInRoom(destination)
			number count_things = Count(things)
			if count_things > 0
				array task = schedule[destination]
				number index = 0
				if HasIndex(task, "index")
					index = task["index"]
				end
				if index < 0
					return [Left("`index` should be >= 0.")]
				else if index - Int(index) != 0
					return [Left("`index` should be an integer.")]
				else if index + 1 > count_things
					return [Left("" + (count_things - 1) + 'is the max `index` value for "' + destination + '".')]
				else
					loop task["things"]
						if !thing_exists(@)
							return [invalid_thing(@)]
						end
					end
				end
			else
				return [Left('"' + destination + '" is not a valid destination.')]
			end
		end
	end
	array output = []
	loop destination in destinations
		array task = schedule[destination]
		if thing_exists(destination)
			ARRAY_BUFFER = Right(move_to_thing(destination, task["things"]))
		else
			array things = cached_connection("GetThingsInRoom").GetThingsInRoom(destination)
			number index = 0
			if HasIndex(task, "index")
				index = task["index"]
			end
			ARRAY_BUFFER = Right(move_to_thing(things[index], task["things"]))
		end
		Append(output, ARRAY_BUFFER)
	end
	return output
end

string get_things_in(array rooms)
	array outputs = []
	number TingrunnerAPI = cached_connection("GetThingsInRoom")
	loop rooms
		Append(outputs, 'Serialised list of things in "' + @ + '": ' + "'" + serialise(TingrunnerAPI.GetThingsInRoom(@)) + "'.")
	end
	return concatenate(outputs, " ")
end

array get_rooms_of(array things)
	array outputs = []
	loop things
		if !thing_exists(@)
			return [invalid_thing(@)]
		end
	end
	loop things
		Append(outputs, Right('"' + @ + '" is in "' + room_of(@) + '".'))
	end
	return outputs
end

string toggle_modifier_copy(string key)
	string MemoryAPI_thing = cached_supplier("SaveMemory")
	number MemoryAPI = Connect(MemoryAPI_thing)
	if !MemoryAPI.HasMemory(key)
		MemoryAPI.SaveMemory(key, false)
	end
	bool copying_target = MemoryAPI.LoadMemory(key)
	MemoryAPI.SaveMemory(key, !copying_target)
	return 'The value accessed by the key "' + key + '" on the server "' + MemoryAPI_thing + '" was set to `' + (!copying_target) + "`."
end

array set_data(string serialised_data, string key)
	array data = deserialise(serialised_data)
	array things = GetIndexes(data)
	loop thing in things
		if !thing_exists(thing)
			return invalid_thing(thing)
		end
		array data_points = data[thing]
		loop key_data_point in GetIndexes(data_points)
			if Type(data_points[key_data_point]) != "number"
				return Left("`" + thing + "[" + key_data_point + "]` should be set to a numeric value.")
			end
			if key_data_point == "cash" || key_data_point == "wellspring"
			if !is_person(thing)
				return Left('"' + thing + '" is not a valid person.')
			end
			end
		end
	end
	string MemoryAPI_thing = cached_supplier("SaveMemory")
	Connect(MemoryAPI_thing).SaveMemory(key, serialised_data)
	return Right('The value accessed by the key "' + key + '" on the server "' + MemoryAPI_thing + '" was set to "' + serialised_data + '".')
end

void say(string output, bool copying, bool saving, string key)
	if output != ""
		if copying
			if !HasIndex(CONNECTION_CACHE, "CopyToClipboard")
				array overrides = []
				overrides["more_skip_types"] = ["taser"]
				CONNECTION_CACHE["CopyToClipboard"] = supply_unwrapped(overrides, "CopyToClipboard")
			end
			if saving
				CONNECTION_CACHE["CopyToClipboard"].CopyToClipboard(output)
				string MemoryAPI_thing = cached_supplier("SaveMemory")
				Connect(MemoryAPI_thing).SaveMemory(key, output)
				Say('The following was copied to the clipboard and saved to "' + MemoryAPI_thing + '" using the key "' + key + '": ' + output)
			else
				CONNECTION_CACHE["CopyToClipboard"].CopyToClipboard(output)
				Say("Copied: " + output)
			end
		else if saving
			string MemoryAPI_thing = cached_supplier("SaveMemory")
			Connect(MemoryAPI_thing).SaveMemory(key, output)
			Say('The following was saved to "' + MemoryAPI_thing + '" using the key "' + key + '": ' + output)
		else
			Say(output)
		end
	end
end

# Imports

###############
# serde.sprak #
###############
string serialise_string(string input)
	string output = ""
	loop character in input
		if character == '"' 
			output += "\"
		else if character == "\"
			output += "\"
		end
		output += character
	end
	return '"' + output + '"'
end

string serialise_array(array input)
	string output = ""
	bool not_start = false
	loop key in GetIndexes(input)
		if Type(key) != "array"
			if not_start
				output += ","
			else
				not_start = true
			end
			output += serialise(key) + ":" + serialise(input[key])
		end
	end
	return "{" + output + "}"
end

string serialise(var input)
	string input_type = Type(input)
	if input_type == "unknown"
		string output = ""
		loop character in "" + input
			if character != "i"
				output += character
			end
		end
		return output
	else if input_type == "string"
		return serialise_string(input)
	else if input_type == "number"
		return "" + input
	else if input_type == "bool"
		if input
			return "t"
		end
		return "f"
	else if input_type == "array"
		return serialise_array(input)
	end
end

string deserialise_string(string input)
	string output = ""
	bool escaped = false
	loop character in input
		if !escaped
			if character == '\'
				escaped = true
			else if character != '"'
				output += character
			end
		else
			output += character
			escaped = false
		end
	end
	return output
end

bool is_digit(string input)
	array digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
	loop digits
		if input == @
			return true
		end
	end
	return false
end

bool is_numeric(string character)
	if is_digit(character)
		return true
	else if character == "-"
		return true
	else if character == "."
		return true
	else
		return false
	end
end

# Types:
# * 0: none
# * 1: bool
# * 2: number
# * 3: string
# * 4: array
array deserialise_array(string input)
	array accumulator = []
	bool in_string = false
	bool escaped = false
	bool in_value = false
	string buffer = ""
	number key_type = 0
	bool key_bool = false
	number key_number = 0
	string key_string = ""
	number value_type = 0
	bool value_bool = false
	number value_number = 0
	string value_string = ""
	array contexts = []
	loop character in input
		if character == '"'
			if !in_string
				in_string = true
				if in_value
					value_type = 3
				else
					key_type = 3
				end
			else if !escaped
				in_string = false
			else if in_value
				value_string += '"'
			else
				key_string += '"'
			end
		else if character == "t"
			if !in_string
				if in_value
					value_bool = true
					value_type = 1
				else
					key_bool = true
					key_type = 1
				end
			else if in_value
				value_string += "t"
			else
				key_string += "t"
			end
		else if character == "f"
			if !in_string
				if in_value
					value_bool = false
					value_type = 1
				else
					key_bool = false
					key_type = 1
				end
			else if in_value
				value_string += "f"
			else
				key_string += "f"
			end
		else if character == ":"
			if !in_string
				in_value = true
				if key_type == 2
					key_number = buffer
					buffer = ""
				end
			else if in_value
				value_string += ":"
			else
				key_string += ":"
			end
		else if character == ","
			if !in_string
				if key_type == 2
					if value_type == 3
						accumulator[key_number] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_number] = value_number
					else if value_type == 1
						accumulator[key_number] = value_bool
					end
				else if key_type == 3
					if value_type == 3
						accumulator[key_string] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_string] = value_number
					else if value_type == 1
						accumulator[key_string] = value_bool
					end
				else if key_type == 1
					if value_type == 3
						accumulator[key_bool] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_bool] = value_number
					else if value_type == 1
						accumulator[key_bool] = value_bool
					end
				end
				in_value = false
				buffer = ""
				key_string = ""
				value_string = ""
			else if in_value
				value_string += ","
			else
				key_string += ","
			end
		else if is_numeric(character)
			if !in_string
				buffer += character
				if in_value
					value_type = 2
				else
					key_type = 2
				end
			else if in_value
				value_string += character
			else
				key_string += character
			end
		else if character == "{"
			if !in_string
				if key_type == 2
					Append(contexts, [accumulator, key_type, key_number])
				else if key_type == 3
					Append(contexts, [accumulator, key_type, key_string])
				else if key_type == 0
					Append(contexts, [accumulator, key_type])
				else
					Append(contexts, [accumulator, key_type, key_bool])
				end
				accumulator = []
				in_string = false
				escaped = false
				in_value = false
				buffer = ""
				key_type = 0
				key_bool = false
				key_number = 0
				key_string = ""
				value_type = 0
				value_bool = false
				value_number = 0
				value_string = ""
			else
				value_string += "{"
			end
		else if character == "}"
			if !in_string
				if key_type == 2
					if value_type == 3
						accumulator[key_number] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_number] = value_number
					else if value_type == 1
						accumulator[key_number] = value_bool
					end
				else if key_type == 3
					if value_type == 3
						accumulator[key_string] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_string] = value_number
					else if value_type == 1
						accumulator[key_string] = value_bool
					end
				else if key_type == 1
					if value_type == 3
						accumulator[key_bool] = value_string
					else if value_type == 2
						value_number = buffer
						accumulator[key_bool] = value_number
					else if value_type == 1
						accumulator[key_bool] = value_bool
					end
				end
				array last_context = contexts[Count(contexts) - 1]
				array last_accumulator = last_context[0]
				number last_key_type = last_context[1]
				if last_key_type != 0
					last_accumulator[last_context[2]] = accumulator
				else
					return accumulator
				end
				accumulator = last_accumulator
				value_type = 4
				Remove(contexts, Count(contexts) - 1)
			else
				value_string += "}"
			end
		else if character == "\"
			if !escaped
				escaped = true
			else
				escaped = false
				if in_value
					value_string += "\"
				else
					key_string += "\"
				end
			end
		else if in_value
			value_string += character
		else
			key_string += character
		end
	end
end

var deserialise(string input)
	string head = input[0]
	if head == "{"
		return deserialise_array(input)
	else if is_numeric(head)
		number output = input
		return output
	else if head == '"'
		return deserialise_string(input)
	else if head == "t"
		return true
	else if head == "f"
		return false
	end
end

##################
# equality.sprak #
##################
bool equal_array(array first, array second)
	if Count(first) == Count(second)
		loop key in GetIndexes(first)
			if !HasIndex(second, key)
				return false
			else if !equal(first[key], second[key])
				return false
			end
		end
		return true
	end
	return false
end

bool equal(var first, var second)
	string type_first = Type(first)
	if type_first == Type(second)
		if type_first != "array"
			return first == second
		end
		return equal_array(first, second)
	end
	return false
end

###############
# array.sprak #
###############
bool has(array arr, var element)
	loop arr
		if equal(@, element)
			return true
		end
	end
	return false
end

###############
# types.sprak #
###############
array Left(var input)
	return [false, input]
end

array Right(var input)
	return [true, input]
end

################
# supply.sprak #
################
array supplier_of(array overrides, string function)
	string MemoryAPI_thing = "FinanceComputer"
	string TingrunnerAPI_thing = "PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1"
	if HasIndex(overrides, "MemoryAPI")
		MemoryAPI_thing = overrides["MemoryAPI"]
	end
	if HasIndex(overrides, "TingrunnerAPI")
		TingrunnerAPI_thing = overrides["TingrunnerAPI"]
	end
	number MemoryAPI = Connect(MemoryAPI_thing)
	number TingrunnerAPI = Connect(TingrunnerAPI_thing)
	array skip_types = []
	loop ["floppy", "navnode", "bed", "point", "seat", "locker", "memory", "portal", "character", "map", "suitcase", "goods"]
		Append(skip_types, @)
	end
	array skip_things = []
	loop ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]
		Append(skip_things, @)
	end
	string load_buffer = ""
	if !HasIndex(overrides, "skip_types")
		if MemoryAPI.HasMemory("skip_types")
			load_buffer = MemoryAPI.LoadMemory("skip_types")
			RemoveAll(skip_types)
			loop deserialise(load_buffer)
				Append(skip_types, @)
			end
		end
	else
		RemoveAll(skip_types)
		loop overrides["skip_types"]
			Append(skip_types, @)
		end
	end
	if !HasIndex(overrides, "skip_things")
		if MemoryAPI.HasMemory("skip_things")
			load_buffer = MemoryAPI.LoadMemory("skip_things")
			RemoveAll(skip_things)
			loop deserialise(load_buffer)
				Append(skip_things, @)
			end
		end
	else
		RemoveAll(skip_things)
		loop overrides["skip_things"]
			Append(skip_things, @)
		end
	end
	if HasIndex(overrides, "more_skip_types")
		loop overrides["more_skip_types"]
			if !has(skip_types, @)
				Append(skip_types, @)
			end
		end
	end
	if HasIndex(overrides, "more_skip_things")
		loop overrides["more_skip_things"]
			if !has(skip_things, @)
				Append(skip_things, @)
			end
		end
	end
	if MemoryAPI.HasMemory(function)
		load_buffer = MemoryAPI.LoadMemory(function)
		if !has(skip_things, load_buffer)
		if !has(skip_types, TingrunnerAPI.GetTypeOfThing(load_buffer))
			if Connect(load_buffer).HasFunction(function)
				return Right(load_buffer)
			end
		end
		end
	end
	load_buffer = ""
	loop room in TingrunnerAPI.GetAllRooms()
		loop thing in TingrunnerAPI.GetThingsInRoom(room)
			if !has(skip_things, thing)
			if !has(skip_types, TingrunnerAPI.GetTypeOfThing(thing))
				if Connect(thing).HasFunction(function)
					MemoryAPI.SaveMemory(function, thing)
					return Right(thing)
				end
			end
			end
		end
	end
	return Left("`" + function + "` not found.")
end

string supplier_of_unwrapped(array overrides, string function)
	array array_buffer = supplier_of(overrides, function)
	return array_buffer[1]
end

array supply(array overrides, string function)
	array array_buffer = supplier_of(overrides, function)
	if array_buffer[0]
		return Right(Connect(array_buffer[1]))
	else
		return Left(array_buffer[1])
	end
end

number supply_unwrapped(array overrides, string function)
	array array_buffer = supply(overrides, function)
	return array_buffer[1]
end