mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
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:
@@ -51,7 +51,6 @@
|
||||
var/aiHacking = 0
|
||||
var/obj/machinery/door/airlock/closeOther = null
|
||||
var/closeOtherId = null
|
||||
var/list/signalers[12]
|
||||
var/lockdownbyai = 0
|
||||
autoclose = 1
|
||||
var/doortype = 0
|
||||
|
||||
@@ -519,6 +519,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
// would add up to md5("password123comsat")
|
||||
var/language = "human"
|
||||
var/obj/item/device/radio/headset/server_radio = null
|
||||
var/last_signal = 0 // Last time it sent a signal
|
||||
|
||||
/obj/machinery/telecomms/server/New()
|
||||
..()
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
if(signal.encryption != code) return 0
|
||||
if(!(src.wires & WIRE_RADIO_RECEIVE)) return 0
|
||||
pulse(1)
|
||||
|
||||
for(var/mob/O in hearers(1, src.loc))
|
||||
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
|
||||
return
|
||||
|
||||
@@ -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(!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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define DEBUG
|
||||
|
||||
#define PI 3.1415
|
||||
#define MIDNIGHT_ROLLOVER 864000
|
||||
|
||||
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
|
||||
#define ONE_ATMOSPHERE 101.325 //kPa
|
||||
|
||||
@@ -54,6 +54,8 @@ should be listed in the changelog upon commit tho. Thanks. -->
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">There are now hackable wires for the PA computer. To open the interface, click on it while the wires are exposed/panel is open. All but one wire will do something interesting, see if you can figure it out. You can also attach signallers to the wires so have fun remotely releasing the singularity.</li>
|
||||
<li class="imageadd">New staff of animation icon by Teh Wolf!</li>
|
||||
<li class="rscadd">You can now hack plastic explosives (C4)!</li>
|
||||
<li class="rscadd">You can now use NTSL to send signals! With the function signal(frequency, code) you can create some clever ways to trigger a bomb. NTSL also has two new additions; return in the global scope will now stop the remaining code from executing and NTSL now has "elseif"s, huzzah!</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user