diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index cbc7fd08920..af4de68fd7a 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -4,25 +4,14 @@ #define HOURS *36000 //Returns the world time in english -proc/worldtime2text(time = world.time) +/proc/worldtime2text(time = world.time) return "[round(time / 36000)+12]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]" -proc/time_stamp() +/proc/time_stamp() return time2text(world.timeofday, "hh:mm:ss") - -/* Preserving this so future generations can see how fucking retarded some people are -proc/time_stamp() - var/hh = text2num(time2text(world.timeofday, "hh")) // Set the hour - var/mm = text2num(time2text(world.timeofday, "mm")) // Set the minute - var/ss = text2num(time2text(world.timeofday, "ss")) // Set the second - var/ph - var/pm - var/ps - if(hh < 10) ph = "0" - if(mm < 10) pm = "0" - if(ss < 10) ps = "0" - return"[ph][hh]:[pm][mm]:[ps][ss]" -*/ + +/proc/gameTimestamp(format = "hh:mm:ss") // Get the game time in text + return time2text(world.time - timezoneOffset + 432000, format) /* Returns 1 if it is the selected month and day */ proc/isDay(var/month, var/day) @@ -35,3 +24,8 @@ proc/isDay(var/month, var/day) // Uncomment this out when debugging! //else //return 1 + +//returns timestamp in a sql and ISO 8601 friendly format +/proc/SQLtime() + return time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") + \ No newline at end of file diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index cd38e6e34d8..00a878bf27f 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -64,4 +64,6 @@ var/score_dmgestjob = null var/score_dmgestdamage = 0 var/score_dmgestkey = null -var/TAB = "    " \ No newline at end of file +var/TAB = "    " + +var/timezoneOffset = 0 // The difference betwen midnight (of the host computer) and 0 world.ticks. \ No newline at end of file diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 9264feaa869..edee5035f2d 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -115,12 +115,6 @@ if(vname) speaker_name = vname - - if(istype(speaker, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = speaker - if(H.voice) - speaker_name = H.voice - if(hard_to_hear) speaker_name = "unknown" diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index dcff5244f6d..f93bbb0cb67 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -66,7 +66,7 @@ interpreter.SetVar("$science", 1351) interpreter.SetVar("$command", 1353) interpreter.SetVar("$medical", 1355) - interpreter.SetVar("$engineering",1357) + interpreter.SetVar("$engineering", 1357) interpreter.SetVar("$security", 1359) interpreter.SetVar("$supply", 1347) interpreter.SetVar("$service", 1349) @@ -79,6 +79,12 @@ 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 + + var/datum/language/speaking = signal.data["language"] + if(speaking) + interpreter.SetVar("$language", speaking.name) + else + interpreter.SetVar("$language", "Unknown") // Set up the script procs @@ -102,49 +108,9 @@ */ interpreter.SetProc("mem", "mem", signal, list("address", "value")) - /* - -> Delay code for a given amount of deciseconds - @format: sleep(time) - - @param time: time to sleep in deciseconds (1/10th second) - */ - interpreter.SetProc("sleep", /proc/delay) - - /* - -> Replaces a string with another string - @format: replace(string, substring, replacestring) - - @param string: the string to search for substrings (best used with $content$ constant) - @param substring: the substring to search for - @param replacestring: the string to replace the substring with - - */ - interpreter.SetProc("replace", /proc/string_replacetext) - - /* - -> Locates an element/substring inside of a list or string - @format: find(haystack, needle, start = 1, end = 0) - - @param haystack: the container to search - @param needle: the element to search for - @param start: the position to start in - @param end: the position to end in - - */ - interpreter.SetProc("find", /proc/smartfind) - - /* - -> Finds the length of a string or list - @format: length(container) - - @param container: the list or container to measure - - */ - interpreter.SetProc("length", /proc/smartlength) - /* -- Clone functions, carried from default BYOND procs --- */ - - // vector namespace + + // Vector interpreter.SetProc("vector", /proc/n_list) interpreter.SetProc("at", /proc/n_listpos) interpreter.SetProc("copy", /proc/n_listcopy) @@ -153,19 +119,22 @@ 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/prob_chance) - interpreter.SetProc("substr", /proc/docopytext) + interpreter.SetProc("prob", /proc/n_prob) + interpreter.SetProc("substr", /proc/n_substr) + interpreter.SetProc("find", /proc/n_smartfind) + interpreter.SetProc("length", /proc/n_smartlength) - // Donkie~ // Strings interpreter.SetProc("lower", /proc/n_lower) interpreter.SetProc("upper", /proc/n_upper) - interpreter.SetProc("explode", /proc/string_explode) + 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) @@ -176,8 +145,20 @@ interpreter.SetProc("round", /proc/n_round) interpreter.SetProc("clamp", /proc/n_clamp) interpreter.SetProc("inrange", /proc/n_inrange) - // End of Donkie~ + 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() diff --git a/code/modules/scripting/Implementations/_Logic.dm b/code/modules/scripting/Implementations/_Logic.dm index af422c4f04c..4034315aab3 100644 --- a/code/modules/scripting/Implementations/_Logic.dm +++ b/code/modules/scripting/Implementations/_Logic.dm @@ -1,15 +1,16 @@ // Script -> BYOND code procs #define SCRIPT_MAX_REPLACEMENTS_ALLOWED 200 + // --- List operations (lists known as vectors in n_script) --- -// Clone of list() +// Creates a list out of all the arguments /proc/n_list() var/list/returnlist = list() for(var/e in args) returnlist.Add(e) return returnlist -// Clone of pick() +// Picks one random item from the list /proc/n_pick() var/list/finalpick = list() for(var/e in args) @@ -23,7 +24,7 @@ return pick(finalpick) -// Clone of list[] +// Gets/Sets a value at a key in the list /proc/n_listpos(var/list/L, var/pos, var/value) if(!istype(L, /list)) return if(isnum(pos)) @@ -39,12 +40,12 @@ else L[pos] = value -// Clone of list.Copy() +// Copies the list into a new one /proc/n_listcopy(var/list/L, var/start, var/end) if(!istype(L, /list)) return return L.Copy(start, end) -// Clone of list.Add() +// Adds arg 2,3,4,5... to the end of list at arg 1 /proc/n_listadd() var/list/chosenlist var/i = 1 @@ -58,7 +59,7 @@ if(chosenlist) chosenlist.Add(e) -// Clone of list.Remove() +// Removes arg 2,3,4,5... from list at arg 1 /proc/n_listremove() var/list/chosenlist var/i = 1 @@ -72,34 +73,26 @@ if(chosenlist) chosenlist.Remove(e) -// Clone of list.Cut() +// Cuts out a copy of a list /proc/n_listcut(var/list/L, var/start, var/end) if(!istype(L, /list)) return return L.Cut(start, end) -// Clone of list.Swap() +// Swaps two values in the list /proc/n_listswap(var/list/L, var/firstindex, var/secondindex) if(!istype(L, /list)) return if(L.len >= secondindex && L.len >= firstindex) return L.Swap(firstindex, secondindex) -// Clone of list.Insert() +// Inserts a value into the list /proc/n_listinsert(var/list/L, var/index, var/element) if(!istype(L, /list)) return return L.Insert(index, element) -// --- Miscellaneous functions --- +// --- String methods --- -// Clone of sleep() -/proc/delay(var/time) - sleep(time) - -// Clone of prob() -/proc/prob_chance(var/chance) - return prob(chance) - -// Merge of list.Find() and findtext() -/proc/smartfind(var/haystack, var/needle, var/start = 1, var/end = 0) +//If list, finds a value in it, if text, finds a substring in it +/proc/n_smartfind(var/haystack, var/needle, var/start = 1, var/end = 0) if(haystack && needle) if(isobject(haystack)) if(istype(haystack, /list)) @@ -111,65 +104,41 @@ if(istext(haystack)) 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) + +//Returns a substring of the string +/proc/n_substr(var/string, var/start = 1, var/end = 0) if(istext(string) && isnum(start) && isnum(end)) if(start > 0) return copytext(string, start, end) -// Clone of length() -/proc/smartlength(var/container) +//Returns the length of the string or list +/proc/n_smartlength(var/container) if(container) if(istype(container, /list) || istext(container)) return length(container) -// BY DONKIE~ -// String stuff +//Lowercase all characters /proc/n_lower(var/string) if(istext(string)) return lowertext(string) +//Uppercase all characters /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)) +//Converts a string to a list +/proc/n_explode(var/string, var/separator = "") + if(istext(string) && (istext(separator) || isnull(separator))) return text2list(string, separator) -proc/n_repeat(var/string, var/amount) +//Converts a list to a string +/proc/n_implode(var/list/li, var/separator) + if(istype(li) && (istext(separator) || isnull(separator))) + return list2text(li, separator) + +//Repeats the string x times +/proc/n_repeat(var/string, var/amount) if(istext(string) && isnum(amount)) var/i var/newstring = "" @@ -182,7 +151,8 @@ proc/n_repeat(var/string, var/amount) return newstring -proc/n_reverse(var/string) +//Reverses the order of the string. "Clown" becomes "nwolC" +/proc/n_reverse(var/string) if(istext(string)) var/newstring = "" var/i @@ -193,45 +163,92 @@ proc/n_reverse(var/string) 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) +// String -> Number +/proc/n_str2num(var/string) if(istext(string)) return text2num(string) +/proc/n_proper(var/string) + if(!istext(string)) + return "" + + return text("[][]", uppertext(copytext(string, 1, 2)), lowertext(copytext(string, 2))) + + +// --- Number methods --- + +//Returns the highest value of the arguments +//Need custom functions here cause byond's min and max runtimes if you give them a string or list. +/proc/n_max() + if(args.len == 0) + return 0 + + var/max = args[1] + for(var/e in args) + if(isnum(e) && e > max) + max = e + + return max + +//Returns the lowest value of the arguments +/proc/n_min() + if(args.len == 0) + return 0 + + var/min = args[1] + for(var/e in args) + if(isnum(e) && e < min) + min = e + + return min + +/proc/n_prob(var/chance) + return prob(chance) + +/proc/n_randseed(var/seed) + rand_seed(seed) + return 0 + +/proc/n_rand(var/low, var/high) + if(isnull(low) && isnull(high)) + return rand() + + return rand(low, high) + // Number shit -proc/n_num2str(var/num) +/proc/n_num2str(var/num) if(isnum(num)) return num2text(num) // Squareroot -proc/n_sqrt(var/num) +/proc/n_sqrt(var/num) if(isnum(num)) return sqrt(num) // Magnitude of num -proc/n_abs(var/num) +/proc/n_abs(var/num) if(isnum(num)) return abs(num) // Round down -proc/n_floor(var/num) +/proc/n_floor(var/num) if(isnum(num)) return round(num) // Round up -proc/n_ceil(var/num) +/proc/n_ceil(var/num) if(isnum(num)) return round(num)+1 // Round to nearest integer -proc/n_round(var/num) +/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) +/proc/n_clamp(var/num, var/min=-1, var/max=1) if(isnum(num)&&isnum(min)&&isnum(max)) if(num<=min) return min @@ -240,52 +257,60 @@ proc/n_clamp(var/num, var/min=-1, var/max=1) return num // Returns 1 if N is inbetween Min and Max -proc/n_inrange(var/num, var/min=-1, var/max=1) +/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 :( -// Non-recursive -// Imported from Mono string.ReplaceUnchecked -/proc/string_replacetext(var/haystack,var/a,var/b) - if(istext(haystack)&&istext(a)&&istext(b)) - var/i = 1 - var/lenh=lentext(haystack) - var/lena=lentext(a) - //var/lenb=lentext(b) +// Returns the sine of num +/proc/n_sin(var/num) + if(isnum(num)) + return sin(num) + +// Returns the cosine of num +/proc/n_cos(var/num) + if(isnum(num)) + return cos(num) + +// Returns the arcsine of num +/proc/n_asin(var/num) + if(isnum(num)&&-1<=num&&num<=1) + return arcsin(num) + +// Returns the arccosine of num +/proc/n_acos(var/num) + if(isnum(num)&&-1<=num&&num<=1) + return arccos(num) + +// Returns the natural log of num +/proc/n_log(var/num) + if(isnum(num)&&0 SCRIPT_MAX_REPLACEMENTS_ALLOWED) break - else - if (count < SCRIPT_MAX_REPLACEMENTS_ALLOWED) - dat+=found - count+=1 - else - //diary << "Script found [a] [count] times, aborted" - break - //diary << "Found [a] at [found]! Moving up..." - i = found + lena - if (count == 0) - return haystack - //var/nlen = lenh + ((lenb - lena) * count) - var/buf = copytext(haystack,1,dat[1]) // Prefill - var/lastReadPos = 0 - for (i = 1, i <= count, i++) - var/precopy = dat[i] - lastReadPos-1 - //internal static unsafe void CharCopy (String target, int targetIndex, String source, int sourceIndex, int count) - //fixed (char* dest = target, src = source) - //CharCopy (dest + targetIndex, src + sourceIndex, count); - //CharCopy (dest + curPos, source + lastReadPos, precopy); - buf+=copytext(haystack,lastReadPos,precopy) - diary << "buf+=copytext([haystack],[lastReadPos],[precopy])" - diary<<"[buf]" - lastReadPos = dat[i] + lena - //CharCopy (dest + curPos, replace, newValue.length); - buf+=b - diary<<"[buf]" - buf+=copytext(haystack,lastReadPos, 0) - return buf \ No newline at end of file + var/found = findtext(text, find, last_found, 0) + . += copytext(text, last_found, found) + if(found) + . += replacement + last_found = found + find_len + continue + return + +// --- Miscellaneous functions --- + +/proc/n_time() + return world.timeofday + +// Clone of sleep() +/proc/n_delay(var/time) + sleep(time) \ No newline at end of file diff --git a/code/modules/scripting/Interpreter/Evaluation.dm b/code/modules/scripting/Interpreter/Evaluation.dm index 02cdc929c5c..0b612608e7f 100644 --- a/code/modules/scripting/Interpreter/Evaluation.dm +++ b/code/modules/scripting/Interpreter/Evaluation.dm @@ -134,7 +134,7 @@ else if(isobject(b) && !isobject(a)) RaiseError(new/runtimeError/TypeMismatch("/", a, b)) return null - if(b==0) + if(b==0 || b==null) RaiseError(new/runtimeError/DivisionByZero()) return null return a/b diff --git a/code/modules/scripting/Scanner/Scanner.dm b/code/modules/scripting/Scanner/Scanner.dm index 35f21b39fd0..a667becea17 100644 --- a/code/modules/scripting/Scanner/Scanner.dm +++ b/code/modules/scripting/Scanner/Scanner.dm @@ -118,13 +118,14 @@ for(, src.codepos<=lentext(code), src.codepos++) var/char=copytext(code, codepos, codepos+1) + var/nextchar=copytext(code, codepos+1, codepos+2) if(char=="\n") line++ linepos=codepos if(ignore.Find(char)) continue - else if(char == "/") + else if(char == "/" && (nextchar == "/" || nextchar == "*")) ReadComment() else if(end_stmt.Find(char)) tokens+=new /token/end(char, line, COL) diff --git a/code/world.dm b/code/world.dm index 2086f563590..5378d235fe6 100644 --- a/code/world.dm +++ b/code/world.dm @@ -42,6 +42,8 @@ var/global/datum/global_init/init = new () // dumb and hardcoded but I don't care~ config.server_name += " #[(world.port % 1000) / 100]" + timezoneOffset = text2num(time2text(0,"hh")) * 36000 + if(config && config.log_runtime) log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")