TG: More work done on Telecomms:

▫ Signals can now be rejected by Subspace broadcasters through a specific data[]
parameter.
▫ Improved the log browser.
▫ Log browsers and telecommunication monitors no longer require access to use.
You do need access to delete logs, however.
▫ Intercoms need power to work. They don't drain power, they just need a
constant flow of equipment power. As such, that offline intercom sprite's now
finally being put to use.

Scripting language:

▫ Sorry about all the files; they're all necessary! It's important to notice
that the basic structure of the scripting language code is not mine; I
cannibalized the base structure from some obscure BYOND project. It's pretty
well documented, and I'd say easier to browse through than atmos. Here's the
basic deal:

A compiler datum manages the relationships between the three main subsystems of
a scripting language: the Scanner, the Parser, and the Interpreter. The Scanner
splits raw text into token datums that the Parser can read. The Parser
transforms the otherwise random bits and strings into ordered AST Trees and
nodes for the Interpreter to read. The interpreter actually executes the code
and handles scope/functions/code blocks.
Revision: r3193
Author: 	 vageyenaman
This commit is contained in:
Ren Erthilo
2012-04-24 21:13:55 +01:00
parent 757b76c456
commit f8dd926ca5
14 changed files with 350 additions and 99 deletions

View File

@@ -47,6 +47,8 @@
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
@@ -155,6 +157,25 @@
interpreter.SetProc("prob", /proc/prob_chance)
interpreter.SetProc("substr", /proc/docopytext)
// Donkie~
// Strings
interpreter.SetProc("lower", /proc/n_lower)
interpreter.SetProc("upper", /proc/n_upper)
interpreter.SetProc("explode", /proc/string_explode)
interpreter.SetProc("repeat", /proc/n_repeat)
interpreter.SetProc("reverse", /proc/n_reverse)
interpreter.SetProc("tonum", /proc/n_str2num)
// 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)
// End of Donkie~
// Run the compiled code
@@ -163,7 +184,7 @@
// Backwards-apply variables onto signal data
/* sanitize EVERYTHING. fucking players can't be trusted with SHIT */
signal.data["message"] = trim(copytext(sanitize(interpreter.GetVar("$content")), 1, MAX_MESSAGE_LEN))
signal.data["message"] = interpreter.GetVar("$content")
signal.frequency = interpreter.GetVar("$freq")
var/setname = ""
@@ -171,14 +192,18 @@
if(interpreter.GetVar("$source") in S.stored_names)
setname = interpreter.GetVar("$source")
else
setname = "<i>[trim(copytext(sanitize(interpreter.GetVar("$source")), 1, MAX_MESSAGE_LEN))]</i>"
setname = "<i>[interpreter.GetVar("$source")]</i>"
if(signal.data["name"] != setname)
signal.data["realname"] = setname
signal.data["name"] = setname
signal.data["job"] = trim(copytext(sanitize(interpreter.GetVar("$job")), 1, MAX_MESSAGE_LEN))
signal.data["job"] = interpreter.GetVar("$job")
signal.data["reject"] = !(interpreter.GetVar("$pass")) // set reject to the opposite of $pass
// 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 -- */
datum/signal
@@ -188,7 +213,7 @@ datum/signal
if(istext(address))
var/obj/machinery/telecomms/server/S = data["server"]
if(!value)
if(!value && value != 0)
return S.memory[address]
else
@@ -202,7 +227,7 @@ datum/signal
var/obj/machinery/telecomms/server/S = data["server"]
var/obj/item/device/radio/hradio
if(!message)
if((!message || message == "") && message != 0)
message = "*beep*"
if(!source)
source = "[html_encode(uppertext(S.id))]"
@@ -213,7 +238,7 @@ datum/signal
freq *= 10 // shift the decimal one place
if(!job)
job = "None"
job = "?"
newsign.data["mob"] = H
newsign.data["mobtype"] = H.type
@@ -222,9 +247,9 @@ datum/signal
else
newsign.data["name"] = "<i>[html_encode(uppertext(source))]<i>"
newsign.data["realname"] = newsign.data["name"]
newsign.data["job"] = html_encode(job)
newsign.data["job"] = job
newsign.data["compression"] = 0
newsign.data["message"] = html_encode(message)
newsign.data["message"] = message
newsign.data["type"] = 2 // artificial broadcast
if(!isnum(freq))
freq = text2num(freq)
@@ -242,4 +267,4 @@ datum/signal
newsign.data["vmessage"] = H.voice_message
newsign.data["vname"] = H.voice_name
newsign.data["vmask"] = 0
S.relay_information(newsign, "/obj/machinery/telecomms/broadcaster") // send this simple message to broadcasters
S.relay_information(newsign, "/obj/machinery/telecomms/broadcaster") // send this simple message to broadcasters

