2: Add programs for drink, modifier, screwdriver and server.
[?]
9Zb2bmkejrNknawUtr3MKvVstZkVDR8x8ritfgZXKrky
Oct 1, 2022, 8:53 AM
S7BXWG4QQMJ6M4XDUNDLJGD4BXB4QVZKXWSHXXVGKMNDWB5WV5LQCDependencies
Change contents
- file addition: types.sprak[3.2]
################ types.sprak ################array Left(var input)return [false, input]endarray Right(var input)return [true, input]end - file addition: types.md[3.2]
# types.sprakLibrary of types.## Functions### `Left`Constructor for the `Left` variant of the `Either` type#### Type`A -> [false, A]`#### Arguments* `input`: Value to wrap in the `Either` type.#### Examples```sprak# TODO```### `Right`Constructor for the `Reft` variant of the `Either` type#### Type`A -> [true, A]`#### Arguments* `input`: Value to wrap in the `Either` type.#### Examples```sprak# TODO``` - edit in test.md at line 2
- edit in test.md at line 8
### Imports* equality.sprak - replacement in test.md at line 22
#### Imports* equality.sprak[3.701]## TODO* Add option to copy output to clipboard. - replacement in supply.sprak at line 8
if character != "\"if character != '"'output += characterendelse if escapedif !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelse - edit in supply.sprak at line 17
else if character == '\'escaped = true - replacement in supply.sprak at line 23
number code = CharToInt(input)if code >= -49if code <= -40return truearray digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueend - edit in supply.sprak at line 29
end - replacement in supply.sprak at line 38
var deserialise_array(string input)array deserialise_array(string input) - edit in supply.sprak at line 40
bool is_numeric = false - replacement in supply.sprak at line 55
bool is_numeric = falseif character == ":"if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":" - edit in supply.sprak at line 155
else if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"end - edit in supply.sprak at line 159
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in supply.sprak at line 161
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in supply.sprak at line 167
is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = "" - edit in supply.sprak at line 256
is_numeric = false - edit in supply.sprak at line 284
if "" + first == "" + second - edit in supply.sprak at line 292
end - replacement in supply.sprak at line 310
bool has(var test_element, array input)loop element in inputif equal(element, test_element)bool has(array arr, var element)loop arrif equal(@, element) - edit in supply.sprak at line 317
end################ types.sprak ################array Left(var input)return [false, input] - replacement in supply.sprak at line 326
############## Functions ##############array supply(array overrides, string function)array Right(var input)return [true, input]end################# supply.sprak #################array supplier_of(array overrides, string function) - edit in supply.sprak at line 336
string name = Name() - replacement in supply.sprak at line 342
var MemoryAPIif MemoryAPI_thing != nameMemoryAPI = Connect(MemoryAPI_thing)elsereturn [false, "MemoryAPI unavailable."]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, @) - replacement in supply.sprak at line 348
var TingrunnerAPIif TingrunnerAPI_thing != nameTingrunnerAPI = Connect(TingrunnerAPI_thing)elsereturn [false, "TingrunnerAPI unavailable."]array skip_things = []loop ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]Append(skip_things, @) - replacement in supply.sprak at line 352
array skip_types = ["floppy", "navnode", "bed", "point", "seat", "locker", "memory", "portal", "character", "map", "suitcase", "goods"]array skip_things = ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]var load_bufferstring load_buffer = "" - replacement in supply.sprak at line 354
load_buffer = MemoryAPI.LoadMemory("skip_types")if load_buffer != 0skip_types = deserialise(load_buffer)if MemoryAPI.HasMemory("skip_types")load_buffer = MemoryAPI.LoadMemory("skip_types")RemoveAll(skip_types)loop deserialise(load_buffer)Append(skip_types, @)end - replacement in supply.sprak at line 362
skip_types = overrides["skip_types"]RemoveAll(skip_types)loop overrides["skip_types"]Append(skip_types, @)end - replacement in supply.sprak at line 368
load_buffer = MemoryAPI.LoadMemory("skip_things")if load_buffer != 0skip_things = deserialise(load_buffer)if MemoryAPI.HasMemory("skip_things")load_buffer = MemoryAPI.LoadMemory("skip_things")RemoveAll(skip_things)loop deserialise(load_buffer)Append(skip_things, @)end - replacement in supply.sprak at line 376
skip_things = overrides["skip_things"]RemoveAll(skip_things)loop overrides["skip_things"]Append(skip_things, @)end - replacement in supply.sprak at line 382
loop type in overrides["more_skip_types"]if !has(type, skip_types)Append(skip_types, type)loop overrides["more_skip_types"]if !has(skip_types, @)Append(skip_types, @) - replacement in supply.sprak at line 389
loop thing in overrides["more_skip_things"]if !has(thing, skip_things)Append(skip_things, thing)loop overrides["more_skip_things"]if !has(skip_things, @)Append(skip_things, @) - replacement in supply.sprak at line 395
load_buffer = MemoryAPI.LoadMemory(function)if load_buffer != 0if load_buffer != nameif !has(load_buffer, skip_things)if !has(TingrunnerAPI.GetTypeOfThing(load_buffer), skip_types)var connection = Connect(load_buffer)if connection.HasFunction(function)return [true, connection]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)endend - edit in supply.sprak at line 404
endend - replacement in supply.sprak at line 405
endload_buffer = 0load_buffer = "" - replacement in supply.sprak at line 408
if thing != nameif !has(thing, skip_things)if !has(TingrunnerAPI.GetTypeOfThing(thing), skip_types)var connection = Connect(thing)if connection.HasFunction(function)if !has(skip_things, thing)if !has(skip_types, TingrunnerAPI.GetTypeOfThing(thing))if Connect(thing).HasFunction(function) - replacement in supply.sprak at line 412
return [true, connection]return Right(thing) - edit in supply.sprak at line 414
end - replacement in supply.sprak at line 418
return [false, "`" + function + "` not found."]return Left("`" + function + "` not found.")endstring supplier_of_unwrapped(array overrides, string function)array array_buffer = supplier_of(overrides, function)return array_buffer[1]endarray supply(array overrides, string function)array array_buffer = supplier_of(overrides, function)if array_buffer[0]return Right(Connect(array_buffer[1]))elsereturn Left(array_buffer[1])endendnumber supply_unwrapped(array overrides, string function)array array_buffer = supply(overrides, function)return array_buffer[1] - edit in supply.md at line 2
- edit in supply.md at line 5
- edit in supply.md at line 7
* May fail if the thing containing the function found is the same thing that is programmed with this program. `Name()` function isn't used to detect this as that isn't available in all things. Use `overrides` to skip these things instead. - edit in supply.md at line 10
### Imports* serde.sprak* `deserialise`* equality.sprak* array.sprak* `has`* types.sprak* `Left`* `Right`### `supplier_of`Returns `Either(string, string)` where `Right` is the name of a thing that supplies the input function if anything in the game world is able to supply the function, and `Left` is a error message about what caused the failure. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function.#### Type`["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> Either(string, string)`#### Arguments* `overrides`: `array` that may contain data to replace or supplement variables used by the function.* `function`: Function to find a supplier of.#### Examples```sprakarray array_buffer = supplier_of([], "IsNight")string supplier = array_buffer[1]Say(Connect(supplier).IsNight())``` - edit in supply.md at line 34
### `supplier_of_unwrapped`Returns a `string` representing the name of a thing that supplies the input function. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function. May fail silently if nothing in the game world is able to supply the function.#### Type`["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> string`#### Arguments* `overrides`: `array` that may contain data to replace or supplement variables used by the function.* `function`: Function to find a supplier of.#### Examples```sprakstring supplier = supplier_of_unwrapped([], "IsNight")Say(Connect(supplier).IsNight())``` - replacement in supply.md at line 48
Returns `[true, connection]` where `connection` is a connection to a thing that supplies the input function if anything in the game world is able to supply the function, otherwise `[false, error_message]` where `error_message` is a `string` about what caused the failure. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function.Returns `Either(string, number)` where `Right` is the connection to a thing that supplies the input function if anything in the game world is able to supply the function, and `Left` is an error message about what caused the failure. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function. - replacement in supply.md at line 50
`["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> [true, connection] | [false, string]``["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> Either(string, number)` - replacement in supply.md at line 56
var connection = supply([], "IsNight")Say("" + connection[1].IsNight())array array_buffer = supply([], "IsNight")number connection = array_buffer[1]Say(connection.IsNight()) - replacement in supply.md at line 60
#### Imports* serde.sprak* `deserialise`* equality.sprak* array.sprak* `has`[3.11178]### `supply_unwrapped`Returns a `number` representing the connection to a thing that supplies the input function. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function. May fail silently if nothing in the game world is able to supply the function.#### Type`["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> number`#### Arguments* `overrides`: `array` that may contain data to replace or supplement variables used by the function.* `function`: Function to find a connection for.#### Examples```sprakstring connection = supply_unwrapped([], "IsNight")Say(connection.IsNight())``` - replacement in skip.sprak at line 1
DisconnectAll()main()void main()DisconnectAll()ClearText()string MemoryAPI_thing = "FinanceComputer"string TingrunnerAPI_thing = "PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1"string name = Name()number MemoryAPI = Connect(MemoryAPI_thing)number TingrunnerAPI = Connect(TingrunnerAPI_thing)array skip_types = []skip_types[0] = "floppy"array skip_things = []string load_buffer = ""if MemoryAPI.HasMemory("skip_types")load_buffer = MemoryAPI.LoadMemory("skip_types")RemoveAll(skip_types)loop deserialise(load_buffer)Append(skip_types, @)endendif MemoryAPI.HasMemory("skip_things")load_buffer = MemoryAPI.LoadMemory("skip_things")RemoveAll(skip_things)loop deserialise(load_buffer)Append(skip_things, @)endendload_buffer = ""bool seen_last_thing = falsestring last_thing = ""number number_buffer = Count(skip_things)if number_buffer > 0last_thing = skip_things[number_buffer - 1]elseseen_last_thing = trueendloop room in TingrunnerAPI.GetAllRooms()loop thing in TingrunnerAPI.GetThingsInRoom(room)if seen_last_thingstring thing_type = TingrunnerAPI.GetTypeOfThing(thing)if thing != nameif !has(skip_types, thing_type)if !has(skip_things, thing)Append(skip_things, thing)MemoryAPI.SaveMemory("skip_things", serialise(skip_things))if no_SprakAPI(thing)Append(skip_types, thing_type)MemoryAPI.SaveMemory("skip_types", serialise(skip_types))endRemove(skip_things, Count(skip_things) - 1)endendendelse if thing == last_thingseen_last_thing = trueendendendMemoryAPI.SaveMemory("skip_things", serialise(skip_things))Say("Done.")DisconnectAll()endbool no_SprakAPI(string thing)return Connect(thing).HasFunction("") == 0end - replacement in skip.sprak at line 129
if character != "\"if character != '"'if !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelse - edit in skip.sprak at line 137
endelse if escapedoutput += character - edit in skip.sprak at line 138
else if character == '\'escaped = true - replacement in skip.sprak at line 144
number code = CharToInt(input)if code >= -49if code <= -40return trueendarray digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueend - replacement in skip.sprak at line 159
var deserialise_array(string input)array deserialise_array(string input) - edit in skip.sprak at line 161
bool is_numeric = false - replacement in skip.sprak at line 176
bool is_numeric = falseif character == ":"if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":" - edit in skip.sprak at line 276
else if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"end - edit in skip.sprak at line 280
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in skip.sprak at line 282
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in skip.sprak at line 288
is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = "" - edit in skip.sprak at line 377
is_numeric = false - edit in skip.sprak at line 405
if "" + first == "" + second - edit in skip.sprak at line 414
end - replacement in skip.sprak at line 431
bool has(array input, var test_element)loop element in inputif equal(element, test_element)bool has(array arr, var element)loop arrif equal(@, element) - edit in skip.sprak at line 438
end############## Functions ##############bool no_SprakAPI(string thing)return Connect(thing).HasFunction("") == 0end######### Main #########ClearText()string name = Name()string MemoryAPI = Connect("FinanceComputer")string TingrunnerAPI = Connect("PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1")array skip_types = []skip_types[0] = "floppy"array skip_things = []var load_buffer = MemoryAPI.LoadMemory("skip_types")if load_buffer != 0skip_types = deserialise(load_buffer)endload_buffer = MemoryAPI.LoadMemory("skip_things")if load_buffer != 0skip_things = deserialise(load_buffer) - edit in skip.sprak at line 439
load_buffer = 0bool seen_last_thing = falsestring last_thing = ""number number_buffer = Count(skip_things)if number_buffer > 0last_thing = skip_things[number_buffer - 1]elseseen_last_thing = trueendloop room in TingrunnerAPI.GetAllRooms()loop thing in TingrunnerAPI.GetThingsInRoom(room)if seen_last_thingstring thing_type = TingrunnerAPI.GetTypeOfThing(thing)if thing != nameif !has(skip_types, thing_type)if !has(skip_things, thing)Append(skip_things, thing)MemoryAPI.SaveMemory("skip_things", serialise(skip_things))if no_SprakAPI(thing)Append(skip_types, thing_type)MemoryAPI.SaveMemory("skip_types", serialise(skip_types))endRemove(skip_things, Count(skip_things) - 1)endendendelse if thing == last_thingseen_last_thing = trueendendendMemoryAPI.SaveMemory("skip_things", serialise(skip_things))Say("Done.")DisconnectAll() - edit in skip.md at line 2
- edit in skip.md at line 5
- edit in skip.md at line 11
### Imports* serde.sprak* equality.sprak* array.sprak* `has` - replacement in skip.md at line 26
```## Imports* supply.sprak* `hardcoded_supply`* serde.sprak* equality.sprak* array.sprak* `has`[3.21634]``` - file addition: server.sprak[3.2]
string KEY_NUMERIC_DATA = "numeric_data"void main()DisconnectAll()ClearText()string data_serialised = ""array data = []string load_buffer = ""number MemoryAPI = supply_unwrapped([], "LoadMemory")number FinanceAPI = supply_unwrapped([], "ChangeBalance")number WellspringAPI = supply_unwrapped([], "RegisterSeller")number HeartAPI = supply_unwrapped([], "SetNumericData")array things = []array data_points = []loopif MemoryAPI.HasMemory(KEY_NUMERIC_DATA)load_buffer = MemoryAPI.LoadMemory(KEY_NUMERIC_DATA)if data_serialised != load_bufferdata_serialised = load_bufferdata = deserialise(data_serialised)endthings = GetIndexes(data)loop thing in thingsdata_points = data[thing]loop key_data_point in GetIndexes(data_points)if key_data_point == "cash"FinanceAPI.SaveMemory(thing, data_points[key_data_point])else if key_data_point == "wellspring"WellspringAPI.RegisterSeller(thing, data_points[key_data_point])elseHeartAPI.SetNumericData(thing, key_data_point, data_points[key_data_point])endendendendSleep(1)endendmain()# Imports################ serde.sprak ################string deserialise_string(string input)string output = ""bool escaped = falseloop character in inputif !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelseoutput += characterescaped = falseendendreturn outputendbool is_digit(string input)array digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueendendreturn falseend# Types:# * 0: none# * 1: bool# * 2: number# * 3: string# * 4: arrayarray deserialise_array(string input)array accumulator = []bool is_numeric = falsebool in_string = falsebool escaped = falsebool in_value = falsestring buffer = ""number key_type = 0bool key_bool = falsenumber key_number = 0string key_string = ""number value_type = 0bool value_bool = falsenumber value_number = 0string value_string = ""array contexts = []loop character in inputif character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":"if !in_stringin_value = trueif key_type == 2key_number = bufferbuffer = ""endelse if in_valuevalue_string += ":"elsekey_string += ":"endelse if character == ","if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendin_value = falsebuffer = ""key_string = ""value_string = ""else if in_valuevalue_string += ","elsekey_string += ","endelse if is_digit(character)is_numeric = trueelse if character == "."is_numeric = trueelse if character == "-"is_numeric = trueelse if character == "{"if !in_stringif key_type == 2Append(contexts, [accumulator, key_type, key_number])else if key_type == 3Append(contexts, [accumulator, key_type, key_string])else if key_type == 0Append(contexts, [accumulator, key_type])elseAppend(contexts, [accumulator, key_type, key_bool])endaccumulator = []is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = ""elsevalue_string += "{"endelse if character == "}"if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendarray last_context = contexts[Count(contexts) - 1]array last_accumulator = last_context[0]number last_key_type = last_context[1]if last_key_type != 0last_accumulator[last_context[2]] = accumulatorelsereturn accumulatorendaccumulator = last_accumulatorvalue_type = 4Remove(contexts, Count(contexts) - 1)elsevalue_string += "}"endelse if character == "\"if !escapedescaped = trueelseescaped = falseif in_valuevalue_string += "\"elsekey_string += "\"endendelse if in_valuevalue_string += characterelsekey_string += characterendif is_numericif !in_stringbuffer += characterif in_valuevalue_type = 2elsekey_type = 2endelse if in_valuevalue_string += characterelsekey_string += characterendis_numeric = falseendendendvar deserialise(string input)if input[0] == "{"return deserialise_array(input)else if is_digit(input[0])number output = inputreturn outputelse if input[0] == "-"number output = inputreturn outputelse if input[0] == '"'return deserialise_string(input)else if input == "t"return trueelse if input == "f"return falseendend################### equality.sprak ###################bool equal_array(array first, array second)if Count(first) == Count(second)loop key in GetIndexes(first)if !HasIndex(second, key)return falseelse if !equal(first[key], second[key])return falseendendreturn trueendreturn falseendbool equal(var first, var second)string type_first = Type(first)if type_first == Type(second)if type_first != "array"return first == secondendreturn equal_array(first, second)endreturn falseend################ array.sprak ################bool has(array arr, var element)loop arrif equal(@, element)return trueendendreturn falseend################ types.sprak ################array Left(var input)return [false, input]endarray 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"]endif HasIndex(overrides, "TingrunnerAPI")TingrunnerAPI_thing = overrides["TingrunnerAPI"]endnumber 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, @)endarray skip_things = []loop ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]Append(skip_things, @)endstring 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, @)endendelseRemoveAll(skip_types)loop overrides["skip_types"]Append(skip_types, @)endendif !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, @)endendelseRemoveAll(skip_things)loop overrides["skip_things"]Append(skip_things, @)endendif HasIndex(overrides, "more_skip_types")loop overrides["more_skip_types"]if !has(skip_types, @)Append(skip_types, @)endendendif HasIndex(overrides, "more_skip_things")loop overrides["more_skip_things"]if !has(skip_things, @)Append(skip_things, @)endendendif 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)endendendendload_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)endendendendendreturn Left("`" + function + "` not found.")endarray supply(array overrides, string function)array array_buffer = supplier_of(overrides, function)if array_buffer[0]return Right(Connect(array_buffer[1]))elsereturn Left(array_buffer[1])endendnumber supply_unwrapped(array overrides, string function)array array_buffer = supply(overrides, function)return array_buffer[1]end - file addition: server.md[3.2]
# server.sprakAllows computers programmed with it to set the numeric data of things, as set by the `NUMERIC_DATA` variable in "drink.sprak".## Usage* May fail if the `supply` function supplies a function from the same server, since `Name()` is not used to check this.## Functions### Imports* serde.sprak* `deserialise`* equality.sprak* array.sprak* `has`* types.sprak* `Left`* `Right`* supply.sprak* `supplier_of`* `supply`* `supply_unwrapped` - replacement in serde.tests.sprak at line 5
if Count(first) == Count(second) && "" + first == "" + secondif Count(first) == Count(second) - replacement in serde.tests.sprak at line 114
array a = []array aarray barray ca = deserialise_array('{}')Append(tests, [a, []]) - replacement in serde.tests.sprak at line 123
a = deserialise_array('{0:"a"}')Append(tests, [a, ["a"]])a = deserialise_array('{0:""}')Append(tests, [a, [""]])a = deserialise_array('{0:"abc"}')Append(tests, [a, ["abc"]]) - replacement in serde.tests.sprak at line 127
a = deserialise_array('{}')Append(tests, [a, []])a = deserialise_array('{0:f,1:t}')Append(tests, [a, [false,true]])a = deserialise_array('{0:0,1:-273.15}')Append(tests, [a, [0,-273.15]])a = deserialise_array('{0:"abc",1:"def"}')Append(tests, [a, ["abc","def"]])a = deserialise_array('{0:{},1:{}}')Append(tests, [a, [[],[]]])a = deserialise_array('{f:f,t:t}')b = []b[false] = falseb[true] = trueAppend(tests, [a, b])a = deserialise_array('{f:0,t:-273.15}')b = []b[false] = 0b[true] = -273.15Append(tests, [a, b])a = deserialise_array('{f:"abc",t:"def"}')b = []b[false] = "abc"b[true] = "def"Append(tests, [a, b])a = deserialise_array('{f:{},t:{}}')b = []b[false] = []b[true] = []Append(tests, [a, b])a = deserialise_array('{0:f,-273.15:t}')b = []b[0] = falseb[-273.15] = trueAppend(tests, [a, b])a = deserialise_array('{0:0,-273.15:-273.15}')b = []b[0] = 0b[-273.15] = -273.15Append(tests, [a, b])a = deserialise_array('{0:"abc",-273.15:"def"}')b = []b[0] = "abc"b[-273.15] = "def"Append(tests, [a, b])a = deserialise_array('{0:{},-273.15:{}}')b = []b[0] = []b[-273.15] = []Append(tests, [a, b])a = deserialise_array('{"abc":f,"def":t}')b = []b["abc"] = falseb["def"] = trueAppend(tests, [a, b])a = deserialise_array('{"abc":0,"def":-273.15}')b = []b["abc"] = 0b["def"] = -273.15Append(tests, [a, b])a = deserialise_array('{"abc":"abc","def":"def"}')b = []b["abc"] = "abc"b["def"] = "def"Append(tests, [a, b])a = deserialise_array('{"abc":{},"def":{}}')b = []b["abc"] = []b["def"] = []Append(tests, [a, b])a = deserialise_array('{"a":{"b":f}}')b = []c = []c["b"] = falseb["a"] = cAppend(tests, [a, b]) - replacement in serde.sprak at line 61
if character != "\"if character != '"'if !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelse - edit in serde.sprak at line 69
endelse if escapedoutput += character - edit in serde.sprak at line 70
else if character == '\'escaped = true - replacement in serde.sprak at line 76
number code = CharToInt(input)if code >= -49if code <= -40return trueendarray digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueend - replacement in serde.sprak at line 91
var deserialise_array(string input)array deserialise_array(string input) - edit in serde.sprak at line 93
bool is_numeric = false - replacement in serde.sprak at line 108
bool is_numeric = falseif character == ":"if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":" - edit in serde.sprak at line 208
else if character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"end - edit in serde.sprak at line 212
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in serde.sprak at line 214
else if key_type == 0Append(contexts, [accumulator, key_type]) - edit in serde.sprak at line 220
is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = "" - edit in serde.sprak at line 309
is_numeric = false - replacement in serde.sprak at line 330
end[3.32441]end - edit in serde.md at line 2
- edit in serde.md at line 5
- replacement in serde.md at line 6
Returns the serialised form of input where `\` and `"` characters have been prepended with `\`.Returns the serialised form of a string input where `\` and `"` characters have been prepended with `\`. - replacement in serde.md at line 53
Determines if the input character is a numeric digit.Determines if the input character is a numeric digit. `CharToInt` isn't used as this isn't always available. - replacement in serde.md at line 100
* Replace recursions with iterations in:* `serialise_array` and `serialise`* Add an option to serialise numbers using more precision.[3.35076]* Handle failures during deserialisations by outputting `[true, parse]` or `[false, error]`.* Replace mutual recursions with iterations in:* `serialise_array` and `serialise` - file addition: screwdriver.sprak[3.2]
array APIs = []Append(APIs, "arcade")Append(APIs, "door")Append(APIs, "floppy")Append(APIs, "internet")Append(APIs, "memory")main()void main()SetMaxTime(-2)SetMhz(500)loop APIsEnableAPI(@)endend - file addition: screwdriver.md[3.2]
# screwdriver.sprakAllows screwdrivers programmed with it, when used on computers, to set their execution times to infinite, their clockspeed to 500 MHz, and enables the "arcade", "door", "floppy", "internet" and "memory" APIs on them. - file addition: modifier.sprak[3.2]
string KEY_COPY_TARGET = "copy_target"bool Allow(string target, number level)DisconnectAll()number connection_target = Connect(target)number TingrunnerAPI = supply_unwrapped([], "GetTypeOfThing")number MemoryAPI = supply_unwrapped([], "LoadMemory")array overrides = []overrides["more_skip_types"] = ["key"]number DoorAPI = supply_unwrapped(overrides, "Lock")overrides["more_skip_types"] = ["taser"]number connection_extractor = supply_unwrapped(overrides, "CopyToClipboard")if TingrunnerAPI.GetTypeOfThing(target) == "door"if MemoryAPI.LoadMemory("lock " + target)DoorAPI.Unlock(target)MemoryAPI.SaveMemory("lock " + target, false)connection_target.Say(target + " unlocked.")elseDoorAPI.Lock(target)MemoryAPI.SaveMemory("lock " + target, true)connection_target.Say(target + " locked.")endendif MemoryAPI.HasMemory(KEY_COPY_TARGET)if MemoryAPI.LoadMemory(KEY_COPY_TARGET)connection_extractor.CopyToClipboard(target)endendDisconnectAll()return trueend################ serde.sprak ################string deserialise_string(string input)string output = ""bool escaped = falseloop character in inputif !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelseoutput += characterescaped = falseendendreturn outputendbool is_digit(string input)array digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueendendreturn falseend# Types:# * 0: none# * 1: bool# * 2: number# * 3: string# * 4: arrayarray deserialise_array(string input)array accumulator = []bool is_numeric = falsebool in_string = falsebool escaped = falsebool in_value = falsestring buffer = ""number key_type = 0bool key_bool = falsenumber key_number = 0string key_string = ""number value_type = 0bool value_bool = falsenumber value_number = 0string value_string = ""array contexts = []loop character in inputif character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":"if !in_stringin_value = trueif key_type == 2key_number = bufferbuffer = ""endelse if in_valuevalue_string += ":"elsekey_string += ":"endelse if character == ","if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendin_value = falsebuffer = ""key_string = ""value_string = ""else if in_valuevalue_string += ","elsekey_string += ","endelse if is_digit(character)is_numeric = trueelse if character == "."is_numeric = trueelse if character == "-"is_numeric = trueelse if character == "{"if !in_stringif key_type == 2Append(contexts, [accumulator, key_type, key_number])else if key_type == 3Append(contexts, [accumulator, key_type, key_string])else if key_type == 0Append(contexts, [accumulator, key_type])elseAppend(contexts, [accumulator, key_type, key_bool])endaccumulator = []is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = ""elsevalue_string += "{"endelse if character == "}"if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendarray last_context = contexts[Count(contexts) - 1]array last_accumulator = last_context[0]number last_key_type = last_context[1]if last_key_type != 0last_accumulator[last_context[2]] = accumulatorelsereturn accumulatorendaccumulator = last_accumulatorvalue_type = 4Remove(contexts, Count(contexts) - 1)elsevalue_string += "}"endelse if character == "\"if !escapedescaped = trueelseescaped = falseif in_valuevalue_string += "\"elsekey_string += "\"endendelse if in_valuevalue_string += characterelsekey_string += characterendif is_numericif !in_stringbuffer += characterif in_valuevalue_type = 2elsekey_type = 2endelse if in_valuevalue_string += characterelsekey_string += characterendis_numeric = falseendendendvar deserialise(string input)if input[0] == "{"return deserialise_array(input)else if is_digit(input[0])number output = inputreturn outputelse if input[0] == "-"number output = inputreturn outputelse if input[0] == '"'return deserialise_string(input)else if input == "t"return trueelse if input == "f"return falseendend################### equality.sprak ###################bool equal_array(array first, array second)if Count(first) == Count(second)loop key in GetIndexes(first)if !HasIndex(second, key)return falseelse if !equal(first[key], second[key])return falseendendreturn trueendreturn falseendbool equal(var first, var second)string type_first = Type(first)if type_first == Type(second)if type_first != "array"return first == secondendreturn equal_array(first, second)endreturn falseend################ array.sprak ################bool has(array arr, var element)loop arrif equal(@, element)return trueendendreturn falseend################ types.sprak ################array Left(var input)return [false, input]endarray 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"]endif HasIndex(overrides, "TingrunnerAPI")TingrunnerAPI_thing = overrides["TingrunnerAPI"]endnumber 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, @)endarray skip_things = []loop ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]Append(skip_things, @)endstring 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, @)endendelseRemoveAll(skip_types)loop overrides["skip_types"]Append(skip_types, @)endendif !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, @)endendelseRemoveAll(skip_things)loop overrides["skip_things"]Append(skip_things, @)endendif HasIndex(overrides, "more_skip_types")loop overrides["more_skip_types"]if !has(skip_types, @)Append(skip_types, @)endendendif HasIndex(overrides, "more_skip_things")loop overrides["more_skip_things"]if !has(skip_things, @)Append(skip_things, @)endendendif 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)endendendendload_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)endendendendendreturn Left("`" + function + "` not found.")endarray supply(array overrides, string function)array array_buffer = supplier_of(overrides, function)if array_buffer[0]return Right(Connect(array_buffer[1]))elsereturn Left(array_buffer[1])endendnumber supply_unwrapped(array overrides, string function)array array_buffer = supply(overrides, function)return array_buffer[1]end - file addition: modifier.md[3.2]
# modifier.sprakAllows any modifier programmed with it to hack any hackable object as well as toggle the lock state of any door hacked with it.## Usage* The toggle states for each door are stored in a computer's memory.* May fail if the `supply` function supplies a function from the same modifier, since `Name()` is not used to check this.## Functions### Imports* serde.sprak* `deserialise`* equality.sprak* array.sprak* `has`* types.sprak* `Left`* `Right`* supply.sprak* `supplier_of`* `supply`* `supply_unwrapped` - edit in equality.sprak at line 1
################### equality.sprak ################### - edit in equality.sprak at line 6
if "" + first == "" + second - edit in equality.sprak at line 15
end - replacement in equality.md at line 1
# serde.sprak# equality.sprak - edit in equality.md at line 5
- file addition: drink.sprak[3.2]
string MOVE_DATA = '' # '{"Sebastian_inventory":{"things":{0:"RustyModder",1:"Typer1Modifier",2:"Screwdriver_ScrewDriver"}}}'bool WILL_TOGGLE_MODIFIER_COPY = falsearray WHATS_IN = []array WHERES = []string NUMERIC_DATA = '' # '{"Sebastian":{"cash":999,"walkSpeed":10,"sleepiness":0,"wellspring":10,"corruption":0,"drunkenness":0,"smelliness":0}}'bool COPYING = falsebool SAVING = falsestring 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, @)endendif Count(WHERES) > 0loop get_rooms_of(WHERES)Append(results, @)endendif NUMERIC_DATA != ""ARRAY_BUFFER = set_data(NUMERIC_DATA, KEY_NUMERIC_DATA)Append(results, ARRAY_BUFFER)endif Count(results) > 0outputs = format_results(results)endif Count(WHATS_IN) > 0STRING_BUFFER = get_things_in(WHATS_IN)Append(outputs, STRING_BUFFER)endif WILL_TOGGLE_MODIFIER_COPYSTRING_BUFFER = toggle_modifier_copy(KEY_COPY_TARGET)Append(outputs, STRING_BUFFER)endif Count(outputs) > 0say(concatenate(outputs, " "), COPYING, SAVING, KEY_SAY)endDisconnectAll()endarray ARRAY_BUFFERarray CONNECTION_CACHE = []array SUPPLIER_CACHE = []string STRING_BUFFERmain()# Functionsstring concatenate(array strings, string separator)string output = ""loop stringsoutput += @ + separatorendreturn outputendstring format_result(array either)if either[0]return either[1]endreturn "ERROR: " + either[1]endarray format_results(array results)array output = []loop resultsAppend(output, format_result(@))endreturn outputendstring room_of(string thing)if !HasIndex(CONNECTION_CACHE, "GetRoom")array overrides = []overrides["more_skip_types"] = ["drink"]CONNECTION_CACHE["GetRoom"] = supply_unwrapped(overrides, "GetRoom")endreturn CONNECTION_CACHE["GetRoom"].GetRoom(thing)endbool thing_exists(string thing)return room_of(thing) != ""endarray invalid_thing(string thing)return Left('"' + thing + '" is not a valid thing.')endnumber cached_connection(string function)if HasIndex(CONNECTION_CACHE, function)return CONNECTION_CACHE[function]endCONNECTION_CACHE[function] = supply_unwrapped([], function)return CONNECTION_CACHE[function]endstring cached_supplier(string function)if HasIndex(SUPPLIER_CACHE, function)return SUPPLIER_CACHE[function]endSUPPLIER_CACHE[function] = supplier_of_unwrapped([], function)return SUPPLIER_CACHE[function]endbool is_person(string person)return cached_connection("GetTypeOfThing").GetTypeOfThing(person) == "character"endstring move_to_thing(string destination, array move_these)array output = []loop move_theseif is_person(@)string TingrunnerAPI_thing = cached_supplier("MovePerson")cached_connection("SetPosition").SetPosition(TingrunnerAPI_thing, @)Connect(TingrunnerAPI_thing).MovePerson(@, destination)elsecached_connection("SetPosition").SetPosition(@, destination)endAppend(output, 'Moved "' + @ + '" to "' + destination + '".')endreturn concatenate(output, " ")endarray move(string serialised_schedule)array schedule = deserialise(serialised_schedule)array destinations = GetIndexes(schedule)loop destination in destinationsif thing_exists(destination)array task = schedule[destination]loop task["things"]if !thing_exists(@)return [invalid_thing(@)]endendelsearray things = cached_connection("GetThingsInRoom").GetThingsInRoom(destination)number count_things = Count(things)if count_things > 0array task = schedule[destination]number index = 0if HasIndex(task, "index")index = task["index"]endif index < 0return [Left("`index` should be >= 0.")]else if index - Int(index) != 0return [Left("`index` should be an integer.")]else if index + 1 > count_thingsreturn [Left("" + (count_things - 1) + 'is the max `index` value for "' + destination + '".')]elseloop task["things"]if !thing_exists(@)return [invalid_thing(@)]endendendelsereturn [Left('"' + destination + '" is not a valid destination.')]endendendarray output = []loop destination in destinationsarray task = schedule[destination]if thing_exists(destination)ARRAY_BUFFER = Right(move_to_thing(destination, task["things"]))Append(output, ARRAY_BUFFER)elsearray things = cached_connection("GetThingsInRoom").GetThingsInRoom(destination)number index = 0if HasIndex(task, "index")index = task["index"]endARRAY_BUFFER = Right(move_to_thing(things[index], task["things"]))Append(output, ARRAY_BUFFER)endendreturn outputendstring get_things_in(array rooms)array outputs = []number TingrunnerAPI = cached_connection("GetThingsInRoom")loop roomsAppend(outputs, 'Serialised list of things in "' + @ + '": ' + "'" + serialise(TingrunnerAPI.GetThingsInRoom(@)) + "'.")endreturn concatenate(outputs, " ")endarray get_rooms_of(array things)array outputs = []loop thingsif !thing_exists(@)return [invalid_thing(@)]endendloop thingsAppend(outputs, Right('"' + @ + '" is in "' + room_of(@) + '".'))endreturn outputsendstring toggle_modifier_copy(string key)string MemoryAPI_thing = cached_supplier("SaveMemory")number MemoryAPI = Connect(MemoryAPI_thing)if !MemoryAPI.HasMemory(key)MemoryAPI.SaveMemory(key, false)endbool 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) + "`."endarray set_data(string serialised_data, string key)array data = deserialise(serialised_data)array things = GetIndexes(data)loop thing in thingsif !thing_exists(thing)return invalid_thing(thing)endarray 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.")endif key_data_point == "cash" || key_data_point == "wellspring"if !is_person(thing)return Left('"' + thing + '" is not a valid person.')endendendendstring 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 + '".')endvoid say(string output, bool copying, bool saving, string key)if output != ""if copyingif !HasIndex(CONNECTION_CACHE, "CopyToClipboard")array overrides = []overrides["more_skip_types"] = ["taser"]CONNECTION_CACHE["CopyToClipboard"] = supply_unwrapped(overrides, "CopyToClipboard")endif savingCONNECTION_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)elseCONNECTION_CACHE["CopyToClipboard"].CopyToClipboard(output)Say("Copied: " + output)endelse if savingstring MemoryAPI_thing = cached_supplier("SaveMemory")Connect(MemoryAPI_thing).SaveMemory(key, output)Say('The following was saved to "' + MemoryAPI_thing + '" using the key "' + key + '": ' + output)elseSay(output)endendend# Imports################ serde.sprak ################string serialise_string(string input)string output = ""loop character in inputif character == '"'output += "\"else if character == "\"output += "\"endoutput += characterendreturn '"' + output + '"'endstring serialise_array(array input)string output = ""bool not_start = falseloop key in GetIndexes(input)if Type(key) != "array"if not_startoutput += ","elsenot_start = trueendoutput += serialise(key) + ":" + serialise(input[key])endendreturn "{" + output + "}"endstring serialise(var input)string input_type = Type(input)if input_type == "unknown"string output = ""loop character in "" + inputif character != "i"output += characterendendreturn outputelse if input_type == "string"return serialise_string(input)else if input_type == "number"return "" + inputelse if input_type == "bool"if inputreturn "t"endreturn "f"else if input_type == "array"return serialise_array(input)endendstring deserialise_string(string input)string output = ""bool escaped = falseloop character in inputif !escapedif character == '\'escaped = trueelse if character != '"'output += characterendelseoutput += characterescaped = falseendendreturn outputendbool is_digit(string input)array digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]loop digitsif input == @return trueendendreturn falseend# Types:# * 0: none# * 1: bool# * 2: number# * 3: string# * 4: arrayarray deserialise_array(string input)array accumulator = []bool is_numeric = falsebool in_string = falsebool escaped = falsebool in_value = falsestring buffer = ""number key_type = 0bool key_bool = falsenumber key_number = 0string key_string = ""number value_type = 0bool value_bool = falsenumber value_number = 0string value_string = ""array contexts = []loop character in inputif character == '"'if !in_stringin_string = trueif in_valuevalue_type = 3elsekey_type = 3endelse if !escapedin_string = falseelse if in_valuevalue_string += '"'elsekey_string += '"'endelse if character == "t"if !in_stringif in_valuevalue_bool = truevalue_type = 1elsekey_bool = truekey_type = 1endelse if in_valuevalue_string += "t"elsekey_string += "t"endelse if character == "f"if !in_stringif in_valuevalue_bool = falsevalue_type = 1elsekey_bool = falsekey_type = 1endelse if in_valuevalue_string += "f"elsekey_string += "f"endelse if character == ":"if !in_stringin_value = trueif key_type == 2key_number = bufferbuffer = ""endelse if in_valuevalue_string += ":"elsekey_string += ":"endelse if character == ","if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendin_value = falsebuffer = ""key_string = ""value_string = ""else if in_valuevalue_string += ","elsekey_string += ","endelse if is_digit(character)is_numeric = trueelse if character == "."is_numeric = trueelse if character == "-"is_numeric = trueelse if character == "{"if !in_stringif key_type == 2Append(contexts, [accumulator, key_type, key_number])else if key_type == 3Append(contexts, [accumulator, key_type, key_string])else if key_type == 0Append(contexts, [accumulator, key_type])elseAppend(contexts, [accumulator, key_type, key_bool])endaccumulator = []is_numeric = falsein_string = falseescaped = falsein_value = falsebuffer = ""key_type = 0key_bool = falsekey_number = 0key_string = ""value_type = 0value_bool = falsevalue_number = 0value_string = ""elsevalue_string += "{"endelse if character == "}"if !in_stringif key_type == 2if value_type == 3accumulator[key_number] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_number] = value_numberelse if value_type == 1accumulator[key_number] = value_boolendelse if key_type == 3if value_type == 3accumulator[key_string] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_string] = value_numberelse if value_type == 1accumulator[key_string] = value_boolendelse if key_type == 1if value_type == 3accumulator[key_bool] = value_stringelse if value_type == 2value_number = bufferaccumulator[key_bool] = value_numberelse if value_type == 1accumulator[key_bool] = value_boolendendarray last_context = contexts[Count(contexts) - 1]array last_accumulator = last_context[0]number last_key_type = last_context[1]if last_key_type != 0last_accumulator[last_context[2]] = accumulatorelsereturn accumulatorendaccumulator = last_accumulatorvalue_type = 4Remove(contexts, Count(contexts) - 1)elsevalue_string += "}"endelse if character == "\"if !escapedescaped = trueelseescaped = falseif in_valuevalue_string += "\"elsekey_string += "\"endendelse if in_valuevalue_string += characterelsekey_string += characterendif is_numericif !in_stringbuffer += characterif in_valuevalue_type = 2elsekey_type = 2endelse if in_valuevalue_string += characterelsekey_string += characterendis_numeric = falseendendendvar deserialise(string input)if input[0] == "{"return deserialise_array(input)else if is_digit(input[0])number output = inputreturn outputelse if input[0] == "-"number output = inputreturn outputelse if input[0] == '"'return deserialise_string(input)else if input == "t"return trueelse if input == "f"return falseendend################### equality.sprak ###################bool equal_array(array first, array second)if Count(first) == Count(second)loop key in GetIndexes(first)if !HasIndex(second, key)return falseelse if !equal(first[key], second[key])return falseendendreturn trueendreturn falseendbool equal(var first, var second)string type_first = Type(first)if type_first == Type(second)if type_first != "array"return first == secondendreturn equal_array(first, second)endreturn falseend################ array.sprak ################bool has(array arr, var element)loop arrif equal(@, element)return trueendendreturn falseend################ types.sprak ################array Left(var input)return [false, input]endarray 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"]endif HasIndex(overrides, "TingrunnerAPI")TingrunnerAPI_thing = overrides["TingrunnerAPI"]endnumber 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, @)endarray skip_things = []loop ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]Append(skip_things, @)endstring 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, @)endendelseRemoveAll(skip_types)loop overrides["skip_types"]Append(skip_types, @)endendif !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, @)endendelseRemoveAll(skip_things)loop overrides["skip_things"]Append(skip_things, @)endendif HasIndex(overrides, "more_skip_types")loop overrides["more_skip_types"]if !has(skip_types, @)Append(skip_types, @)endendendif HasIndex(overrides, "more_skip_things")loop overrides["more_skip_things"]if !has(skip_things, @)Append(skip_things, @)endendendif 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)endendendendload_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)endendendendendreturn Left("`" + function + "` not found.")endstring supplier_of_unwrapped(array overrides, string function)array array_buffer = supplier_of(overrides, function)return array_buffer[1]endarray supply(array overrides, string function)array array_buffer = supplier_of(overrides, function)if array_buffer[0]return Right(Connect(array_buffer[1]))elsereturn Left(array_buffer[1])endendnumber supply_unwrapped(array overrides, string function)array array_buffer = supply(overrides, function)return array_buffer[1]end - file addition: drink.md[3.2]
# drink.sprakAllows any drink programmed with it when drunk to:* Set the location of things.* Get the location of things.* Get the names of things in a room.* Set the numeric data of things, e.g., their cash balance, sleepiness, walking speed, etc.* Copy or save any outputs.## Usage* May fail if the `supply` function supplies a function from the same modifier, since `Name()` is not used to check this.The following global variables at the top of the program are intended to be set by the user:### `MOVE_THESE`Accepts an `string` representing a serialised `array` in the format:```{DESTINATION_THING:{"things":{0:THING_A,1:THING_B,...}},DESTINATION_ROOM:{"index":NATURAL_NUMBER,"things":{0:THING_C,1:THING_D,...}},...}```Representing:* `DESTINATION_THING` - A `string` representing the name of a thing that things `THING_A`, `THING_B`, ... will be moved to.* `THING_A`, `THING_B`, ... - `string`s representing the names of things that things that will be moved to `DESTINATION_THING`.* `DESTINATION_ROOM` - A `string` representing the name of a room that things `THING_C`, `THING_D`, ... will be moved to.* `NATURAL_NUMBER` - An integer `number` >= 0 representing the index of a thing in `DESTINATION_ROOM`.* `THING_C`, `THING_D`, ... - `string`s representing the names of things that things that will be moved to the thing in `DESTINATION_ROOM` indexed by `NATURAL_NUMBER`.The `"index"` attribute is optional and will default to `0` if unset.#### Example```sprakstring MOVE_DATA = '{"Sebastian_inventory":{"things":{0:"RustyModder",1:"Typer1Modifier",2:"Screwdriver_ScrewDriver"}}}'```### `WILL_TOGGLE_MODIFIER_COPY`If set to `true`, drinking will toggle the `bool` value in memory accessed by the key `KEY_COPY_TARGET`, which determines if a modifier programmed with "modifier.sprak" will copy the name of its target.### `WHATS_IN`Accepts an `array` containing strings, each representing the name of a room. The names of the contents of these rooms are outputted after drinking.### `WHERES`Accepts an array containing strings, each representing the name of a thing whose current locations are outputted after drinking.### `NUMERIC_DATA`Accepts an `string` representing a serialised `array` in the format:```{THING:{DATA_POINT:NUMBER,...},...}```Representing:* `THING` - A `string` representing the name of a thing whose numeric data will be set.* `DATA_POINT` - A `string` representing a data point whose value will be set. Known valid values are "cash", "wellspring", "walkSpeed", "sleepiness", "corruption", "drunkenness", "smelliness", "charisma", "happiness", "supremacy".* `NUMBER` - A `number` representing the value that `DATA_POINT` will be set to.After drinking, the value of `NUMERIC_DATA` will be saved to memory, to be accessed by servers programmed with "server.sprak" which will use the value to set the data every tick of their main loop.#### Example```sprakstring NUMERIC_DATA = '{"Sebastian":{"cash":999,"walkSpeed":10,"sleepiness":0,"wellspring":10,"corruption":0,"drunkenness":0,"smelliness":0},"Babcia":{"supremacy":9001}}'```### `COPYING`If set to `true`, causes outputs to be copied to the clipboard after drinking.### `SAVING`If set to `true`, causes outputs to be saved after drinking.### `KEY_COPY_TARGET`A `string` representing the key used to access the memory value determining whether a modifier programmed with "modifier.sprak" will copy its target.### `KEY_NUMERIC_DATA`A `string` representing the key used to access the memory value determining the values that a modifier programmed with "server.sprak" will set.### `KEY_SAY`A `string` representing the key used to access the memory value that will store the outputs of the program.## Functions### Imports* serde.sprak* `deserialise`* equality.sprak* array.sprak* `has`* types.sprak* `Left`* `Right`* supply.sprak* `supplier_of`* `supplier_of_unwrapped`* `supply`* `supply_unwrapped`## TODO* Handle invalid inputs for `get_things_in`.* Return early if any results are left/errors. - replacement in array.sprak at line 4
bool has(var elem, array arr)loop element in arrif equal(element, elem)bool has(array arr, var element)loop arrif equal(@, element) - edit in array.sprak at line 12[3.37139]
array push(array arr, var element)array output = []loop arrAppend(output, @)endAppend(output, element)return outputend - replacement in array.md at line 1
# serde.sprak# array.sprak - edit in array.md at line 5
### Imports* equality.sprak* `equal_array`* `equal` - replacement in array.md at line 13
`A -> array A -> bool``[A] -> A -> bool` - edit in array.md at line 15
* `elem`: The value to search for. - edit in array.md at line 16
* `element`: The value to search for. - replacement in array.md at line 21
#### Imports* equality.sprak* `equal_array`* `equal`[3.37430]### `push`Return a new array containing a new element along with the elements of an input array. Exists because `Append` on `array` types [don't work properly](https://steamcommunity.com/app/400110/discussions/0/2992043384032764071/).#### Type`[A] -> A -> [A]`#### Arguments* `arr`: Array to get the elements of.* `element`: The element to add to the new array.#### Examples```sprak# TODO``` - edit in README.md at line 3
--- - edit in README.md at line 5
* `bool` operators in Sprak don't seem to short-circuit. Unconcise usage of conditionals in this project may have been used to emulate short-circuiting `bool` operators. - replacement in README.md at line 6
---* The deserialisation machinery in "serde.sprak" don't currently have any error-handling for bad inputs, so ensure all inputs to these are correct.* `bool` operators in Sprak [don't short-circuit](https://steamcommunity.com/app/400110/discussions/0/523898291507887095/). Unconcise usage of conditionals in this project may have been used to emulate short-circuiting `bool` operators.* `Append` on `array` types [don't work properly](https://steamcommunity.com/app/400110/discussions/0/2992043384032764071/) and only works when the array started as an empty array and hasn't been set to a pre-populated one. - edit in .ignore at line 3[3.40070]
else_heart_break.code-workspace