mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-17 05:03:28 +00:00
Enables NTSL to read and set four radio span classes to messages. Also enables NTSL to set each of the say modification verbs to custom values. -Broadcast() proc of NTSL now accepts 5 additional parameters - spans and each of the Say verbs.
368 lines
13 KiB
Plaintext
368 lines
13 KiB
Plaintext
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
|
|
|
|
|
/* --- Traffic Control Scripting Language --- */
|
|
// Nanotrasen TCS Language - Made by Doohl
|
|
|
|
//Span classes that players are allowed to set in a radio transmission.
|
|
var/list/allowed_custom_spans = list(SPAN_ROBOT,SPAN_YELL,SPAN_ITALICS,SPAN_SANS)
|
|
|
|
/n_Interpreter/TCS_Interpreter
|
|
var/datum/TCS_Compiler/Compiler
|
|
|
|
HandleError(runtimeError/e)
|
|
Compiler.Holder.add_entry(e.ToString(), "Execution Error")
|
|
|
|
GC()
|
|
..()
|
|
Compiler = null
|
|
|
|
|
|
/datum/TCS_Compiler
|
|
|
|
var/n_Interpreter/TCS_Interpreter/interpreter
|
|
var/obj/machinery/telecomms/server/Holder // the server that is running the code
|
|
var/ready = 1 // 1 if ready to run code
|
|
|
|
/* -- Set ourselves to Garbage Collect -- */
|
|
|
|
proc/GC()
|
|
|
|
Holder = null
|
|
if(interpreter)
|
|
interpreter.GC()
|
|
|
|
|
|
/* -- Compile a raw block of text -- */
|
|
|
|
proc/Compile(code as message)
|
|
var/n_scriptOptions/nS_Options/options = new()
|
|
var/n_Scanner/nS_Scanner/scanner = new(code, options)
|
|
var/list/tokens = scanner.Scan()
|
|
var/n_Parser/nS_Parser/parser = new(tokens, options)
|
|
var/node/BlockDefinition/GlobalBlock/program = parser.Parse()
|
|
|
|
var/list/returnerrors = list()
|
|
|
|
returnerrors += scanner.errors
|
|
returnerrors += parser.errors
|
|
|
|
if(returnerrors.len)
|
|
return returnerrors
|
|
|
|
interpreter = new(program)
|
|
interpreter.persist = 1
|
|
interpreter.Compiler= src
|
|
|
|
return returnerrors
|
|
|
|
/* -- Execute the compiled code -- */
|
|
|
|
proc/Run(var/datum/signal/signal)
|
|
|
|
if(!ready)
|
|
return
|
|
|
|
if(!interpreter)
|
|
return
|
|
|
|
interpreter.container = src
|
|
|
|
interpreter.SetVar("PI" , 3.141592653) // value of pi
|
|
interpreter.SetVar("E" , 2.718281828) // value of e
|
|
interpreter.SetVar("SQURT2" , 1.414213562) // value of the square root of 2
|
|
interpreter.SetVar("FALSE" , 0) // boolean shortcut to 0
|
|
interpreter.SetVar("false" , 0) // boolean shortcut to 0
|
|
interpreter.SetVar("TRUE" , 1) // boolean shortcut to 1
|
|
interpreter.SetVar("true" , 1) // boolean shortcut to 1
|
|
|
|
interpreter.SetVar("NORTH" , NORTH) // NORTH (1)
|
|
interpreter.SetVar("SOUTH" , SOUTH) // SOUTH (2)
|
|
interpreter.SetVar("EAST" , EAST) // EAST (4)
|
|
interpreter.SetVar("WEST" , WEST) // WEST (8)
|
|
|
|
// Channel macros
|
|
interpreter.SetVar("$common", 1459)
|
|
interpreter.SetVar("$science", 1351)
|
|
interpreter.SetVar("$command", 1353)
|
|
interpreter.SetVar("$medical", 1355)
|
|
interpreter.SetVar("$engineering",1357)
|
|
interpreter.SetVar("$security", 1359)
|
|
interpreter.SetVar("$supply", 1347)
|
|
interpreter.SetVar("$service", 1349)
|
|
|
|
// Signal data
|
|
|
|
interpreter.SetVar("$content", html_decode(signal.data["message"]))
|
|
interpreter.SetVar("$freq" , signal.frequency)
|
|
interpreter.SetVar("$source" , signal.data["name"])
|
|
interpreter.SetVar("$job" , signal.data["job"])
|
|
interpreter.SetVar("$sign" , signal)
|
|
interpreter.SetVar("$pass" , !(signal.data["reject"])) // if the signal isn't rejected, pass = 1; if the signal IS rejected, pass = 0
|
|
interpreter.SetVar("$filters" , signal.data["spans"]) //Important, this is given as a vector! (a list)
|
|
interpreter.SetVar("$say" , signal.data["verb_say"])
|
|
interpreter.SetVar("$ask" , signal.data["verb_ask"])
|
|
interpreter.SetVar("$yell" , signal.data["verb_yell"])
|
|
interpreter.SetVar("$exclaim" , signal.data["verb_exclaim"])
|
|
|
|
//Current allowed span classes
|
|
interpreter.SetVar("$robot", SPAN_ROBOT) //The font used by silicons!
|
|
interpreter.SetVar("$loud", SPAN_YELL) //Bolding, applied when ending a message with several exclamation marks.
|
|
interpreter.SetVar("$emphasis", SPAN_ITALICS) //Italics
|
|
interpreter.SetVar("$wacky", SPAN_SANS) //Comic sans font, normally seen from the genetics power.
|
|
|
|
//Language bitflags
|
|
interpreter.SetVar("HUMAN" , HUMAN)
|
|
interpreter.SetVar("MONKEY" , MONKEY)
|
|
interpreter.SetVar("ALIEN" , ALIEN)
|
|
interpreter.SetVar("ROBOT" , ROBOT)
|
|
interpreter.SetVar("SLIME" , SLIME)
|
|
interpreter.SetVar("DRONE" , DRONE)
|
|
|
|
var/curlang = HUMAN
|
|
if(istype(signal.data["mob"], /atom/movable))
|
|
var/atom/movable/M = signal.data["mob"]
|
|
curlang = M.languages
|
|
|
|
interpreter.SetVar("$language", curlang)
|
|
|
|
|
|
/*
|
|
Telecomms procs
|
|
*/
|
|
|
|
/*
|
|
-> Send another signal to a server
|
|
@format: broadcast(content, frequency, source, job, lang)
|
|
|
|
@param content: Message to broadcast
|
|
@param frequency: Frequency to broadcast to
|
|
@param source: The name of the source you wish to imitate. Must be stored in stored_names list.
|
|
@param job: The name of the job.
|
|
@param spans What span classes you want to apply to your message. Must be in the "allowed_custom_spans" list.
|
|
@param say Say verb used in messages ending in ".".
|
|
@param ask Say verb used in messages ending in "?".
|
|
@param yell Say verb used in messages ending in "!!" (or more).
|
|
@param exclaim Say verb used in messages ending in "!".
|
|
|
|
*/
|
|
interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job","spans","say","ask","yell","exclaim"))
|
|
|
|
/*
|
|
-> Send a code signal.
|
|
@format: signal(frequency, code)
|
|
|
|
@param frequency: Frequency to send the signal to
|
|
@param code: Encryption code to send the signal with
|
|
*/
|
|
interpreter.SetProc("signal", "signaler", signal, list("freq", "code"))
|
|
|
|
/*
|
|
-> Store a value permanently to the server machine (not the actual game hosting machine, the ingame machine)
|
|
@format: mem(address, value)
|
|
|
|
@param address: The memory address (string index) to store a value to
|
|
@param value: The value to store to the memory address
|
|
*/
|
|
interpreter.SetProc("mem", "mem", signal, list("address", "value"))
|
|
|
|
|
|
/*
|
|
General NTSL procs
|
|
Should probably be moved to its own place
|
|
*/
|
|
// Vector
|
|
interpreter.SetProc("vector", /proc/n_list)
|
|
interpreter.SetProc("at", /proc/n_listpos)
|
|
interpreter.SetProc("copy", /proc/n_listcopy)
|
|
interpreter.SetProc("push_back", /proc/n_listadd)
|
|
interpreter.SetProc("remove", /proc/n_listremove)
|
|
interpreter.SetProc("cut", /proc/n_listcut)
|
|
interpreter.SetProc("swap", /proc/n_listswap)
|
|
interpreter.SetProc("insert", /proc/n_listinsert)
|
|
interpreter.SetProc("pick", /proc/n_pick)
|
|
interpreter.SetProc("prob", /proc/n_prob)
|
|
interpreter.SetProc("substr", /proc/n_substr)
|
|
interpreter.SetProc("find", /proc/n_smartfind)
|
|
interpreter.SetProc("length", /proc/n_smartlength)
|
|
|
|
// Strings
|
|
interpreter.SetProc("lower", /proc/n_lower)
|
|
interpreter.SetProc("upper", /proc/n_upper)
|
|
interpreter.SetProc("explode", /proc/n_explode)
|
|
interpreter.SetProc("implode", /proc/n_implode)
|
|
interpreter.SetProc("repeat", /proc/n_repeat)
|
|
interpreter.SetProc("reverse", /proc/n_reverse)
|
|
interpreter.SetProc("tonum", /proc/n_str2num)
|
|
interpreter.SetProc("replace", /proc/n_replace)
|
|
interpreter.SetProc("proper", /proc/n_proper)
|
|
|
|
// Numbers
|
|
interpreter.SetProc("tostring", /proc/n_num2str)
|
|
interpreter.SetProc("sqrt", /proc/n_sqrt)
|
|
interpreter.SetProc("abs", /proc/n_abs)
|
|
interpreter.SetProc("floor", /proc/n_floor)
|
|
interpreter.SetProc("ceil", /proc/n_ceil)
|
|
interpreter.SetProc("round", /proc/n_round)
|
|
interpreter.SetProc("clamp", /proc/n_clamp)
|
|
interpreter.SetProc("inrange", /proc/n_inrange)
|
|
interpreter.SetProc("rand", /proc/n_rand)
|
|
interpreter.SetProc("randseed", /proc/n_randseed)
|
|
interpreter.SetProc("min", /proc/n_min)
|
|
interpreter.SetProc("max", /proc/n_max)
|
|
interpreter.SetProc("sin", /proc/n_sin)
|
|
interpreter.SetProc("cos", /proc/n_cos)
|
|
interpreter.SetProc("asin", /proc/n_asin)
|
|
interpreter.SetProc("acos", /proc/n_acos)
|
|
interpreter.SetProc("log", /proc/n_log)
|
|
|
|
// Time
|
|
interpreter.SetProc("time", /proc/n_time)
|
|
interpreter.SetProc("sleep", /proc/n_delay)
|
|
interpreter.SetProc("timestamp", /proc/gameTimestamp)
|
|
|
|
// Run the compiled code
|
|
interpreter.Run()
|
|
|
|
// Backwards-apply variables onto signal data
|
|
/* sanitize EVERYTHING. fucking players can't be trusted with SHIT */
|
|
|
|
signal.data["message"] = interpreter.GetCleanVar("$content", signal.data["message"])
|
|
signal.frequency = interpreter.GetCleanVar("$freq", signal.frequency)
|
|
|
|
var/setname = interpreter.GetCleanVar("$source", signal.data["name"])
|
|
|
|
if(signal.data["name"] != setname)
|
|
signal.data["realname"] = setname
|
|
signal.data["name"] = setname
|
|
signal.data["job"] = interpreter.GetCleanVar("$job", signal.data["job"])
|
|
signal.data["reject"] = !(interpreter.GetCleanVar("$pass")) // set reject to the opposite of $pass
|
|
signal.data["verb_say"] = interpreter.GetCleanVar("$say")
|
|
signal.data["verb_ask"] = interpreter.GetCleanVar("$ask")
|
|
signal.data["verb_yell"] = interpreter.GetCleanVar("$yell")
|
|
signal.data["verb_exclaim"] = interpreter.GetCleanVar("$exclaim")
|
|
var/list/setspans = interpreter.GetCleanVar("$filters") //Save the span vector/list to a holder list
|
|
setspans &= allowed_custom_spans //Prune out any illegal ones. Go ahead, comment this line out. See the horror you can unleash!
|
|
signal.data["spans"] = setspans //Apply it to the signal
|
|
|
|
// If the message is invalid, just don't broadcast it!
|
|
if(signal.data["message"] == "" || !signal.data["message"])
|
|
signal.data["reject"] = 1
|
|
|
|
/* -- Actual language proc code -- */
|
|
|
|
var/const/SIGNAL_COOLDOWN = 20 // 2 seconds
|
|
|
|
datum/signal
|
|
|
|
proc/mem(var/address, var/value)
|
|
|
|
if(istext(address))
|
|
var/obj/machinery/telecomms/server/S = data["server"]
|
|
|
|
if(!value && value != 0)
|
|
return S.memory[address]
|
|
|
|
else
|
|
S.memory[address] = value
|
|
|
|
|
|
proc/signaler(var/freq = 1459, var/code = 30)
|
|
|
|
if(isnum(freq) && isnum(code))
|
|
|
|
var/obj/machinery/telecomms/server/S = data["server"]
|
|
|
|
if(S.last_signal + SIGNAL_COOLDOWN > world.timeofday && S.last_signal < MIDNIGHT_ROLLOVER)
|
|
return
|
|
S.last_signal = world.timeofday
|
|
|
|
var/datum/radio_frequency/connection = radio_controller.return_frequency(freq)
|
|
|
|
if(findtext(num2text(freq), ".")) // if the frequency has been set as a decimal
|
|
freq *= 10 // shift the decimal one place
|
|
|
|
freq = sanitize_frequency(freq)
|
|
|
|
code = round(code)
|
|
code = Clamp(code, 0, 100)
|
|
|
|
var/datum/signal/signal = new
|
|
signal.source = S
|
|
signal.encryption = code
|
|
signal.data["message"] = "ACTIVATE"
|
|
|
|
connection.post_signal(S, signal)
|
|
|
|
var/time = time2text(world.realtime,"hh:mm:ss")
|
|
lastsignalers.Add("[time] <B>:</B> [S.id] sent a signal command, which was triggered by NTSL.<B>:</B> [format_frequency(freq)]/[code]")
|
|
|
|
|
|
proc/tcombroadcast(var/message, var/freq, var/source, var/job, var/spans, var/say = "says", var/ask = "asks", var/yell = "yells", var/exclaim = "exclaims")
|
|
|
|
var/datum/signal/newsign = new
|
|
var/obj/machinery/telecomms/server/S = data["server"]
|
|
var/obj/item/device/radio/hradio = S.server_radio
|
|
|
|
if(!hradio)
|
|
ERROR("[src] has no radio.")
|
|
return
|
|
|
|
if((!message || message == "") && message != 0)
|
|
message = "*beep*"
|
|
if(!source)
|
|
source = "[html_encode(uppertext(S.id))]"
|
|
hradio = new // sets the hradio as a radio intercom
|
|
if(!freq || (!isnum(freq) && text2num(freq) == null))
|
|
freq = 1459
|
|
if(findtext(num2text(freq), ".")) // if the frequency has been set as a decimal
|
|
freq *= 10 // shift the decimal one place
|
|
|
|
if(!job)
|
|
job = "Unknown"
|
|
|
|
if(!islist(spans))
|
|
spans = list()
|
|
else
|
|
spans &= allowed_custom_spans //Removes any spans not on the allowed list. Comment this out if want to let players use ANY span in stylesheet.dm!
|
|
|
|
//SAY REWRITE RELATED CODE.
|
|
//This code is a little hacky, but it *should* work. Even though it'll result in a virtual speaker referencing another virtual speaker. vOv
|
|
var/atom/movable/virtualspeaker/virt = PoolOrNew(/atom/movable/virtualspeaker,null)
|
|
virt.name = source
|
|
virt.job = job
|
|
virt.faketrack = 1
|
|
virt.languages = HUMAN
|
|
//END SAY REWRITE RELATED CODE.
|
|
|
|
newsign.data["mob"] = virt
|
|
newsign.data["mobtype"] = /mob/living/carbon/human
|
|
newsign.data["name"] = source
|
|
newsign.data["realname"] = newsign.data["name"]
|
|
newsign.data["job"] = "[job]"
|
|
newsign.data["compression"] = 0
|
|
newsign.data["message"] = message
|
|
newsign.data["type"] = 2 // artificial broadcast
|
|
newsign.data["spans"] = spans
|
|
newsign.data["verb_say"] = say
|
|
newsign.data["verb_ask"] = ask
|
|
newsign.data["verb_yell"]= yell
|
|
newsign.data["verb_exclaim"] = exclaim
|
|
if(!isnum(freq))
|
|
freq = text2num(freq)
|
|
newsign.frequency = freq
|
|
|
|
|
|
newsign.data["radio"] = hradio
|
|
newsign.data["vmessage"] = message
|
|
newsign.data["vname"] = source
|
|
newsign.data["vmask"] = 0
|
|
newsign.data["level"] = data["level"]
|
|
|
|
newsign.sanitize_data()
|
|
|
|
var/pass = S.relay_information(newsign, "/obj/machinery/telecomms/hub")
|
|
if(!pass)
|
|
S.relay_information(newsign, "/obj/machinery/telecomms/broadcaster") // send this simple message to broadcasters
|
|
|