View File

@@ -53,6 +53,7 @@
if(isobject(e))
if(istype(e, /list))
chosenlist = e
i = 2
else
if(chosenlist)
chosenlist.Add(e)
@@ -66,6 +67,7 @@
if(isobject(e))
if(istype(e, /list))
chosenlist = e
i = 2
else
if(chosenlist)
chosenlist.Remove(e)
@@ -101,23 +103,142 @@
if(haystack && needle)
if(isobject(haystack))
if(istype(haystack, /list))
if(length(haystack) + 1 >= end && start > 0)
if(length(haystack) >= end && start > 0)
var/list/listhaystack = haystack
return listhaystack.Find(needle, start, end)
else
if(istext(haystack))
if(length(haystack) + 1 >= end && start > 0)
if(length(haystack) >= end && start > 0)
return findtext(haystack, needle, start, end)
// Clone of copytext()
/proc/docopytext(var/string, var/start = 1, var/end = 0)
if(istext(string) && isnum(start) && isnum(end))
if(length(string) >= end && start > 0)
if(start > 0)
return copytext(string, start, end)
// Clone of length()
/proc/smartlength(var/container)
if(container)
if(istype(container, /list) || istext(container))
return length(container)
return length(container)
// BY DONKIE~
// String stuff
/proc/n_lower(var/string)
if(istext(string))
return lowertext(string)
/proc/n_upper(var/string)
if(istext(string))
return uppertext(string)
/*
//Makes a list where all indicies in a string is a seperate index in the list
// JUST A HELPER DON'T ADD TO NTSCRIPT
proc/string_tolist(var/string)
var/list/L = new/list()
var/i
for(i=1, i<=lentext(string), i++)
L.Add(copytext(string, i, i))
return L
proc/string_explode(var/string, var/separator)
if(istext(string))
if(istext(separator) && separator == "")
return string_tolist(string)
var/i
var/lasti = 1
var/list/L = new/list()
for(i=1, i<=lentext(string)+1, i++)
if(copytext(string, i, i+1) == separator) // We found a separator
L.Add(copytext(string, lasti, i))
lasti = i+1
L.Add(copytext(string, lasti, lentext(string)+1)) // Adds the last segment
return L
Just found out there was already a string explode function, did some benchmarking, and that function were a bit faster, sticking to that.
*/
proc/string_explode(var/string, var/separator)
if(istext(string) && istext(separator))
return dd_text2list(string, separator)
proc/n_repeat(var/string, var/amount)
if(istext(string) && isnum(amount))
var/i
var/newstring = ""
for(i=0, i<=amount, i++)
if(i>=1000)
break
newstring = newstring + string
return newstring
proc/n_reverse(var/string)
if(istext(string))
var/newstring = ""
var/i
for(i=lentext(string), i>0, i--)
if(i>=1000)
break
newstring = newstring + copytext(string, i, i+1)
return newstring
// I don't know if it's neccesary to make my own proc, but I think I have to to be able to check for istext.
proc/n_str2num(var/string)
if(istext(string))
return text2num(string)
// Number shit
proc/n_num2str(var/num)
if(isnum(num))
return num2text(num)
// Squareroot
proc/n_sqrt(var/num)
if(isnum(num))
return sqrt(num)
// Magnitude of num
proc/n_abs(var/num)
if(isnum(num))
return abs(num)
// Round down
proc/n_floor(var/num)
if(isnum(num))
return round(num)
// Round up
proc/n_ceil(var/num)
if(isnum(num))
return round(num)+1
// Round to nearest integer
proc/n_round(var/num)
if(isnum(num))
if(num-round(num)<0.5)
return round(num)
return n_ceil(num)
// Clamps N between min and max
proc/n_clamp(var/num, var/min=-1, var/max=1)
if(isnum(num)&&isnum(min)&&isnum(max))
if(num<=min)
return min
if(num>=max)
return max
return num
// Returns 1 if N is inbetween Min and Max
proc/n_inrange(var/num, var/min=-1, var/max=1)
if(isnum(num)&&isnum(min)&&isnum(max))
return ((min <= num) && (num <= max))
// END OF BY DONKIE :(