NTSL Update:

- You can now send signals with signal(freq, code). Added a cooldown to limit spamming.
    - You can now use "elseif" in your scripts to create a chain.
    - You can now use "return" in the global scope to end the script from running.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5701 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
giacomand@gmail.com
2013-02-13 21:43:34 +00:00
parent 9f1318f48d
commit 39a97a6f77
11 changed files with 96 additions and 15 deletions
+4
View File
@@ -69,11 +69,15 @@
//
IfStatement
var
skip = 0
node
BlockDefinition
block
else_block //may be null
expression/cond
statement/else_if
ElseIf
/*
Class: WhileLoop
@@ -92,6 +92,15 @@
*/
interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job"))
/*
-> 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)
@@ -210,6 +219,8 @@
/* -- Actual language proc code -- */
var/const/SIGNAL_COOLDOWN = 20 // 2 seconds
datum/signal
proc/mem(var/address, var/value)
@@ -224,6 +235,33 @@ datum/signal
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)
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/datum/signal/newsign = new
@@ -239,7 +277,7 @@ datum/signal
if(!source)
source = "[html_encode(uppertext(S.id))]"
hradio = new // sets the hradio as a radio intercom
if(!freq)
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
@@ -250,13 +288,13 @@ datum/signal
newsign.data["mob"] = null
newsign.data["mobtype"] = /mob/living/carbon/human
if(source in S.stored_names)
newsign.data["name"] = source
newsign.data["name"] = "[source]"
else
newsign.data["name"] = "<i>[html_encode(uppertext(source))]<i>"
newsign.data["realname"] = newsign.data["name"]
newsign.data["job"] = job
newsign.data["job"] = "[job]"
newsign.data["compression"] = 0
newsign.data["message"] = message
newsign.data["message"] = "[message]"
newsign.data["type"] = 2 // artificial broadcast
if(!isnum(freq))
freq = text2num(freq)
@@ -223,10 +223,21 @@
Checks a condition and runs either the if block or else block.
*/
RunIf(node/statement/IfStatement/stmt)
if(Eval(stmt.cond))
RunBlock(stmt.block)
else if(stmt.else_block)
RunBlock(stmt.else_block)
if(!stmt.skip)
if(Eval(stmt.cond))
RunBlock(stmt.block)
// Loop through the if else chain and tell them to be skipped.
var/node/statement/IfStatement/i = stmt.else_if
var/fail_safe = 800
while(i && fail_safe)
fail_safe -= 1
i.skip = 1
i = i.else_if
else if(stmt.else_block)
RunBlock(stmt.else_block)
// We don't need to skip you anymore.
stmt.skip = 0
/*
Proc: RunWhile
+1 -1
View File
@@ -50,7 +50,7 @@ n_scriptOptions
An associative list used by the parser to parse keywords. Indices are strings which will trigger the keyword when parsed and the
associated values are <nS_Keyword> types of which the <n_Keyword.Parse()> proc will be called.
*/
keywords = list("if" = /n_Keyword/nS_Keyword/kwIf, "else" = /n_Keyword/nS_Keyword/kwElse, \
keywords = list("if" = /n_Keyword/nS_Keyword/kwIf, "else" = /n_Keyword/nS_Keyword/kwElse, "elseif" = /n_Keyword/nS_Keyword/kwElseIf, \
"while" = /n_Keyword/nS_Keyword/kwWhile, "break" = /n_Keyword/nS_Keyword/kwBreak, \
"continue" = /n_Keyword/nS_Keyword/kwContinue, \
"return" = /n_Keyword/nS_Keyword/kwReturn, "def" = /n_Keyword/nS_Keyword/kwDef)
+2 -1
View File
@@ -281,7 +281,8 @@
for()
loops++
if(loops>=1000)
CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
break
//CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
if(istype(curToken, /token/symbol) && curToken.value==")")
return exp
+28 -3
View File
@@ -51,9 +51,9 @@ var/const/Represents a special statement in the code triggered by a keyword.
kwReturn
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock))
parser.errors+=new/scriptError/BadReturn(parser.curToken)
. = KW_WARN
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock)) // Exit out of the program by setting the tokens list size to the same as index.
parser.tokens.len = parser.index
return
var/node/statement/ReturnStatement/stmt=new
parser.NextToken() //skip 'return' token
stmt.value=parser.ParseExpression()
@@ -73,6 +73,31 @@ var/const/Represents a special statement in the code triggered by a keyword.
stmt.block=new
parser.AddBlock(stmt.block)
kwElseIf
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS
var/list/L=parser.curBlock.statements
var/node/statement/IfStatement/ifstmt
if(L && L.len)
ifstmt = L[L.len] //Get the last statement in the current block
if(!ifstmt || !istype(ifstmt) || ifstmt.else_if)
parser.errors += new/scriptError/ExpectedToken("if statement", parser.curToken)
return KW_FAIL
var/node/statement/IfStatement/ElseIf/stmt = new
parser.NextToken() //skip 'if' token
stmt.cond = parser.ParseParenExpression()
if(!parser.CheckToken(")", /token/symbol))
return KW_FAIL
if(!parser.CheckToken("{", /token/symbol, skip=0)) //Token needs to be preserved for parse loop, so skip=0
return KW_ERR
parser.curBlock.statements+=stmt
stmt.block=new
ifstmt.else_if = stmt
parser.AddBlock(stmt.block)
kwElse
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS