Initial Commit

This commit is contained in:
Tobba
2016-03-06 20:52:14 +01:00
commit b181d0b552
4325 changed files with 579453 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
/proc/AStar(start, end, adjacent, heuristic, maxtraverse = 30, adjacent_param = null, exclude = null)
var/list/open = list(start), list/nodeG = list(), list/nodeParent = list(), P = 0
while (P++ < open.len)
var/T = open[P], TG = nodeG[T]
if (T == end)
var/list/R = list()
while (T)
R.Insert(1, T)
T = nodeParent[T]
return R
var/list/other = call(T, adjacent)(adjacent_param)
for (var/next in other)
if (open.Find(next) || next == exclude) continue
var/G = TG + other[next], F = G + call(next, heuristic)(end)
for (var/i = P; i <= open.len;)
if (i++ == open.len || open[open[i]] >= F)
open.Insert(i, next)
open[next] = F
break
nodeG[next] = G
nodeParent[next] = T
if (P > maxtraverse)
return
+171
View File
@@ -0,0 +1,171 @@
/* *********************************************************************
_____ _ ______ _ _ _____
/ ____| | | | ____| | | | |_ _|
| | __ ___| |_ | |__ | | __ _| |_ | | ___ ___ _ __
| | |_ |/ _ \ __| | __| | |/ _` | __| | | / __/ _ \| '_ \
| |__| | __/ |_ | | | | (_| | |_ _| || (_| (_) | | | |
\_____|\___|\__| |_| |_|\__,_|\__| |_____\___\___/|_| |_|
Created by David "DarkCampainger" Braun
Released under the Unlicense (see end of file)
Version 3.0 - September 19, 2014
*///////////////////////////////////////////////////////////////////////
// Associative list of [md5 values = Icon] for determining if the icon already exists
var/list/_flatIcons = list()
proc
getFlatIcon(atom/A, dir, cache=1) // 1 = use cache, 2 = override cache, 0 = ignore cache
var/list/layers = list() // Associative list of [overlay = layer]
var/hash = "" // Hash of overlay combination
if(!dir) dir = A.dir // dir defaults to A's dir
var/parentColor = ""
if(A.color || A.alpha != 255)
parentColor = (A.color || "#FFFFFF") + copytext(rgb(0,0,0,A.alpha), 8)
// Add the atom's icon itself
if(A.icon)
// Make a copy without pixel_x/y settings
var/image/copy = image(icon=A.icon,icon_state=A.icon_state,layer=A.layer,dir=dir)
layers[copy] = A.layer
// Loop through the underlays, then overlays, sorting them into the layers list
var
list/process = A.underlays // Current list being processed
processSubset=0 // Which list is being processed: 0 = underlays, 1 = overlays
currentIndex=1 // index of 'current' in list being processed
currentOverlay // Current overlay being sorted
currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER)
compareOverlay // The overlay that the current overlay is being compared against
compareIndex // The index in the layers list of 'compare'
while(TRUE)
if(currentIndex<=process.len)
currentOverlay = process[currentIndex]
currentLayer = currentOverlay:layer
if(currentLayer<0) // Special case for FLY_LAYER
ASSERT(currentLayer > -1000)
if(processSubset == 0) // Underlay
currentLayer = A.layer+currentLayer/1000
else // Overlay
currentLayer = A.layer+(1000+currentLayer)/1000
// Sort add into layers list
for(compareIndex=1,compareIndex<=layers.len,compareIndex++)
compareOverlay = layers[compareIndex]
if(currentLayer < layers[compareOverlay]) // Associated value is the calculated layer
layers.Insert(compareIndex,currentOverlay)
layers[currentOverlay] = currentLayer
break
if(compareIndex>layers.len) // Reached end of list without inserting
layers[currentOverlay]=currentLayer // Place at end
currentIndex++
if(currentIndex>process.len)
if(processSubset == 0) // Switch to overlays
currentIndex = 1
processSubset = 1
process = A.overlays
else // All done
break
if(cache!=0) // If cache is NOT disabled
// Create a hash value to represent this specific flattened icon
hash = "[parentColor];__;"
for(var/I in layers)
hash += "\ref[I:icon],[I:icon_state],[I:dir != SOUTH ? I:dir : dir],[I:pixel_x],[I:pixel_y],[I:color],[I:alpha];_;"
hash=md5(hash)
if(cache!=2) // If NOT overriding cache
// Check if the icon has already been generated
if((hash in _flatIcons) && _flatIcons[hash])
// Icon already exists, just return that one
return _flatIcons[hash]
var
// We start with a blank canvas, otherwise some icon procs crash silently
icon/flat = icon('icons/misc/flatBlank.dmi') // Final flattened icon
icon/add // Icon of overlay being added
// Set current dimensions of flattened icon
flatX1=1
flatX2=flat.Width()
flatY1=1
flatY2=flat.Height()
// Dimensions of overlay being added
addX1;addX2;addY1;addY2
for(var/I in layers)
add = icon(I:icon || A.icon
, I:icon_state || (I:icon && (A.icon_state in icon_states(I:icon)) && A.icon_state)
, (I:dir != SOUTH ? I:dir : dir)
, 1
, 0)
// Apply any color or alpha settings
if(I:color || I:alpha != 255)
var/rgba = (I:color || "#FFFFFF") + copytext(rgb(0,0,0,I:alpha), 8)
add.Blend(rgba, ICON_MULTIPLY)
if(parentColor)
add.Blend(parentColor, ICON_MULTIPLY)
// Find the new dimensions of the flat icon to fit the added overlay
addX1 = min(flatX1, I:pixel_x+1)
addX2 = max(flatX2, I:pixel_x+add.Width())
addY1 = min(flatY1, I:pixel_y+1)
addY2 = max(flatY2, I:pixel_y+add.Height())
if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2)
// Resize the flattened icon so the new icon fits
flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1)
flatX1=addX1;flatX2=addX2
flatY1=addY1;flatY2=addY2
// Blend the overlay into the flattened icon
flat.Blend(add,ICON_OVERLAY,I:pixel_x+2-flatX1,I:pixel_y+2-flatY1)
if(cache!=0) // If cache is NOT disabled
// Cache the generated icon in our list so we don't have to regenerate it
_flatIcons[hash] = flat
return flat
/* License:
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
+620
View File
@@ -0,0 +1,620 @@
/datum/parse_result
var/string = ""
var/chars_used = 0
/datum/text_roamer
var/string = ""
var/curr_char_pos = 0
var/curr_char = ""
var/prev_char = ""
var/next_char = ""
var/next_next_char = ""
var/next_next_next_char = ""
New(var/str)
if(isnull(str)) qdel(src)
string = str
curr_char_pos = 1
curr_char = copytext(string,curr_char_pos,curr_char_pos+1)
if(length(string) > 1) next_char = copytext(string,curr_char_pos+1,curr_char_pos+2)
if(length(string) > 2) next_next_char = copytext(string,curr_char_pos+2,curr_char_pos+3)
if(length(string) > 3) next_next_next_char = copytext(string,curr_char_pos+3,curr_char_pos+4)
proc
in_word()
if(prev_char != "" && prev_char != " " && next_char != "" && next_char != " ") return 1
else return 0
end_of_word()
if(prev_char != "" && prev_char != " " && (next_char == "" || next_char == " ") ) return 1
else return 0
alone()
if((prev_char == "" || prev_char == " ") && (next_char == "" || next_char == " ") ) return 1
else return 0
update()
curr_char = copytext(string,curr_char_pos,curr_char_pos+1)
if(curr_char_pos + 1 <= length(string))
next_char = copytext(string,curr_char_pos+1,curr_char_pos+2)
else
next_char = ""
if(curr_char_pos + 2 <= length(string))
next_next_char = copytext(string,curr_char_pos+2,curr_char_pos+3)
else
next_next_char = ""
if(curr_char_pos + 3 <= length(string))
next_next_next_char = copytext(string,curr_char_pos+3,curr_char_pos+4)
else
next_next_next_char = ""
if(curr_char_pos - 1 >= 1)
prev_char = copytext(string,curr_char_pos-1,curr_char_pos)
else
prev_char = ""
return
next()
if(curr_char_pos + 1 <= length(string))
curr_char_pos++
curr_char = copytext(string,curr_char_pos,curr_char_pos+1)
if(curr_char_pos + 1 <= length(string))
next_char = copytext(string,curr_char_pos+1,curr_char_pos+2)
else
next_char = ""
if(curr_char_pos + 2 <= length(string))
next_next_char = copytext(string,curr_char_pos+2,curr_char_pos+3)
else
next_next_char = ""
if(curr_char_pos + 3 <= length(string))
next_next_next_char = copytext(string,curr_char_pos+3,curr_char_pos+4)
else
next_next_next_char = ""
if(curr_char_pos - 1 >= 1)
prev_char = copytext(string,curr_char_pos-1,curr_char_pos)
else
prev_char = ""
return
prev()
if(curr_char_pos - 1 >= 1)
curr_char_pos--
curr_char = copytext(string,curr_char_pos,curr_char_pos+1)
if(curr_char_pos + 1 <= length(string))
next_char = copytext(string,curr_char_pos+1,curr_char_pos+2)
else
next_char = ""
if(curr_char_pos + 2 <= length(string))
next_next_char = copytext(string,curr_char_pos+2,curr_char_pos+3)
else
next_next_char = ""
if(curr_char_pos + 3 <= length(string))
next_next_next_char = copytext(string,curr_char_pos+3,curr_char_pos+4)
else
next_next_next_char = ""
if(curr_char_pos - 1 >= 1)
prev_char = copytext(string,curr_char_pos-1,curr_char_pos)
else
prev_char = ""
return
/proc/elvis_parse(var/datum/text_roamer/R)
var/new_string = ""
var/used = 0
switch(R.curr_char)
if("t")
if(R.next_char == "i" && R.next_next_char == "o" && R.next_next_next_char == "n")
new_string = "shun"
used = 4
else if(R.next_char == "h" && R.next_next_char == "e")
new_string = "tha"
used = 3
else if(R.next_char == "h" && (R.next_next_char == " " || R.next_next_char == "," || R.next_next_char == "." || R.next_next_char == "-"))
new_string = "t" + R.next_next_char
used = 3
if("T")
if(R.next_char == "I" && R.next_next_char == "O" && R.next_next_next_char == "N")
new_string = "SHUN"
used = 4
else if(R.next_char == "H" && R.next_next_char == "E")
new_string = "THA"
used = 3
else if(R.next_char == "H" && (R.next_next_char == " " || R.next_next_char == "," || R.next_next_char == "." || R.next_next_char == "-"))
new_string = "T" + R.next_next_char
used = 3
if("u")
if (R.prev_char != " " || R.next_char != " ")
new_string = "uh"
used = 2
if("U")
if (R.prev_char != " " || R.next_char != " ")
new_string = "UH"
used = 2
if("o")
if (R.next_char == "w" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "aw"
used = 2
else if (R.prev_char != " " || R.next_char != " ")
new_string = "ah"
used = 1
if("O")
if (R.next_char == "W" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "AW"
used = 2
else if (R.prev_char != " " || R.next_char != " ")
new_string = "AH"
used = 1
if("i")
if (R.next_char == "r" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "ahr"
used = 2
else if(R.next_char == "n" && R.next_next_char == "g")
new_string = "in'"
used = 3
if("I")
if (R.next_char == "R" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "AHR"
used = 2
else if(R.next_char == "N" && R.next_next_char == "G")
new_string = "IN'"
used = 3
if("e")
if (R.next_char == "n" && R.next_next_char == " ")
new_string = "un "
used = 3
if (R.next_char == "r" && R.next_next_char == " ")
new_string = "ah "
used = 3
else if (R.next_char == "w" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "yew"
used = 2
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "ee"
used = 1
if("E")
if (R.next_char == "N" && R.next_next_char == " ")
new_string = "UN "
used = 3
if (R.next_char == "R" && R.next_next_char == " ")
new_string = "AH "
used = 3
else if (R.next_char == "W" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "YEW"
used = 2
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "EE"
used = 1
if("a")
if (R.next_char == "u")
new_string = "ah"
used = 2
else if (R.next_char == "n")
new_string = "ain"
used = (R.next_next_char == "d" ? 3 : 2)
if("A")
if (R.next_char == "U")
new_string = "AH"
used = 2
else if (R.next_char == "N")
new_string = "AIN"
used = (R.next_next_char == "D" ? 3 : 2)
if(new_string == "")
new_string = R.curr_char
used = 1
var/datum/parse_result/P = new/datum/parse_result
P.string = new_string
P.chars_used = used
return P
/proc/borkborkbork_parse(var/datum/text_roamer/R)
var/new_string = ""
var/used = 0
switch(R.curr_char)
if("f")
if(R.prev_char != " " || R.next_char != " ")
new_string = "ff"
used = 1
if("F")
if(R.prev_char != " " || R.next_char != " ")
new_string = "FF"
used = 1
if("w")
new_string = "v"
used = 1
if("W")
new_string = "V"
used = 1
if("v")
new_string = "f"
used = 1
if("V")
new_string = "F"
used = 1
if("t")
if(R.next_char == "i" && R.next_next_char == "o" && R.next_next_next_char == "n")
new_string = "shun"
used = 4
else if(R.next_char == "h" && R.next_next_char == "e")
new_string = "zee"
used = 3
else if(R.next_char == "h" && (R.next_next_char == " " || R.next_next_char == "," || R.next_next_char == "." || R.next_next_char == "-"))
new_string = "t" + R.next_next_char
used = 3
if("T")
if(R.next_char == "I" && R.next_next_char == "O" && R.next_next_next_char == "N")
new_string = "SHUN"
used = 4
else if(R.next_char == "H" && R.next_next_char == "E")
new_string = "ZEE"
used = 3
else if(R.next_char == "H" && (R.next_next_char == " " || R.next_next_char == "," || R.next_next_char == "." || R.next_next_char == "-"))
new_string = "T" + R.next_next_char
used = 3
if("u")
if (R.prev_char != " " || R.next_char != " ")
new_string = "oo"
used = 1
if("U")
if (R.prev_char != " " || R.next_char != " ")
new_string = "OO"
used = 1
if("o")
if (R.next_char == "w" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "oo"
used = 2
else if (R.prev_char != " " || R.next_char != " ")
new_string = "u"
used = 1
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "oo"
used = 1
if("O")
if (R.next_char == "W" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "OO"
used = 2
else if (R.prev_char != " " || R.next_char != " ")
new_string = "U"
used = 1
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "OO"
used = 1
if("i")
if (R.next_char == "r" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "ur"
used = 2
else if(R.prev_char != " " || R.next_char != " ")
new_string = "ee"
used = 1
if("I")
if (R.next_char == "R" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "UR"
used = 2
else if(R.prev_char != " " || R.next_char != " ")
new_string = "EE"
used = 1
if("e")
if (R.next_char == "n" && R.next_next_char == " ")
new_string = "ee "
used = 3
else if (R.next_char == "w" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "oo"
used = 2
else if ((R.next_char == " " || R.next_char == "," || R.next_char == "." || R.next_char == "-") && R.prev_char != " ")
new_string = "e-a" + R.next_char
used = 2
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "i"
used = 1
if("E")
if (R.next_char == "N" && R.next_next_char == " ")
new_string = "EE "
used = 3
else if (R.next_char == "W" && (R.prev_char != " " || R.next_next_char != " "))
new_string = "OO"
used = 2
else if ((R.next_char == " " || R.next_char == "," || R.next_char == "." || R.next_char == "-") && R.prev_char != " ")
new_string = "E-A" + R.next_char
used = 2
else if(R.next_char == " " && R.prev_char == " ") ///!!!
new_string = "i"
used = 1
if("a")
if (R.next_char == "u")
new_string = "oo"
used = 2
else if (R.next_char == "n")
new_string = "un"
used = 2
else
new_string = "e" //{WC} ?
used = 1
if("A")
if (R.next_char == "U")
new_string = "OO"
used = 2
else if (R.next_char == "N")
new_string = "UN"
used = 2
else
new_string = "E" //{WC} ?
used = 1
if(new_string == "")
new_string = R.curr_char
used = 1
var/datum/parse_result/P = new/datum/parse_result
P.string = new_string
P.chars_used = used
return P
/proc/tommy_parse(var/datum/text_roamer/R)
var/S = R.curr_char
var/new_string = ""
var/used = 1
switch(S)
if("a")
new_string = "ah"
used = 1
if("A")
new_string = "AH"
used = 1
if("e")
switch(rand(1,2))
if(1)
new_string = "ee"
if(2)
new_string = "ea"
used = 1
if("E")
switch(rand(1,2))
if(1)
new_string = "EE"
if(2)
new_string = "EA"
used = 1
if("i")
new_string = "ii"
used = 1
if("I")
new_string = "II"
used = 1
if("o")
if(R.next_char == "u")
new_string = "oou"
used = 1
else
new_string = "oe"
used = 1
if("O")
if(R.next_char == "U")
new_string = "OOU"
used = 1
else
new_string = "OE"
used = 1
if("u")
if(R.next_char == " " || R.next_char == "." || R.next_char == "!" || R.next_char == "?" || R.next_char == ",")
new_string = "ue"
used = 1
else if(prob(50))
new_string = "uu"
used = 1
if("U")
if(R.next_char == " " || R.next_char == "." || R.next_char == "!" || R.next_char == "?" || R.next_char == ",")
new_string = "UE"
used = 1
else if(prob(50))
new_string = "UU"
used = 1
if("h")
if(R.next_char == "y")
new_string = "hai"
used = 2
if("H")
if(R.next_char == "Y")
new_string = "HAI"
used = 2
if("r")
if(R.next_char != "h")
new_string = "wh"
used = 2
else if(R.prev_char != "h")
new_string = "hw"
used = 2
else
new_string = "w"
used = 1
if("R")
if(R.next_char != "H")
new_string = "WH"
used = 2
else if(R.prev_char != "H")
new_string = "HW"
used = 2
else
new_string = "W"
used = 1
if(!new_string)
new_string = R.curr_char
used = 1
else if(prob(10))
new_string = uppertext(new_string)
var/datum/parse_result/P = new
P.string = new_string
P.chars_used = used
return P
/proc/tommify(var/string)
var/modded = ""
var/datum/text_roamer/T = new/datum/text_roamer(string)
for(var/i = 0, i < length(string), i=i)
var/datum/parse_result/P = tommy_parse(T)
modded += P.string
i += P.chars_used
T.curr_char_pos = T.curr_char_pos + P.chars_used
T.update()
if(copytext(string, length(string)) == "!")
modded = uppertext(modded) + "!!"
else if(prob(50) && (copytext(string, length(string)) == "?"))
modded = uppertext(modded) + "?[ prob(50) ? " HUH!?" : null]"
return modded
/proc/borkborkbork(var/string)
var/modded = ""
var/datum/text_roamer/T = new/datum/text_roamer(string)
for(var/i = 0, i < length(string), i=i)
var/datum/parse_result/P = borkborkbork_parse(T)
modded += P.string
i += P.chars_used
T.curr_char_pos = T.curr_char_pos + P.chars_used
T.update()
if(prob(15))
modded += " Bork Bork Bork!"
if(prob(5))
modded += " Bork."
return modded
/proc/elvisfy(var/string)
var/modded = ""
var/datum/text_roamer/T = new/datum/text_roamer(string)
for(var/i = 0, i < length(string), i=i)
var/datum/parse_result/P = elvis_parse(T)
modded += P.string
i += P.chars_used
T.curr_char_pos = T.curr_char_pos + P.chars_used
T.update()
if(prob(15)) modded += pick(", uh huh.", ", alright?", ", mmhmm.", ", y'all.");
return modded
/proc/voidSpeak(var/message) // sharing the creepiness with everyone!!
if (!message)
return
var/fontSize = 1
var/fontIncreasing = 1
var/fontSizeMax = 3
var/fontSizeMin = -3
var/messageLen = length(message)
var/processedMessage = ""
for (var/i = 1, i <= messageLen, i++)
processedMessage += "<font size=[fontSize]>[copytext(message, i, i+1)]</font>"
if (fontIncreasing)
fontSize = min(fontSize+1, fontSizeMax)
if (fontSize >= fontSizeMax)
fontIncreasing = 0
else
fontSize = max(fontSize-1, fontSizeMin)
if (fontSize <= fontSizeMin)
fontIncreasing = 1
return "<i><b>[processedMessage]</b></i>"
// zalgo text proc, borrowed from eeemo.net
//those go UP
var/list/zalgo_up = list(
"&#x030d;", "&#x030e;", "&#x0304;", "&#x0305;",
"&#x033f;", "&#x0311;", "&#x0306;", "&#x0310;",
"&#x0352;", "&#x0357;", "&#x0351;", "&#x0307;",
"&#x0308;", "&#x030a;", "&#x0342;", "&#x0343;",
"&#x0344;", "&#x034a;", "&#x034b;", "&#x034c;",
"&#x0303;", "&#x0302;", "&#x030c;", "&#x0350;",
"&#x0300;", "&#x0301;", "&#x030b;", "&#x030f;",
"&#x0312;", "&#x0313;", "&#x0314;", "&#x033d;",
"&#x0309;", "&#x0363;", "&#x0364;", "&#x0365;",
"&#x0366;", "&#x0367;", "&#x0368;", "&#x0369;",
"&#x036a;", "&#x036b;", "&#x036c;", "&#x036d;",
"&#x036e;", "&#x036f;", "&#x033e;", "&#x035b;",
"&#x0346;", "&#x031a;"
)
//those go DOWN
var/list/zalgo_down = list(
"&#x0316;", "&#x0317;", "&#x0318;", "&#x0319;",
"&#x031c;", "&#x031d;", "&#x031e;", "&#x031f;",
"&#x0320;", "&#x0324;", "&#x0325;", "&#x0326;",
"&#x0329;", "&#x032a;", "&#x032b;", "&#x032c;",
"&#x032d;", "&#x032e;", "&#x032f;", "&#x0330;",
"&#x0331;", "&#x0332;", "&#x0333;", "&#x0339;",
"&#x033a;", "&#x033b;", "&#x033c;", "&#x0345;",
"&#x0347;", "&#x0348;", "&#x0349;", "&#x034d;",
"&#x034e;", "&#x0353;", "&#x0354;", "&#x0355;",
"&#x0356;", "&#x0359;", "&#x035a;", "&#x0323;"
)
//those always stay in the middle
var/list/zalgo_mid = list(
"&#x0315;", "&#x031b;", "&#x0340;", "&#x0341;",
"&#x0358;", "&#x0321;", "&#x0322;", "&#x0327;",
"&#x0328;", "&#x0334;", "&#x0335;", "&#x0336;",
"&#x034f;", "&#x035c;", "&#x035d;", "&#x035e;",
"&#x035f;", "&#x0360;", "&#x0362;", "&#x0338;",
"&#x0337;", "&#x0361;", "&#x0489;"
)
/proc/zalgoify(var/message, var/up, var/mid, var/down)
if(!message)
return
var/new_string = ""
for (var/i = 1, i <= length(message), i++)
var/char = copytext(message, i, i+1)
new_string += char
for(var/j = 0, j < up, j++)
new_string += pick(zalgo_up)
for(var/j = 0, j < mid, j++)
new_string += pick(zalgo_mid)
for(var/j = 0, j < down, j++)
new_string += pick(zalgo_down)
return new_string
+411
View File
@@ -0,0 +1,411 @@
// Note: Don't forget to check and modify /obj/machinery/computer/card (the ID computer) as needed
// when you re-enable old credentials or add new ones.
// Also check proc/get_access_desc() (ID computer lookup) at the bottom of this file.
/var/const
access_fuck_all = 0 //Because completely empty access lists can make things grump
access_security = 1
access_brig = 2
access_armory = 3 // Unused and replaced by maxsec (HoS-exclusive).
access_forensics_lockers = 4
access_medical = 5
access_morgue = 6
access_tox = 7
access_tox_storage = 8
access_medlab = 9
access_medical_lockers = 10
access_research_director = 11
access_maint_tunnels = 12
access_external_airlocks = 13 // Unused. Most are all- or maintenance access these days.
access_emergency_storage = 14
access_change_ids = 15
access_ai_upload = 16
access_teleporter = 17
access_eva = 18
access_heads = 19 // Mostly just the bridge.
access_captain = 20
access_all_personal_lockers = 21 // Unused. Personal lockers are always linked to ID that was swiped first.
access_chapel_office = 22
access_tech_storage = 23
access_research = 24
access_bar = 25
access_janitor = 26
access_crematorium = 27
access_kitchen = 28
access_robotics = 29
access_hangar = 30 // Unused. Theoretically the pod hangars, but not implemented as such in practice.
access_cargo = 31 // QM.
access_construction = 32 // Unused.
access_chemistry = 33
access_dwaine_superuser = 34 // So it's not the same as the RD's office and locker.
access_hydro = 35
access_mail = 36 // Unused.
access_maxsec = 37 // The HoS' armory.
access_securitylockers = 38
access_carrypermit = 39 // Are allowed to carry sidearms as far as guardbuddies and secbots are concerned.
access_engineering = 40 // General engineering area and substations.
access_engineering_storage = 41 // Main metal/tool storage things.
access_engineering_eva = 42 // Engineering space suits. Currently unused.
access_engineering_power = 43 // APCs and related supplies.
access_engineering_engine = 44 // Engine room.
access_engineering_mechanic = 45 // Electronics lab.
access_engineering_atmos = 46 // Engineering's supply of gas canisters.
access_engineering_control = 48 // Engine control room.
access_engineering_chief = 49 // CE's office.
access_mining_shuttle = 47
access_mining = 50
access_mining_outpost = 51
access_syndicate_shuttle = 52 // Also to the listening post.
access_medical_director = 53
access_head_of_personnel = 55
access_special_club = 54 //Shouldnt be used for general gameplay. Used for adminevents.
/obj/var/list/req_access = null
/obj/var/req_access_txt = "0"
/obj/var/req_only_one_required = 0
/obj/New()
if(src.req_access_txt && src.req_access_txt != "0")
var/req_access_str = params2list(req_access_txt)
req_access = list()
for(var/x in req_access_str)
var/n = text2num(x)
if(n)
req_access += n
..()
//returns 1 if this mob has sufficient access to use this object
/obj/proc/allowed(mob/M, acceptIfAny=0)
//check if it doesn't require any access at all
if (src.check_access(null))
return 1
if (M && ismob(M))
if (src.check_access(M.equipped(), acceptIfAny))
return 1
if (ishuman(M))
var/mob/living/carbon/human/H = M
//if they are holding or wearing a card that has access, that works
if (src.check_access(H.wear_id, acceptIfAny))
return 1
else if (issilicon(M))
var/mob/living/silicon/S = M
if (src.check_access(S.botcard, acceptIfAny))
return 1
return 0
/obj/proc/check_access(obj/item/I, acceptAny=0)
if(!src.req_access) //no requirements
return 1
if(!istype(src.req_access, /list)) //something's very wrong
return 1
if (istype(I, /obj/item/device/pda2))
var/obj/item/device/pda2/P = I
if (P.ID_card)
I = P.ID_card
var/obj/item/card/id/ID = I
if (!istype(ID))
return 0
var/list/L = src.req_access
if(!L.len) //no requirements
return 1
if(!ID.access) //not ID or no access
return 0
if (acceptAny)
for(var/req in src.req_access)
if (req in ID.access)
return 1
return 0
else
for(var/req in src.req_access)
if(!(req in ID.access)) //doesn't have this access
return 0
return 1
// I moved all the duplicate definitions from jobs.dm to this global lookup proc.
// Advantages: can be used by other stuff (bots etc), and there's less code to maintain (Convair880).
/proc/get_access(job)
switch(job)
///////////////////////////// Heads of staff
if("Captain")
return get_all_accesses()
if("Head of Personnel")
return list(access_security, access_carrypermit, access_brig, access_forensics_lockers, access_armory,
access_tox, access_tox_storage, access_chemistry, access_medical, access_medlab,
access_emergency_storage, access_change_ids, access_eva, access_heads, access_head_of_personnel, access_medical_lockers,
access_all_personal_lockers, access_tech_storage, access_maint_tunnels, access_bar, access_janitor,
access_crematorium, access_kitchen, access_robotics, access_cargo,
access_research, access_hydro, access_mail, access_ai_upload)
if("Head of Security")
if (map_setting == "DESTINY")
var/list/hos_access = get_all_accesses()
hos_access += access_maxsec
return hos_access
return list(access_security, access_carrypermit, access_maxsec, access_brig, access_securitylockers, access_forensics_lockers, access_armory,
access_tox, access_tox_storage, access_chemistry, access_medical, access_medlab,
access_emergency_storage, access_change_ids, access_eva, access_heads, access_medical_lockers,
access_all_personal_lockers, access_tech_storage, access_maint_tunnels, access_bar, access_janitor,
access_crematorium, access_kitchen, access_robotics, access_cargo,
access_research, access_dwaine_superuser, access_hydro, access_mail, access_ai_upload)
if("Research Director")
return list(access_research, access_research_director, access_dwaine_superuser,
access_tech_storage, access_maint_tunnels, access_heads, access_eva, access_tox,
access_tox_storage, access_chemistry, access_teleporter, access_ai_upload)
if("Medical Director", "Head Surgeon")
return list(access_robotics, access_medical, access_morgue,
access_maint_tunnels, access_tech_storage, access_medical_lockers,
access_medlab, access_heads, access_eva, access_medical_director, access_ai_upload)
if("Chief Engineer")
return list(access_engineering, access_maint_tunnels, access_external_airlocks,
access_tech_storage, access_engineering_storage, access_engineering_eva, access_engineering_atmos,
access_engineering_power, access_engineering_engine, access_mining_shuttle,
access_engineering_control, access_engineering_mechanic, access_engineering_chief, access_mining, access_mining_outpost,
access_heads, access_ai_upload, access_construction, access_eva, access_cargo, access_hangar)
if("Head of Mining", "Mining Supervisor")
return list(access_engineering, access_maint_tunnels, access_external_airlocks,
access_engineering_eva, access_mining_shuttle, access_mining,
access_mining_outpost, access_hangar, access_heads, access_ai_upload, access_construction, access_eva)
///////////////////////////// Security
if("Security Officer")
if (map_setting == "DESTINY") // trying out giving them more access for RP
return list(access_security, access_brig, access_forensics_lockers, access_armory,
access_medical, access_medlab, access_morgue, access_securitylockers,
access_tox, access_tox_storage, access_chemistry, access_carrypermit,
access_emergency_storage, access_chapel_office, access_kitchen, access_medical_lockers,
access_bar, access_janitor, access_crematorium, access_robotics, access_cargo, access_construction, access_hydro, access_mail,
access_engineering, access_maint_tunnels, access_external_airlocks,
access_tech_storage, access_engineering_storage, access_engineering_eva,
access_engineering_power, access_engineering_engine, access_mining_shuttle,
access_engineering_control, access_engineering_mechanic, access_mining, access_mining_outpost,
access_research, access_engineering_atmos, access_hangar)
return list(access_security, access_carrypermit, access_securitylockers, access_brig, access_maint_tunnels, access_medical, access_morgue, access_crematorium, access_research)
if("Vice Officer")
return list(access_security, access_carrypermit, access_securitylockers, access_brig, access_maint_tunnels,access_hydro,access_bar,access_kitchen)
if("Detective", "Forensic Technician")
return list(access_brig, access_carrypermit, access_security, access_forensics_lockers, access_morgue, access_maint_tunnels, access_crematorium, access_medical, access_research)
if("Lawyer")
return list(access_maint_tunnels, access_security, access_brig)
///////////////////////////// Medical
if("Medical Doctor")
return list(access_medical, access_medical_lockers, access_morgue, access_maint_tunnels)
if("Geneticist")
return list(access_medical, access_medical_lockers, access_morgue, access_medlab, access_maint_tunnels)
if("Roboticist")
return list(access_robotics, access_tech_storage, access_medical, access_medical_lockers, access_morgue, access_maint_tunnels)
if("Pharmacist")
return list(access_research,access_tech_storage, access_maint_tunnels, access_chemistry,
access_medical_lockers, access_medical, access_morgue)
if("Medical Assistant")
return list(access_maint_tunnels, access_tech_storage, access_medical, access_morgue)
///////////////////////////// Science
if("Scientist")
return list(access_tox, access_tox_storage, access_research, access_chemistry)
if("Chemist")
return list(access_research, access_chemistry)
if("Toxins Researcher")
return list(access_research, access_tox, access_tox_storage)
if("Research Assistant")
return list(access_maint_tunnels, access_tech_storage, access_research)
//////////////////////////// Engineering
if("Mechanic")
return list(access_maint_tunnels, access_external_airlocks,
access_tech_storage,access_engineering_mechanic,access_engineering_power)
if("Atmospheric Technician")
return list(access_maint_tunnels, access_external_airlocks, access_construction,
access_eva, access_engineering, access_engineering_storage, access_engineering_eva, access_engineering_atmos)
if("Engineer")
return list(access_engineering,access_maint_tunnels,access_external_airlocks,
access_engineering_storage,access_engineering_atmos,access_engineering_engine,access_engineering_power)
if("Miner")
return list(access_maint_tunnels, access_external_airlocks,
access_engineering_eva, access_mining_shuttle, access_mining,
access_mining_outpost, access_hangar)
if("Quartermaster")
return list(access_maint_tunnels, access_cargo, access_hangar)
if("Construction Worker")
return list(access_engineering,access_maint_tunnels,access_external_airlocks,
access_engineering_storage,access_engineering_atmos,access_engineering_engine,access_engineering_power)
///////////////////////////// Civilian
if("Chaplain")
return list(access_morgue, access_chapel_office, access_crematorium)
if("Janitor")
return list(access_janitor, access_maint_tunnels, access_medical, access_morgue, access_crematorium)
if("Botanist", "Apiculturist")
return list(access_maint_tunnels, access_hydro)
if("Chef", "Sous-Chef")
return list(access_kitchen)
if("Barman")
return list(access_bar)
if("Waiter")
return list(access_bar, access_kitchen)
if("Clown", "Boxer", "Barber")
return list(access_maint_tunnels)
if("Assistant", "Staff Assistant", "Technical Assistant")
return list(access_maint_tunnels, access_tech_storage)
if("Mailman")
return list(access_maint_tunnels, access_mail)
//////////////////////////// Other or gimmick
if("Rescue Worker")
return get_all_accesses()
if("VIP")
return list(access_heads, access_carrypermit) // Their cane is contraband.
if("Space Cowboy")
return list(access_maint_tunnels, access_carrypermit)
if("Club member")
return list(access_special_club)
if("Inspector")
return list(access_security, access_tox, access_tox_storage, access_chemistry, access_medical, access_medlab,
access_emergency_storage, access_eva, access_heads, access_tech_storage, access_maint_tunnels, access_bar, access_janitor,
access_kitchen, access_robotics, access_cargo, access_research, access_hydro)
else
return list()
/proc/get_all_accesses()
return list(access_security, access_brig, access_forensics_lockers, access_armory,
access_medical, access_medlab, access_morgue, access_securitylockers,
access_tox, access_tox_storage, access_chemistry, access_carrypermit,
access_emergency_storage, access_change_ids, access_ai_upload,
access_teleporter, access_eva, access_heads, access_captain, access_all_personal_lockers, access_head_of_personnel,
access_chapel_office, access_kitchen, access_medical_lockers,
access_bar, access_janitor, access_crematorium, access_robotics, access_cargo, access_construction, access_hydro, access_mail,
access_engineering, access_maint_tunnels, access_external_airlocks,
access_tech_storage, access_engineering_storage, access_engineering_eva,
access_engineering_power, access_engineering_engine, access_mining_shuttle,
access_engineering_control, access_engineering_mechanic, access_engineering_chief, access_mining, access_mining_outpost,
access_research, access_research_director, access_dwaine_superuser, access_engineering_atmos, access_hangar, access_medical_director, access_special_club)
var/list/access_name_lookup //Generated at round start.
//Build the access_name_lookup table, to associate descriptions of accesses with their numerical value.
/proc/generate_access_name_lookup()
if (access_name_lookup)
return
access_name_lookup = list()
var/list/accesses = get_all_accesses()
for (var/accessNum in accesses)
access_name_lookup += "[get_access_desc(accessNum)]"
access_name_lookup = sortList(access_name_lookup) //Make the list all nice and alphabetical.
for (var/accessNum in accesses)
access_name_lookup["[get_access_desc(accessNum)]"] = accessNum
/proc/get_access_desc(A)
switch(A)
if(access_cargo)
return "Cargo Bay"
if(access_security)
return "Security"
if(access_forensics_lockers)
return "Forensics"
if(access_securitylockers)
return "Security Equipment"
if(access_medical)
return "Medical"
if(access_medical_lockers)
return "Medical Equipment"
if(access_medlab)
return "Med-Sci/Genetics"
if(access_morgue)
return "Morgue"
if(access_tox)
return "Toxins Research"
if(access_tox_storage)
return "Toxins Storage"
if(access_chemistry)
return "Chemical Lab"
if(access_bar)
return "Bar"
if(access_janitor)
return "Janitorial Equipment"
if(access_maint_tunnels)
return "Maintenance"
if(access_external_airlocks)
return "External Airlock"
if(access_emergency_storage)
return "Emergency Storage"
if(access_change_ids)
return "ID Computer"
if(access_ai_upload)
return "AI Upload"
if(access_teleporter)
return "Teleporter"
if(access_eva)
return "EVA"
if(access_heads)
return "Head's Quarters/Bridge"
if(access_captain)
return "Captain's Quarters"
if(access_all_personal_lockers)
return "Personal Locker Master Key"
if(access_chapel_office)
return "Chaplain's Office"
if(access_tech_storage)
return "Technical Storage"
if(access_crematorium)
return "Crematorium"
if(access_armory)
return "Armory (Command Staff)"
if(access_maxsec)
return "Armory (Head of Security)"
if(access_construction)
return "Construction Site"
if(access_kitchen)
return "Kitchen"
if(access_hydro)
return "Hydroponics"
if(access_mail)
return "Mailroom"
if(access_research)
return "Research Sector"
if(access_research_director)
return "Research Director's Office"
if(access_engineering)
return "Engineering"
if(access_engineering_storage)
return "Engineering Storage"
if(access_engineering_eva)
return "Engineering EVA"
if(access_engineering_power)
return "Electrical Equipment (APCs)"
if(access_engineering_engine)
return "Engine Room"
if(access_engineering_mechanic)
return "Mechanical Lab"
if(access_engineering_atmos)
return "Engineering Gas Storage/Atmospherics"
if(access_mining_shuttle)
return "Mining Outpost Shuttle"
if(access_engineering_control)
return "Engine Control Room"
if(access_engineering_chief)
return "Chief Engineer's Office"
if(access_mining)
return "Mining Department"
if(access_mining_outpost)
return "Mining Outpost"
if(access_hangar)
return "Hangar"
if(access_carrypermit)
return "Firearms Carry Permit"
if(access_medical_director)
return "Medical Director's Office"
if(access_robotics)
return "Robotics"
if(access_head_of_personnel)
return "Head of Personnel's Office"
if(access_dwaine_superuser)
return "DWAINE Superuser"
View File
+180
View File
@@ -0,0 +1,180 @@
/client/proc/gearspawn_traitor()
set category = "Commands"
set name = "Call Syndicate"
set desc="Teleports useful items to your location."
if (usr.stat || !isliving(usr) || isintangible(usr))
usr.show_text("You can't use this command right now.", "red")
return
var/obj/item/uplink/syndicate/U = new(usr.loc)
if (!usr.put_in_hand(U))
U.set_loc(get_turf(usr))
usr.show_text("<h3>Uplink spawned. You can find it on the floor at your current location.</h3>", "blue")
else
usr.show_text("<h3>Uplink spawned. You can find it in your active hand.</h3>", "blue")
if (usr.mind && istype(usr.mind))
U.lock_code_autogenerate = 1
U.setup(usr.mind)
usr.show_text("<h3>The password to your uplink is '[U.lock_code]'.</h3>", "blue")
usr.mind.store_memory("<B>Uplink password:</B> [U.lock_code].")
usr.verbs -= /client/proc/gearspawn_traitor
return
/client/proc/gearspawn_wizard()
set category = "Commands"
set name = "Call Wizards"
set desc="Teleports useful items to your location."
if (usr.stat || !isliving(usr) || isintangible(usr))
usr.show_text("You can't use this command right now.", "red")
return
if (!istype(usr,/mob/living/carbon/human))
boutput(usr, "<span style=\"color:red\">You must be a human to use this!</span>")
return
var/mob/living/carbon/human/H = usr
equip_wizard(H, 1)
usr.verbs -= /client/proc/gearspawn_wizard
return
/proc/equip_traitor(mob/living/carbon/human/traitor_mob)
if (!(traitor_mob && ishuman(traitor_mob)))
return
var/freq = null
var/pda_pass = null
// find a radio! toolbox(es), backpack, belt, headset
var/loc = ""
var/obj/item/device/R = null //Hide the uplink in a PDA if available, otherwise radio
if (!R && istype(traitor_mob.belt, /obj/item/device/pda2))
R = traitor_mob.belt
loc = "on your belt"
if (!R && istype(traitor_mob.r_store, /obj/item/device/pda2))
R = traitor_mob.r_store
loc = "In your pocket"
if (!R && istype(traitor_mob.l_store, /obj/item/device/pda2))
R = traitor_mob.l_store
loc = "In your pocket"
if (!R && istype(traitor_mob.ears, /obj/item/device/radio))
R = traitor_mob.ears
loc = "on your head"
if (!R && traitor_mob.w_uniform && istype(traitor_mob.belt, /obj/item/device/radio))
R = traitor_mob.belt
loc = "on your belt"
if (!R && istype(traitor_mob.l_hand, /obj/item/storage))
var/obj/item/storage/S = traitor_mob.l_hand
var/list/L = S.get_contents()
for (var/obj/item/device/radio/foo in L)
R = foo
loc = "in the [S.name] in your left hand"
break
if (!R && istype(traitor_mob.r_hand, /obj/item/storage))
var/obj/item/storage/S = traitor_mob.r_hand
var/list/L = S.get_contents()
for (var/obj/item/device/radio/foo in L)
R = foo
loc = "in the [S.name] in your right hand"
break
if (!R && istype(traitor_mob.back, /obj/item/storage))
var/obj/item/storage/S = traitor_mob.back
var/list/L = S.get_contents()
for (var/obj/item/device/radio/foo in L)
R = foo
loc = "in the [S.name] in your backpack"
break
if(!R)
R = new /obj/item/device/radio/headset(traitor_mob)
loc = "in the [S.name] in your backpack"
// Everything else failed and there's no room in the backpack either, oh no.
// I mean, we can't just drop a super-obvious uplink onto the floor. Hands might be full, too (Convair880).
if (traitor_mob.equip_if_possible(R, traitor_mob.slot_in_backpack) == 0)
qdel(R)
traitor_mob.verbs += /client/proc/gearspawn_traitor
traitor_mob << browse(grabResource("html/traitorTips/traitorradiouplinkTips.html"),"window=antagTips;titlebar=1;size=600x400;can_minimize=0;can_resize=0")
return
if (!R)
traitor_mob.verbs += /client/proc/gearspawn_traitor
traitor_mob << browse(grabResource("html/traitorTips/traitorradiouplinkTips.html"),"window=antagTips;titlebar=1;size=600x400;can_minimize=0;can_resize=0")
else
if (!(ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution)) && !(traitor_mob.mind && traitor_mob.mind.special_role == "Spy"))
traitor_mob << browse(grabResource("html/traitorTips/traitorTips.html"),"window=antagTips;titlebar=1;size=600x400;can_minimize=0;can_resize=0")
if (istype(R, /obj/item/device/radio))
var/obj/item/device/radio/RR = R
var/obj/item/uplink/integrated/radio/T = new /obj/item/uplink/integrated/radio(RR)
T.setup(traitor_mob.mind, RR)
freq = RR.traitor_frequency
boutput(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [RR.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Radio Freq:</B> [format_frequency(freq)] ([RR.name] [loc]).")
else if (istype(R, /obj/item/device/pda2))
var/obj/item/device/pda2/P = R
var/obj/item/uplink/integrated/pda/T = new /obj/item/uplink/integrated/pda(P)
T.setup(traitor_mob.mind, P)
pda_pass = T.lock_code
boutput(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [P.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Set your ringtone to:</B> [pda_pass] (In the Messenger menu in the [P.name] [loc]).")
/proc/equip_syndicate(mob/living/carbon/human/synd_mob)
if (!ishuman(synd_mob))
return
synd_mob.equip_if_possible(new /obj/item/device/radio/headset/syndicate(synd_mob), synd_mob.slot_ears)
synd_mob.equip_if_possible(new /obj/item/clothing/under/misc/syndicate(synd_mob), synd_mob.slot_w_uniform)
synd_mob.equip_if_possible(new /obj/item/clothing/shoes/swat(synd_mob), synd_mob.slot_shoes)
synd_mob.equip_if_possible(new /obj/item/clothing/suit/armor/vest(synd_mob), synd_mob.slot_wear_suit)
synd_mob.equip_if_possible(new /obj/item/clothing/gloves/swat(synd_mob), synd_mob.slot_gloves)
synd_mob.equip_if_possible(new /obj/item/clothing/head/helmet/swat(synd_mob), synd_mob.slot_head)
synd_mob.equip_if_possible(new /obj/item/storage/backpack(synd_mob), synd_mob.slot_back)
synd_mob.equip_if_possible(new /obj/item/ammo/bullets/a357(synd_mob), synd_mob.slot_in_backpack)
synd_mob.equip_if_possible(new /obj/item/reagent_containers/pill/tox(synd_mob), synd_mob.slot_in_backpack)
synd_mob.equip_if_possible(new /obj/item/remote/syndicate_teleporter(synd_mob), synd_mob.slot_l_store)
synd_mob.equip_if_possible(new /obj/item/gun/kinetic/revolver(synd_mob), synd_mob.slot_belt)
var/obj/item/uplink/syndicate/U = new /obj/item/uplink/syndicate(synd_mob)
if (synd_mob.mind && istype(synd_mob.mind))
U.setup(synd_mob.mind)
synd_mob.equip_if_possible(U, synd_mob.slot_r_store)
var/obj/item/card/id/syndicate/I = new /obj/item/card/id/syndicate(synd_mob) // for whatever reason, this is neccessary
I.icon_state = "id"
I.icon = 'icons/obj/card.dmi'
synd_mob.equip_if_possible(I, synd_mob.slot_wear_id)
var/obj/item/implant/syn/S = new /obj/item/implant/syn(synd_mob)
S.implanted = 1
S.implanted(synd_mob)
var/obj/item/implant/microbomb/M = new /obj/item/implant/microbomb(synd_mob)
M.implanted = 1
M.implanted(synd_mob)
S.owner = synd_mob
synd_mob.implant.Add(S)
var/the_frequency = R_FREQ_SYNDICATE
if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/nuclear))
var/datum/game_mode/nuclear/N = ticker.mode
the_frequency = N.agent_radiofreq
for (var/obj/item/device/radio/headset/R in synd_mob.contents)
if (!R.secure_frequencies)
R.secure_frequencies = list ("h" = the_frequency)
else
R.secure_frequencies["h"] = the_frequency
R.secure_colors = list(RADIOC_SYNDICATE)
R.protected_radio = 1 // Ops can spawn with the deaf trait.
R.frequency = the_frequency // let's see if this stops rounds from being ruined every fucking time
return
+50
View File
@@ -0,0 +1,50 @@
/client/proc/authorize()
set name = "Authorize"
if (admins.Find(src.ckey))
boutput(src, "<span class='ooc adminooc'>Admin IRC - #ss13centcom #ss13admin on irc.synirc.net</span>")
if (!NT.Find(src.ckey))
NT.Add(src.ckey)
//src.mentor = 1
return
return
if (NT.Find(src.ckey) || mentors.Find(src.ckey))
src.mentor = 1
src.mentor_authed = 1
boutput(src, "<span class='ooc mentorooc'>You are a mentor!</span>")
if (!src.holder)
src.verbs += /client/proc/toggle_mentorhelps
return
/client/proc/set_mentorhelp_visibility(var/set_as = null)
if (!isnull(set_as))
src.mentor = set_as
src.see_mentor_pms = set_as
else
src.mentor = !(src.mentor)
src.see_mentor_pms = src.mentor
boutput(src, "<span class='ooc mentorooc'>You will [src.mentor ? "now" : "no longer"] see Mentorhelps [src.mentor ? "and" : "or"] show up as a Mentor.</span>")
/client/proc/toggle_mentorhelps()
set name = "Toggle Mentorhelps"
set category = "Toggles"
set desc = "Show or hide mentorhelp messages. You will also no longer show up as a mentor in OOC and via the Who command if you disable mentorhelps."
if (!src.mentor_authed && !src.holder)
boutput(src, "<span style='color:red'>Only mentors may use this command.</span>")
src.verbs -= /client/proc/toggle_mentorhelps // maybe?
return
src.set_mentorhelp_visibility()
/*
/proc/proxy_check(address)
if(address)
var/result = world.Export("http://autisticpowers.info/ss13/check_ip.php?ip=[address]")
if("STATUS" in result && lowertext(result["STATUS"]) == "200 ok")
var/using_proxy = text2num(file2text(result["CONTENT"]))
if(using_proxy)
return 1
return 0
*/
+568
View File
@@ -0,0 +1,568 @@
proc/bball_nova()
set category = "Spells"
set name = "B-Ball Nova"
set desc = "Causes an eruption of explosive basketballs from your location"
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
if(!isturf(M.loc))
return
if(!M.bball_spellpower())
return
M.verbs -= /proc/bball_nova
spawn(300)
M.verbs += /proc/bball_nova
M.visible_message("<span style=\"color:red\">A swarm of basketballs erupts from [M]!</span>")
for(var/turf/T in orange(1, M))
if(!T.density)
var/target_dir = get_dir(M.loc, T)
var/turf/U = get_edge_target_turf(M, target_dir)
new /obj/newmeteor/basketball(my_spawn = T, trg = U)
/obj/newmeteor/basketball
name = "basketball"
icon = 'icons/obj/items.dmi'
icon_state = "bball_spin"
hits = 6
/proc/showboat_slam(mob/target as mob in oview(6))
set category = "Spells"
set name = "Showboat Slam"
set desc = "Leap up and slam your target for massive damage"
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
if(!isturf(M.loc) || !M.bball_spellpower())
return
M.verbs -= /proc/showboat_slam
spawn(300)
M.verbs += /proc/showboat_slam
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball2"
M.set_clothing_icon_dirty()
M.transforming = 1
M.layer = EFFECTS_LAYER_BASE
M.visible_message("<span style=\"color:red\">[M] takes a mighty leap towards the ceiling!</span>")
playsound(M.loc, "sound/effects/bionic_sound.ogg", 50)
for(var/i = 0, i < 10, i++)
M.pixel_y += 4
step_to(M, target)
sleep(1)
sleep(1)
M.pixel_y = 0
M.set_loc(target.loc)
M.transforming = 0
M.layer = MOB_LAYER
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball"
playsound(M.loc, "explosion", 50, 1)
var/obj/overlay/O = new/obj/overlay(get_turf(target))
O.anchored = 1
O.name = "Explosion"
O.layer = NOLIGHT_EFFECTS_LAYER_BASE
O.pixel_x = -17
O.icon = 'icons/effects/hugeexplosion.dmi'
O.icon_state = "explosion"
spawn(35) qdel(O)
for(var/mob/N in AIviewers(M, null))
if(get_dist(N, target) <= 2)
if(N != M)
N.weakened = max(N.weakened, 5)
random_brute_damage(N, 10)
if(N.client)
shake_camera(N, 6, 5)
N.show_message("<span style=\"color:red\">[M] showboat slams [target] to the ground!</span>", 1)
random_brute_damage(target, 40)
/proc/holy_jam()
set category = "Spells"
set name = "Holy Jam"
set desc = "Powerful jam that blinds surrounding enemies"
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
if(!isturf(M.loc) || !M.bball_spellpower())
return
M.verbs -= /proc/holy_jam
spawn(150)
M.verbs += /proc/holy_jam
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball2"
M.set_clothing_icon_dirty()
M.transforming = 1
M.layer = EFFECTS_LAYER_BASE
M.visible_message("<span style=\"color:red\">[M] takes a divine leap towards the ceiling!</span>")
playsound(M.loc, "sound/effects/heavenly.ogg", 50, 1)
for(var/i = 0, i < 10, i++)
M.pixel_y += 4
sleep(1)
sleep(1)
M.pixel_y = 0
M.transforming = 0
M.layer = MOB_LAYER
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball"
for(var/mob/N in AIviewers(M, null))
if(get_dist(N, M) <= 6)
if(N != M)
N.apply_flash(30, 5)
if(ishuman(N) && istype(N:mutantrace, /datum/mutantrace/zombie))
N.gib()
if(N.client)
shake_camera(N, 6, 4)
N.show_message("<span style=\"color:red\">[M]'s basketball unleashes a brilliant flash of light!</span>", 1)
playsound(M.loc, "sound/weapons/flashbang.ogg", 50, 1)
proc/blitz_slam()
set category = "Spells"
set name = "Blitz Slam"
set desc="Teleport randomly to a nearby tile."
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
var/SPrange = 2
if (M.bball_spellpower()) SPrange = 6
var/list/turfs = new/list()
for(var/turf/T in orange(SPrange))
if(istype(T,/turf/space)) continue
if(T.density) continue
if(T.x>world.maxx-4 || T.x<4) continue //putting them at the edge is dumb
if(T.y>world.maxy-4 || T.y<4) continue
turfs += T
if(!turfs.len) turfs += pick(/turf in orange(6))
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
smoke.set_up(10, 0, M.loc)
smoke.start()
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
M.set_loc(picked)
M.verbs -= /proc/blitz_slam
spawn(40)
M.verbs += /proc/blitz_slam
/proc/clown_jam(mob/living/target as mob in oview(6))
set category = "Spells"
set name = "Clown Jam"
set desc = "Jams the target into a fat cursed clown"
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
var/SPtime = 3000
if (M.bball_spellpower()) SPtime = 900
M.verbs -= /proc/clown_jam
spawn(SPtime)
M.verbs += /proc/clown_jam
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball2"
M.set_clothing_icon_dirty()
M.transforming = 1
M.layer = EFFECTS_LAYER_BASE
M.visible_message("<span style=\"color:red\">[M] comically leaps towards the ceiling!</span>")
playsound(M.loc, "sound/effects/bionic_sound.ogg", 50)
for(var/i = 0, i < 10, i++)
M.pixel_y += 4
M.pixel_x = rand(-4, 4)
step_to(M, target)
sleep(1)
sleep(1)
M.pixel_x = 0
M.pixel_y = 0
M.set_loc(target.loc)
M.transforming = 0
M.layer = MOB_LAYER
for(var/mob/N in AIviewers(M, null))
if(get_dist(N, target) <= 2)
if(N != M)
N.weakened = max(N.weakened, 5)
if(N.client)
shake_camera(N, 6, 4)
N.show_message("<span style=\"color:red\">[M] clown jams [target]!</span>", 1)
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball"
playsound(target.loc, "explosion", 50, 1)
playsound(target.loc, "sound/items/bikehorn.ogg", 50, 1)
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
smoke.set_up(5, 0, target.loc)
smoke.attach(target)
smoke.start()
if(target.job != "Clown")
boutput(target, "<span style=\"color:red\"><B>You HONK painfully!</B></span>")
target.take_brain_damage(80)
target.stuttering = 120
target.job = "Clown"
target.contract_disease(/datum/ailment/disease/cluwneing_around, null, null, 1) // path, name, strain, bypass resist
target.contract_disease(/datum/ailment/disability/clumsy, null, null, 1) // path, name, strain, bypass resist
target.nutrition = 9000
target.change_misstep_chance(60)
target.unequip_all()
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/cursed = target
cursed.equip_if_possible(new /obj/item/clothing/under/gimmick/cursedclown(cursed), cursed.slot_w_uniform)
cursed.equip_if_possible(new /obj/item/clothing/shoes/cursedclown_shoes(cursed), cursed.slot_shoes)
cursed.equip_if_possible(new /obj/item/clothing/mask/cursedclown_hat(cursed), cursed.slot_wear_mask)
cursed.equip_if_possible(new /obj/item/clothing/gloves/cursedclown_gloves(cursed), cursed.slot_gloves)
target.real_name = "cluwne"
else //The inverse clown principle
var/mob/living/carbon/human/H = target
if(!istype(H))
return
boutput(H, "<span style=\"color:red\"><b>You don't feel very funny.</b></span>")
H.take_brain_damage(-120)
H.stuttering = 0
H.job = "Lawyer"
H.change_misstep_chance(-INFINITY)
H.nutrition = 0
for(var/datum/ailment_data/A in H.ailments)
if(istype(A.master,/datum/ailment/disability/clumsy))
H.cure_disease(A)
var/obj/old_uniform = H.w_uniform
var/obj/item/card/id/the_id = H.wear_id
if(H.w_uniform && findtext("[H.w_uniform.type]","clown"))
H.w_uniform = new /obj/item/clothing/under/suit(H)
qdel(old_uniform)
if(H.shoes && findtext("[H.shoes.type]","clown"))
qdel(H.shoes)
H.shoes = new /obj/item/clothing/shoes/black(H)
if(the_id && the_id.registered == H.real_name)
the_id.assignment = "Lawyer"
the_id.name = "[H.real_name]'s ID Card (Lawyer)"
H.wear_id = the_id
for(var/obj/item/W in H)
if (findtext("[W.type]","clown"))
H.u_equip(W)
if (W)
W.set_loc(target.loc)
W.dropped(H)
W.layer = initial(W.layer)
return
/proc/chaos_dunk()
set category = "Spells"
set name = "Chaos Dunk"
set desc = "Destroy the entire station with the ultimate slam"
var/mob/M = src
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
var/equipped_thing = M.equipped()
if(istype(equipped_thing, /obj/item/basketball))
var/obj/item/basketball/BB = equipped_thing
if(!BB.payload)
boutput(M, __red("This b-ball doesn't have the right heft to it!"))
return
else //Safety thing to ensure the plutonium core is only good for one dunk
var/pl = BB.payload
BB.payload = null
qdel(pl)
else
boutput(M, __red("You can't dunk without a b-ball, yo!"))
return
M.verbs -= /proc/chaos_dunk
logTheThing("combat", M, null, "<b>triggers a chaos dunk in [M.loc.loc] ([showCoords(M.x, M.y, M.z)])!</b>")
for(var/obj/item/basketball/B in M.contents)
B.item_state = "bball2"
M.set_clothing_icon_dirty()
M.transforming = 1
M.layer = EFFECTS_LAYER_BASE
M.visible_message("<span style=\"color:red\">[M] flies through the ceiling!</span>")
playsound(M.loc, "sound/effects/bionic_sound.ogg", 50)
for(var/i = 0, i < 50, i++)
M.pixel_y += 6
M.dir = turn(M.dir, 90)
sleep(1)
M.layer = 0
var/sound/siren = sound('sound/misc/airraid_loop.ogg')
siren.repeat = 1
siren.channel = 5
world << siren
command_alert("A massive influx of negative b-ball protons has been detected in [get_area(M)]. A Chaos Dunk is imminent. All personnel currently on [station_name()] have 15 seconds to reach minimum safe distance. This is not a test.")
for(var/area/A in world)
spawn(0)
A.eject = 1
A.updateicon()
for(var/mob/N in mobs)
spawn(0)
shake_camera(N, 120, 2)
spawn(0)
var/thunder = 70
while(thunder > 0)
thunder--
if(prob(15))
world << sound('sound/effects/thunder.ogg', volume = 80)
for(var/mob/N in mobs)
N.flash(30)
sleep(5)
sleep(300)
playsound(M.loc, "sound/effects/bionic_sound.ogg", 50)
M.layer = EFFECTS_LAYER_BASE
for(var/i = 0, i < 20, i++)
M.pixel_y -= 12
M.dir = turn(M.dir, 90)
sleep(1)
sleep(1)
siren.repeat = 0
siren.status = SOUND_UPDATE
siren.channel = 5
world << siren
M.visible_message("<span style=\"color:red\">[M] successfully executes a Chaos Dunk!</span>")
explosion_new(src, get_turf(M), 1500, 22.78)
for(var/area/A in world)
spawn(0)
A.eject = 0
A.updateicon()
/proc/spin()
set category = "Spells"
set name = "360 Spin"
set desc = "Get fools off your back."
var/mob/M = src
if(!M.bball_spellpower())
return
if(M.stat)
boutput(M, "Not when you're incapacitated.")
return
M.transforming = 1
for(var/mob/N in AIviewers(M, null))
if(N.client)
N.show_message("<span style=\"color:red\">[M] does a quick spin, knocking you off guard!</span>", 1)
if(get_dist(N, M) <= 2)
if(N != M)
N.stunned = max(N.stunned, 2)
M.dir = NORTH
sleep(1)
M.dir = EAST
sleep(1)
M.dir = SOUTH
sleep(1)
M.dir = WEST
M.transforming = 0
M.verbs -= /proc/spin
spawn(40)
M.verbs += /proc/spin
/obj/item/bball_uplink
name = "station bounced radio"
icon = 'icons/obj/device.dmi'
icon_state = "radio"
var/temp = null
var/uses = 4.0
var/selfdestruct = 0.0
var/traitor_frequency = 0.0
var/obj/item/device/radio/origradio = null
flags = FPRINT | TABLEPASS| CONDUCT | ONBELT
item_state = "radio"
throwforce = 5
w_class = 2.0
throw_speed = 4
throw_range = 20
m_amt = 100
/obj/item/bball_uplink/proc/explode()
var/turf/location = get_turf(src.loc)
location.hotspot_expose(700, 125)
explosion(src, location, 0, 0, 2, 4)
qdel(src.master)
qdel(src)
return
/obj/item/bball_uplink/attack_self(mob/user as mob)
user.machine = src
var/dat
if (src.selfdestruct)
dat = "Self Destructing..."
else
if (src.temp)
dat = "[src.temp]<BR><BR><A href='byond://?src=\ref[src];temp=1'>Clear</A>"
else
dat = "<B>ZauberTech Baller Uplink Console:</B><BR>"
dat += "Tele-Crystals left: [src.uses]<BR>"
dat += "<HR>"
dat += "<B>Request item:</B><BR>"
dat += "<I>Each item costs 1 telecrystal. The number afterwards is the cooldown time.</I><BR>"
dat += "<A href='byond://?src=\ref[src];spell_nova=1'>B-Ball Nova</A> (30)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_showboat=1'>Showboat Slam</A> (30)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_holy=1'>Holy Jam</A> (15)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_blink=1'>Blitz Slam</A> (2)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_revengeclown=1'>Clown Jam</A> (90)<BR>"
// dat += "<A href='byond://?src=\ref[src];spell_summongolem=1'>Summon Basketball Golem</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_spin=1'>Spin (free)</A> (4)<BR>"
dat += "<HR>"
if (src.origradio)
dat += "<A href='byond://?src=\ref[src];lock=1'>Lock</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];selfdestruct=1'>Self-Destruct</A>"
user << browse(dat, "window=radio")
onclose(user, "radio")
return
/obj/item/bball_uplink/Topic(href, href_list)
..()
if (usr.stat || usr.restrained())
return
var/mob/living/carbon/human/H = usr
if (!( istype(H, /mob/living/carbon/human)))
return 1
if ((usr.contents.Find(src) || (in_range(src,usr) && istype(src.loc, /turf))))
usr.machine = src
if (href_list["spell_nova"])
if (src.uses >= 1)
src.uses -= 1
src.temp = "This jam will cause an eruption of explosive basketballs from your location."
usr.verbs += /proc/bball_nova
if (href_list["spell_showboat"])
if (src.uses >= 1)
src.uses -= 1
usr.verbs += /proc/showboat_slam
src.temp = "Leap up high above your target and slam them for massive damage."
if (href_list["spell_holy"])
if (src.uses >= 1)
src.uses -= 1
usr.verbs += /proc/holy_jam
src.temp = "A powerful and sacred jam that blinds surrounding enemies."
if (href_list["spell_blink"])
if (src.uses >= 1)
src.uses -= 1
usr.verbs += /proc/blitz_slam
src.temp = "This slam will allow you to teleport randomly at a short distance."
if (href_list["spell_revengeclown"])
if (src.uses >= 1)
src.uses -= 1
usr.verbs += /proc/clown_jam
src.temp = "This unspoken jam bamboozles your target to the extent that they will become an obese, idiotic, horrible, and useless clown."
if (href_list["spell_spin"])
usr.verbs += /proc/spin
src.temp = "This spell lets you do a 360 spin, knocking down any fools tailing you."
/*
if (href_list["spell_summongolem"])
if (src.uses >= 1)
src.uses -= 1
usr.verbs += /proc/summongolem_bball
src.temp = "This zauber allows you to summon a golem.. made of basketballs."
*/
else if (href_list["lock"] && src.origradio)
// presto chango, a regular radio again! (reset the freq too...)
usr.machine = null
usr << browse(null, "window=radio")
var/obj/item/device/radio/T = src.origradio
var/obj/item/bball_uplink/R = src
R.set_loc(T)
T.set_loc(usr)
// R.layer = initial(R.layer)
R.layer = 0
usr.u_equip(R)
usr.put_in_hand_or_drop(T)
T.set_frequency(initial(T.frequency))
T.attack_self(usr)
return
else if (href_list["selfdestruct"])
src.temp = "<A href='byond://?src=\ref[src];selfdestruct2=1'>Self-Destruct</A>"
else if (href_list["selfdestruct2"])
src.selfdestruct = 1
spawn (100)
explode()
return
else
if (href_list["temp"])
src.temp = null
if (istype(src.loc, /mob))
attack_self(src.loc)
else
for(var/mob/M in viewers(1, src))
if (M.client)
src.attack_self(M)
return
/mob/proc/bball_spellpower()
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
var/magcount = 0
if (istype(H.w_uniform, /obj/item/clothing/under/jersey))
magcount += 1
for (var/obj/item/basketball/B in usr.contents)
magcount += 2
if (magcount >= 3)
return 1
return 0
+19
View File
@@ -0,0 +1,19 @@
var/church_name = null
/proc/church_name()
if (church_name)
return church_name
var/name = ""
name += pick("Holy", "United", "First", "Second", "Last", "Primary", "Secondary", "Tertiary", "Unholy", "Exiled", "Exalted", "Free")
if (prob(20))
name += " Space"
else if (prob(10))
name += " "
name += pick("Galactic", "Universal", "Dimensional")
name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses", "Followers", "Ascendants", "Society", "Fellowship", "Order", "Community", "School", "Assembly", "Assemblies", "Association", "Foundation", "Gate", "Trust", "Temple", "Mission", "Union", "Brotherhood", "Sisterhood", "Fraternity")
name += " of [religion_name()]"
return name
+65
View File
@@ -0,0 +1,65 @@
/proc/command_alert(var/text, var/title = "")
boutput(world, "<h1 class='alert'>[command_name()] Update</h1>")
if (title && length(title) > 0)
boutput(world, "<h2 class='alert'>[sanitize(title)]</h2>")
boutput(world, "<span class='alert'>[sanitize(text)]</span>")
boutput(world, "<br>")
/proc/command_announcement(var/text, var/title) //Slightly less conspicuous, but requires a title.
if(!title || !text) return
boutput(world, "<h2 class='alert'>[sanitize(title)]</h2>")
boutput(world, "<span class='alert'>[sanitize(text)]</span>")
boutput(world, "<br>")
/proc/advanced_command_alert(var/text, var/title="")
if(!text) return 0
var/list/mob/mob_list = list()
for(var/mob/M in world)
if(M.client)
mob_list+=M
var/mob/rand_mob_single = pick(mob_list) //A single randomly selected player
for(var/mob/M in mob_list)
spawn(0)
if(M.client)
var/mob/rand_mob_mult = pick(mob_list) //A randomly selected player that's different to each viewer
var/atom/A = get_turf(M.loc)
if(A) A = A.loc
if(title != "")
title = dd_replacetext(title, "%name%", M.real_name)
title = dd_replacetext(title, "%key%", M.key)
title = dd_replacetext(title, "%job%", M.job ? M.job : "space hobo")
title = dd_replacetext(title, "%area_name%", A ? A.name : "some unknown place")
title = dd_replacetext(title, "%srand_name%", rand_mob_single.name)
title = dd_replacetext(title, "%srand_job%", rand_mob_single.job ? rand_mob_single.job : "space hobo" )
title = dd_replacetext(title, "%mrand_name%", rand_mob_mult.name)
title = dd_replacetext(title, "%mrand_job%", rand_mob_mult.job)
title = sanitize(title)
text = dd_replacetext(text, "%name%", M.real_name)
text = dd_replacetext(text, "%key%", M.key)
text = dd_replacetext(text, "%job%", M.job ? M.job : "space hobo")
text = dd_replacetext(text, "%area_name%", A ? A.name : "some unknown place")
text = dd_replacetext(text, "%srand_name%", rand_mob_single.name)
text = dd_replacetext(text, "%srand_job%", rand_mob_single.job ? rand_mob_single.job : "space hobo" )
text = dd_replacetext(text, "%mrand_name%", rand_mob_mult.name)
text = dd_replacetext(text, "%mrand_job%", rand_mob_mult.job)
text = sanitize(text)
boutput(M, "<h1 class='alert'>[command_name()] Update</h1>")
if(title != "") boutput(M, "<h2 class='alert'>[title]</h2>")
boutput(M, "<span class='alert'>[text]</span><br>")
return 1
+26
View File
@@ -0,0 +1,26 @@
var/command_name = null
/proc/command_name()
if (command_name)
return command_name
var/name = ""
if (prob(10))
name += pick("Super", "Ultra", "Mega", "Supreme", "Grand", "Secret")
name += " "
// Prefix
if (name)
name += pick("", "Central", "System", "Galactic", "Space")
else
name += pick("Central", "System", "Galactic", "Space")
if (name)
name += " "
// Suffix
name += pick("Federation", "Command", "Alliance", "Unity", "Empire", "Confederation", "Protectorate", "Commonwealth", "Imperium", "Republic", "Corporate", "Authority", "Council", "System")
//name += " "
command_name = name
return name
+204
View File
@@ -0,0 +1,204 @@
/datum/compid_info
var/compid = ""
var/last_seen = 0 //The time this was last spotted
var/last_ckey = "" //The latest key associated with this ID
var/times_seen = 0
proc/initialize_compid_savefile()
if(!compid_file)
compid_file = new /savefile("data/compid_file.sav")
return compid_file
proc/load_compids(var/ckey)
var/savefile/SF = initialize_compid_savefile()
var/path = "/[copytext(ckey, 1, 2)]/[ckey]"
var/list/datum/compid_info/cid_list = list()
SF.cd = path
while (!SF.eof)
var/datum/compid_info/CI
SF >> CI
cid_list += CI
return cid_list
proc/save_compids(var/ckey, var/list/datum/compid_info/cid_list)
var/savefile/SF = initialize_compid_savefile()
var/path = "/[copytext(ckey, 1, 2)]/[ckey]"
SF.cd = path
SF.eof = -1
for(var/datum/compid_info/CI in cid_list)
SF << CI
proc/check_compid_list(var/client/C)
C.compid_info_list = load_compids(C.ckey)
var/append_CID = 1
for(var/datum/compid_info/CI in C.compid_info_list)
if(CI.compid == C.computer_id) //Seen this computer ID before
append_CID = 0
/* This will never happen what the fuck is wrong with me?
if (CI.last_ckey <> C.ckey) //Computer-sharing? Sneaky jerk? Who knows.
message_admins("[C.key] (ID:[C.computer_id]) shares a computerID with [CI.last_ckey]")
logTheThing("admin", C, null, "[C.key] (ID:[C.computer_id]) shares a computerID with [CI.last_ckey]")
CI.last_ckey = C.ckey
*/
CI.last_seen = world.realtime
CI.times_seen++
break
if(append_CID) //Did not find an entry
var/datum/compid_info/CI = new
CI.compid = C.computer_id
CI.last_seen = world.realtime
CI.last_ckey = C.ckey
CI.times_seen = 1
//Has this computerid changed recently and does it have a habit of changing?
if(C.compid_info_list.len >= 2) //Do they have more than 2 CID's on file? Weird
var/today = time2text(world.realtime, "YYYYMMDD")
var/current_hour = time2text(world.realtime, "hh")
var/current_minute = time2text(world.realtime, "mm")
var/hits = 0
for(var/datum/compid_info/CII in C.compid_info_list)
if(today == time2text(CII.last_seen, "YYYYMMDD"))
var/last_seen_hour = time2text(CII.last_seen, "hh")
var/last_seen_minute = time2text(CII.last_seen, "nn")
var/time_diff = ( text2num(current_hour) * 60 + text2num(current_minute) ) - ( text2num(last_seen_hour) * 60 + text2num(last_seen_minute) )
if(time_diff <= 180 && CI.times_seen < 30)
//If the ID changed within 3 hours and the ID hasn't been seen several times (unlikely to happen with automatically generated IDs
hits++
if(hits)
var/ircmsg[] = new()
ircmsg["key"] = C.key
ircmsg["name"] = C.mob.real_name
var/msg = "'s compID changed [hits] time[hits>1 ? "s" : null] within the last 180 minutes - [C.compid_info_list.len + 1] IDs on file."
if(hits >= 2) //This person used 3 computers within as many hours
if(!cid_test) cid_test = list()
if(!cid_tested) cid_tested = list()
if(!(C.ckey in cid_test) && !(C.ckey in cid_tested)) //They aren't yet scheduled for a test or they have been tested
cid_test[C.ckey] = C.computer_id
cid_tested += C.ckey
msg += " Executing automatic test."
spawn(10)
del(C) //RIP
message_admins("[key_name(C)][msg]")
logTheThing("admin", C, null, msg)
else
message_admins("[key_name(C)][msg]")
logTheThing("admin", C, null, "[key_name(C)][msg]")
ircmsg["msg"] = "(IP: [C.address]) [msg]"
ircbot.export("admin", ircmsg)
//Done with the analysis
C.compid_info_list += CI
/* Pointless alert
if(C.compid_info_list.len > 10) //Holy evasion, Batman!
message_admins("[key_name(C)] (ID:[C.computer_id]) has been seen having [C.compid_info_list.len] IDs!")
logTheThing("admin", C, null, "(ID:[C.computer_id]) has been seen having [C.compid_info_list.len] IDs!")
*/
save_compids(C.ckey, C.compid_info_list)
var/global/list/cid_test = list()
var/global/list/cid_tested = list()
proc/do_computerid_test(var/client/C)
var/cid = cid_test[C.ckey]
if(!cid) return //They were not scheduled for testing
var/is_fucker = cid != C.computer_id //IT CHANGED!!!
cid_test -= C.ckey
var/msg = " [is_fucker ? "failed" : "passed"] the automatic cid dll test."
var/ircmsg[] = new()
ircmsg["key"] = C.key
ircmsg["name"] = C.mob.real_name
ircmsg["msg"] = " [msg]"
ircbot.export("admin", ircmsg)
message_admins("[key_name(C)][msg]")
logTheThing("admin", C, null, msg)
if(is_fucker)
//message_admins("[key_name(C)] was automatically banned for using the CID DLL.")
var/banData[] = new()
banData["ckey"] = C.ckey
banData["compID"] = C.computer_id
banData["akey"] = "Auto Banner"
banData["ip"] = C.address
banData["reason"] = "Using a modified dreamseeker client."
banData["mins"] = 0
addBan(1, banData)
proc/view_client_compid_list(mob/user, var/C)
if(!user.client || !user.client.holder)
return
var/list/datum/compid_info/cid_list = null
var/ckey = ""
if(istype(C, /client))
var/client/CL = C
cid_list = CL.compid_info_list
ckey = CL.ckey
else if(istext(C))
cid_list = load_compids(C)
ckey = C
if(!cid_list.len)
user.show_text("Could not find the ckey [C]!", "red")
return
else
message_coders("[key_name(usr)] gave the compid thing [C]; that's neither text nor a client. What a jerk.")
return
var/dat = {"<html>
<head>
<title>Computer ID viewer</title>
<style>
table {
border: 1px solid black;
border-collapse: collapse;
padding: 2px;
}
tr {
border: 1px solid black;
padding: 2px
}
th {
border: 1px solid black;
padding: 2px
}
td {
border: 1px solid black;
padding: 2px
}
</style>
</head>
<body>
<h3>CompID list for [ckey]</h2>
<hr>
This jerk: [key_name(whom=C, admins=0)]
<table>
<tr>
<th>Comp ID</th><th>Last Ckey</th><th>Last Seen</th><th>Times Seen</th>
</tr>"}
for (var/datum/compid_info/CI in cid_list)
dat += "<tr><td>[CI.compid]</td><td>[CI.last_ckey]</td><td>[time2text(CI.last_seen, "YYYY-MM-DD hh:mm")]</td><td>[CI.times_seen]</td></tr>"
dat += {" </table>
</body>
</html>"}
user << browse(dat, "window=compid_info_view")
+8
View File
@@ -0,0 +1,8 @@
var/currency_name = null
/proc/currency_name()
if (currency_name) return currency_name
else
var/name = ""
if (prob(20)) name += " Space "
name += pick("Credits", "Dollars", "Bucks", "Francs", "Deutschmarks", "Roubles", "Peso", "Denarii")
return name
+124
View File
@@ -0,0 +1,124 @@
proc/explosion(atom/source, turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
var/power = max(devastation_range+heavy_impact_range+0.25, 1)
//boutput(world, "<span style=\"color:blue\">[devastation_range] [heavy_impact_range] [power]</span>")
explosion_new(source, epicenter, (power*1.5)**2, max(light_impact_range/(power*1.5), 1))
//boutput(world, "<span style=\"color:red\">[power]</span>")
proc/explosion_new(atom/source, turf/epicenter, power, brisance=1)
var/distant_sound = 'sound/effects/explosionfar.ogg'
if (!istype(epicenter, /turf))
epicenter = get_turf(epicenter)
if (!epicenter)
return
if(power > 10)
if(!istype(get_area(epicenter), /area/colosseum)) //I do not give a flying FUCK about what goes on in the colosseum. =I
// Cannot read null.name
var/logmsg = "Explosion with power [power] (Source: [source ? "[source.name]" : "*unknown*"]) at [log_loc(epicenter)]. Source last touched by: [source ? "[source.fingerprintslast]" : "*null*"]"
message_admins(logmsg)
logTheThing("bombing", null, null, logmsg)
logTheThing("diary", null, null, logmsg, "combat")
if(big_explosions.len)
distant_sound = pick(big_explosions)
for(var/client/C)
if(C.mob && (C.mob.z == epicenter.z))
if(power > 15 && C.mob.z == 1 && epicenter.z == 1)
shake_camera(C.mob, 8, 3) // remove if this is too laggy
C << sound(distant_sound)
playsound(epicenter.loc, "explosion", 100, 1, round(power, 1) )
if(power > 10)
var/datum/effects/system/explosion/E = new/datum/effects/system/explosion()
E.set_up(epicenter)
E.start()
var/radius = round(sqrt(power), 1) * brisance
var/last_touched
if (source) // Cannot read null.fingerprintslast
last_touched = source.fingerprintslast
else
last_touched = "*null*"
spawn(0)
var/list/nodes = list()
var/list/open = list(epicenter)
nodes[epicenter] = radius
while (open.len)
var/turf/T = open[1]
open.Cut(1, 2)
var/value = nodes[T] - 1 - T.explosion_resistance
var/value2 = nodes[T] - 1.4 - T.explosion_resistance
for (var/atom/A in T.contents)
if (A.density/* && !A.CanPass(null, target)*/) // nothing actually used the CanPass check
value -= A.explosion_resistance
value2 -= A.explosion_resistance
if (value < 0)
continue
for (var/dir in alldirs)
var/turf/target = get_step(T, dir)
if (!target) continue // woo edge of map
var/new_value = dir & (dir-1) ? value2 : value
if ((nodes[target] && nodes[target] >= new_value))
continue
nodes[target] = new_value
open |= target
defer_powernet_rebuild = 1
defer_camnet_rebuild = 1
defer_main_loops = 1
RL_Suspend()
radius += 1 // avoid a division by zero
for (var/turf/T in nodes) // inverse square law (IMPORTANT) and pre-stun
var/p = power / ((radius-nodes[T])**2)
nodes[T] = p
p = min(p, 10)
for(var/mob/living/carbon/C in T)
if (C.stat != 2 && C.client)
shake_camera(C, 3 * p, p)
C.stunned += p
C.stuttering += p
C.lying = 1
C.set_clothing_icon_dirty()
var/needrebuild = 0
for (var/turf/T in nodes)
var/p = nodes[T]
//boutput(world, "P1 [p]")
if (p >= 6)
for (var/atom/A as obj|mob in T)
A.ex_act(1, last_touched)
if (istype(A, /obj/cable)) // these two are hacky, newcables should relieve the need for this
needrebuild = 1
else if (p >= 3)
for (var/atom/A as obj|mob in T)
A.ex_act(2, last_touched)
if (istype(A, /obj/cable))
needrebuild = 1
else
for (var/atom/A as obj|mob in T)
A.ex_act(3, last_touched)
sleep(-1)
for (var/turf/T in nodes) // AFTER that ordeal (which may sleep quite a few times), fuck the turfs up all at once to prevent lag
var/p = nodes[T]
//boutput(world, "P2 [p]")
if (p >= 6)
T.ex_act(1, last_touched)
else if (p >= 3)
T.ex_act(2, last_touched)
else
T.ex_act(3, last_touched)
defer_powernet_rebuild = 0
defer_camnet_rebuild = 0
defer_main_loops = 0
RL_Resume()
if (needrebuild)
makepowernets()
rebuild_camera_network()
+28
View File
@@ -0,0 +1,28 @@
///// FOR EXPORTING DATA TO A SERVER /////
var/global/stat_server = ""
var/global/server_token = ""
// Called in world.dm at new()
/proc/round_start_data()
set background = 1
var/message[] = new()
message["token"] = md5(server_token)
message["round_name"] = url_encode(station_name())
message["round_server"] = "[(world.port % 1000) / 100]"
message["round_status"] = "start"
world.Export("[stat_server][list2params(message)]")
// Called in gameticker.dm at the end of the round.
/proc/round_end_data(var/reason)
set background = 1
var/message[] = new()
message["token"] = md5(server_token)
message["round_server"] = "[(world.port % 1000) / 100]"
message["round_status"] = "end"
message["end_reason"] = reason
message["game_type"] = ticker && ticker.mode ? ticker.mode.name : "pre"
world.Export("[stat_server][list2params(message)]")
+648
View File
@@ -0,0 +1,648 @@
/*
replacetext(haystack, needle, replace)
Replaces all occurrences of needle in haystack (case-insensitive)
with replace value.
replaceText(haystack, needle, replace)
Replaces all occurrences of needle in haystack (case-sensitive)
with replace value.
*/
var/list/vowels_lower = list("a","e","i","o","u")
var/list/vowels_upper = list("A","E","I","O","U")
var/list/consonants_lower = list("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z")
var/list/consonants_upper = list("B","C","D","F","G","H","J","K","L","M","N","P","Q","R","S","T","V","W","X","Y","Z")
var/list/symbols = list("!","?",".",",","'","\"","@","#","$","%","^","&","*","+","-","=","_","(",")","<",">","\[","\]",":",";")
var/list/numbers = list("0","1","2","3","4","5","6","7","8","9")
var/list/stinkDescs = list("nasty","unpleasant","foul","horrible","rotten","unholy",
"repulsive","noxious","putrid","gross","unsavory","fetid","pungent","vulgar")
var/list/stinkTypes = list("smell","stink","odor","reek","stench","miasma")
var/list/stinkExclamations = list("Ugh","Good lord","Good grief","Christ","Fuck","Eww")
var/list/stinkThings = list("garbage can","trash heap","cesspool","toilet","pile of poo",
"butt","skunk","outhouse","corpse","fart","devil")
var/list/stinkVerbs = list("took a shit","died","farted","threw up","wiped its ass")
var/list/stinkThingies = list("ass","taint","armpit","excretions","leftovers")
/proc/stinkString()
// i am five - ISN
switch (rand(1,4))
if (1)
return "[pick(stinkExclamations)], there's a \a [pick(stinkDescs)] [pick(stinkTypes)] in here..."
if (2)
return "[pick(stinkExclamations)], there's a \a [pick(stinkDescs)] [pick(stinkTypes)] in here..."
if (3)
return "[pick(stinkExclamations)], it smells like \a [pick(stinkThings)] [pick(stinkVerbs)] in here!"
else
return "[pick(stinkExclamations)], it smells like \a [pick(stinkThings)]'s [pick(stinkThingies)] in here!"
/proc/replacetext(haystack, needle, replace)
var
pos = findtext(haystack, needle)
needleLen = length(needle)
replaceLen = length(replace)
while(pos)
haystack = copytext(haystack, 1, pos) + replace + \
copytext(haystack, pos+needleLen)
pos = findtext(haystack, needle, pos+replaceLen)
return haystack
/proc/replaceText(haystack, needle, replace)
var
pos = findtextEx(haystack, needle)
needleLen = length(needle)
replaceLen = length(replace)
while(pos)
haystack = copytext(haystack, 1, pos) + replace + \
copytext(haystack, pos+needleLen)
pos = findtextEx(haystack, needle, pos+replaceLen)
return haystack
//For fuck's sake.
/*
/proc/bubblesort(list/L)
var i, j
for(i=L.len, i>0, i--)
for(j=1, j<i, j++)
if(L[j] > L[j+1])
L.Swap(j, j+1)
return L
*/
/proc/get_local_apc(O)
var/turf/T = get_turf(O)
if (!T)
return null
var/area/A = T.loc
if (A.type == /area)
// dont search space for an apc
return null
for (var/obj/machinery/power/apc/APC in A.contents)
if (!(APC.stat & BROKEN))
return APC
// Lots and lots of APCs use area strings to make the blowout random event possible.
for (var/obj/machinery/power/apc/APC2 in machines)
var/area/A2 = null
if (!isnull(APC2.areastring))
A2 = get_area_name(APC2.areastring)
if (!isnull(A2) && istype(A2) && A == A2 && !(APC2.stat & BROKEN))
return APC2
return null
/proc/get_area(O)
var/location = O
var/i
for(i=1, i<=20, i++)
if(location && !isarea(location))
location = location:loc
else
return location
return 0
/proc/get_area_name(N) //get area by it's name
for(var/area/A in world)
if(A.name == N)
return A
return 0
/proc/get_area_by_type(var/type_path)
if (!ispath(type_path))
return null
for (var/area/A in world)
if (A.type == type_path)
return A
return null
/proc/in_range(atom/source, atom/user)
if(bounds_dist(source, user) == 0 || get_dist(source, user) <= 1) // fucking byond
return 1
else if (source in bible_contents && locate(/obj/item/storage/bible) in range(1, user)) // whoever added the global bibles, fuck you
return 1
else
if (iscarbon(user))
var/mob/living/carbon/C = user
if (C.bioHolder.HasEffect("telekinesis") && get_dist(source, user) <= 7) //You can only reach stuff within your screen.
var/X = source:x
var/Y = source:y
var/Z = source:z
if (isrestrictedz(Z) || isrestrictedz(user:z))
boutput(user, "<span style=\"color:red\">Your telekinetic powers don't seem to work here.</span>")
return 0
spawn(0)
//I really shouldnt put this here but i dont have a better idea
var/obj/overlay/O = new /obj/overlay ( locate(X,Y,Z) )
O.name = "sparkles"
O.anchored = 1
O.density = 0
O.layer = FLY_LAYER
O.dir = pick(cardinal)
O.icon = 'icons/effects/effects.dmi'
O.icon_state = "nothing"
flick("empdisable",O)
spawn(5)
qdel(O)
return 1
return 0 //not in range and not telekinetic
var/obj/item/dummy/click_dummy = new
/proc/test_click(turf/from, turf/target)
for (var/atom/A in from)
if (A.flags & ON_BORDER)
if (!A.CheckExit(click_dummy, target))
return 0
for (var/atom/A in target)
if (A.flags & ON_BORDER)
if (!A.CanPass(click_dummy, from, 1, 0))
return 0
return 1
/proc/can_reach(mob/user, atom/target)
if (target in bible_contents)
target = locate(/obj/item/storage/bible) in range(1, user) // fuck bibles
if (!target)
return 0
var/turf/UT = get_turf(user)
var/turf/TT = get_turf(target)
if (TT)
var/obj/cover/C = locate() in TT
if (C && target != C)
return 0
if (UT && TT != UT)
var/obj/cover/C = locate() in UT
if (C && target != C)
return 0
if (isturf(user.loc))
if (!in_range(target, user))
return 0
var/T1 = get_turf(user)
var/T2 = get_turf(target)
if (T1 == T2)
return 1
else
if (!click_dummy)
click_dummy = new
var/dir = get_dir(T1, T2)
if (dir & (dir-1))
var/dir1, dir2
switch (dir)
if (NORTHEAST)
dir1 = NORTH
dir2 = EAST
if (NORTHWEST)
dir1 = NORTH
dir2 = WEST
if (SOUTHEAST)
dir1 = SOUTH
dir2 = EAST
if (SOUTHWEST)
dir1 = SOUTH
dir2 = WEST
var/D1 = get_step(T1, dir1)
var/D2 = get_step(T1, dir2)
if (test_click(T1, D1))
if ((target.flags & ON_BORDER) || test_click(D1, T2))
return 1
if (test_click(T1, D2))
if ((target.flags & ON_BORDER) || test_click(D2, T2))
return 1
else
return (target.flags & ON_BORDER) || test_click(T1, T2)
else if (isobj(target) || ismob(target))
var/atom/L = target.loc
while (L && !isturf(L))
if (L == user)
return 1
L = L.loc
return 0
/proc/AutoUpdateAI(obj/subject)
if (subject!=null)
for(var/mob/living/silicon/ai/M in mobs)
if ((M.client && M.machine == subject))
subject.attack_ai(M)
/proc/get_viewing_AIs(center = null, distance = world.view)
. = list()
for (var/mob/living/silicon/ai/theAI in mobs)
if (istype(theAI.current) && (theAI.current in view(center, distance)) )
. += theAI
//Kinda sorta like viewers but includes observers. In theory.
/proc/observersviewers(var/Dist=world.view, var/Center=usr)
var/list/viewMobs = viewers(Dist, Center)
for(var/mob/dead/target_observer/M in observers)
if(!M.client) continue
if(M.target in view(Dist, Center) || M.target == Center)
viewMobs += M
return viewMobs
/proc/AIviewers(Depth=world.view,Center=usr)
if (istype(Depth, /atom))
var/newDepth = isnum(Center) ? Center : world.view
Center = Depth
Depth = newDepth
return viewers(Depth, Center) + get_viewing_AIs(Center, Depth)
//A unique network ID for devices that could use one
/proc/format_net_id(var/refstring)
if(!refstring)
return
. = copytext(refstring,4,(length(refstring)))
. = add_zero(., 8)
//A little wrapper around format_net_id to account for non-null tag values
/proc/generate_net_id(var/atom/the_atom)
if(!the_atom) return
var/tag_holder = the_atom.tag
the_atom.tag = null //So we generate from internal ref id
. = format_net_id("\ref[the_atom]")
the_atom.tag = tag_holder
/proc/can_act(var/mob/M, var/include_cuffs = 1)
if(include_cuffs) if(M.handcuffed) return 0
if(M.stunned) return 0
if(M.weakened) return 0
if(M.paralysis) return 0
if(M.stat) return 0
return 1
#define CLUWNE_NOISE_DELAY 50
/proc/process_accents(var/mob/living/carbon/human/H, var/message)
if (!H || !istext(message))
return
if (H.bioHolder)
var/datum/bioEffect/speech/S = null
for(var/X in H.bioHolder.effects)
S = H.bioHolder.GetEffect(X)
if (istype(S,/datum/bioEffect/speech/))
message = S.OnSpeak(message)
if (iscluwne(H))
message = honk(message)
if (world.time >= (H.last_cluwne_noise + CLUWNE_NOISE_DELAY))
playsound(get_turf(H), pick("sound/voice/cluwnelaugh1.ogg","sound/voice/cluwnelaugh2.ogg","sound/voice/cluwnelaugh3.ogg"), 70, 0, 0, H.get_age_pitch())
H.last_cluwne_noise = world.time
if ((H.reagents && H.reagents.get_reagent_amount("ethanol") > 30 && H.stat != 2) || H.traitHolder.hasTrait("alcoholic"))
if((H.reagents.get_reagent_amount("ethanol") > 125 && prob(20)))
message = say_superdrunk(message)
else
message = say_drunk(message)
var/datum/ailment_data/disease/berserker = H.find_ailment_by_type(/datum/ailment/disease/berserker/)
if (istype(berserker,/datum/ailment_data/disease/) && berserker.stage > 1)
if (prob(10))
message = say_furious(message)
message = dd_replaceText(message, ".", "!")
message = dd_replaceText(message, ",", "!")
message = dd_replaceText(message, "?", "!")
message = uppertext(message)
var/addexc = rand(2,6)
while (addexc > 0)
message += "!"
--addexc
if(H.bioHolder && H.bioHolder.genetic_stability < 50)
if (prob(40))
message = say_gurgle(message)
if(H.mutantrace && H.stat != 2)
message = H.mutantrace.say_filter(message)
#ifdef CANADADAY
if (prob(30)) message = dd_replaceText(message, "?", " Eh?")
#endif
return message
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
var/turf/current = get_turf(source)
var/turf/target_turf = get_turf(target)
var/steps = 0
while(current != target_turf)
if(steps > length) return 0
if(!current) return 0
if(current.opacity) return 0
for(var/atom/A in current)
if(A.opacity) return 0
current = get_step_towards(current, target_turf)
steps++
return 1
/mob/proc/get_equipped_items()
. = list()
if(src.back) . += src.back
if(src.ears) . += src.ears
if(src.wear_mask) . += src.wear_mask
if(src.l_hand) . += src.l_hand
if(src.r_hand) . += src.r_hand
/proc/get_step_towards2(var/atom/ref , var/atom/trg)
var/base_dir = get_dir(ref, get_step_towards(ref,trg))
var/turf/temp = get_step_towards(ref,trg)
if(is_blocked_turf(temp))
var/dir_alt1 = turn(base_dir, 90)
var/dir_alt2 = turn(base_dir, -90)
var/turf/turf_last1 = temp
var/turf/turf_last2 = temp
var/free_tile = null
var/breakpoint = 0
while(!free_tile && breakpoint < 10)
if(!is_blocked_turf(turf_last1))
free_tile = turf_last1
break
if(!is_blocked_turf(turf_last2))
free_tile = turf_last2
break
turf_last1 = get_step(turf_last1,dir_alt1)
turf_last2 = get_step(turf_last2,dir_alt2)
breakpoint++
if(!free_tile) return get_step(ref, base_dir)
else return get_step_towards(ref,free_tile)
else return get_step(ref, base_dir)
/proc/get_areas(var/areatype)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
. = new/list()
for(var/area/R in world)
if(istype(R, areatype))
. += R
/proc/get_area_turfs(var/areatype, var/floors_only)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
. = new/list()
var/list/areas = get_areas(areatype)
for(var/area/R in areas)
for(var/turf/T in R)
if(floors_only && is_blocked_turf(T))
continue
. += T
/proc/get_area_all_atoms(var/areatype)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
. = new/list()
var/list/areas = get_areas(areatype)
for(var/area/R in areas)
for(var/atom/A in R)
. += A
/datum/coords //Simple datum for storing coordinates.
var/x_pos = null
var/y_pos = null
var/z_pos = null
/datum/color //Simple datum for RGBA colours
// used as an alternative to rgb() proc
// for ease of access to components
var/r = null // all stored as 0-255
var/g = null
var/b = null
var/a = null
New(_r,_g,_b,_a=255)
r = _r
g = _g
b = _b
a = _a
// return in #RRGGBB hex form
proc/to_rgb()
return rgb(r,g,b)
// return in #RRGGBBAA hex form
proc/to_rgba()
return rgb(r,g,b,a)
/area/proc/move_contents_to(var/area/A, var/turftoleave=null)
//Takes: Area. Optional: turf type to leave behind.
//Returns: Nothing.
//Notes: Attempts to move the contents of one area to another area.
// Movement based on lower left corner. Tiles that do not fit
// into the new area will not be moved.
var/testmove = 0
// if(prob(5)) testmove = 1
if(!A || !src) return 0
defer_main_loops = 1
spawn(10)
defer_main_loops = 0
var/list/turfs_src = get_area_turfs(src.type)
var/list/turfs_trg = get_area_turfs(A.type)
var/src_min_x = 0
var/src_min_y = 0
for (var/turf/T in turfs_src)
if(T.x < src_min_x || !src_min_x) src_min_x = T.x
if(T.y < src_min_y || !src_min_y) src_min_y = T.y
DEBUG("src_min_x = [src_min_x], src_min_y = [src_min_y]")
var/trg_min_x = 0
var/trg_min_y = 0
for (var/turf/T in turfs_trg)
if(T.x < trg_min_x || !trg_min_x) trg_min_x = T.x
if(T.y < trg_min_y || !trg_min_y) trg_min_y = T.y
DEBUG("trg_min_x = [src_min_x], trg_min_y = [src_min_y]")
var/list/refined_src = new/list()
for(var/turf/T in turfs_src)
refined_src += T
refined_src[T] = new/datum/coords
var/datum/coords/C = refined_src[T]
C.x_pos = (T.x - src_min_x)
C.y_pos = (T.y - src_min_y)
var/list/refined_trg = new/list()
for(var/turf/T in turfs_trg)
refined_trg += T
refined_trg[T] = new/datum/coords
var/datum/coords/C = refined_trg[T]
C.x_pos = (T.x - trg_min_x)
C.y_pos = (T.y - trg_min_y)
var/list/fromupdate = new/list()
var/list/toupdate = new/list()
moving:
for (var/turf/T in refined_src)
var/datum/coords/C_src = refined_src[T]
for (var/turf/B in refined_trg)
var/datum/coords/C_trg = refined_trg[B]
if(C_src.x_pos == C_trg.x_pos && C_src.y_pos == C_trg.y_pos)
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/turf/X
if(testmove) X = new T.type(get_step(B,pick(cardinal))) //remove this
else X = new T.type (B)
X.dir = old_dir1
X.icon_state = old_icon_state1
for(var/obj/O in T)
if (!istype(O, /obj) || istype(O, /obj/forcefield)) continue
O.set_loc(X)
for(var/mob/M in T)
DEBUG("Moving mob [M] from [T] to [X].")
if(!istype(M,/mob)) continue
M.set_loc(X)
var/area/AR = X.loc
if(AR.RL_Lighting)
X.opacity = !X.opacity
X.RL_SetOpacity(!X.opacity)
toupdate += X
if(turftoleave)
var/turf/ttl = new turftoleave(T)
var/area/AR2 = ttl.loc
if(AR2.RL_Lighting)
ttl.opacity = !ttl.opacity
ttl.RL_SetOpacity(!ttl.opacity)
fromupdate += ttl
else
T.ReplaceWithSpace()
refined_src -= T
refined_trg -= B
continue moving
var/list/doors = new/list()
if(toupdate.len)
for(var/turf/simulated/T1 in toupdate)
for(var/obj/machinery/door/D2 in T1)
doors += D2
if(T1.parent)
air_master.queue_update_group(T1.parent)
else
air_master.queue_update_tile(T1)
if(fromupdate.len)
for(var/turf/simulated/T2 in fromupdate)
for(var/obj/machinery/door/D2 in T2)
doors += D2
if(T2.parent)
air_master.queue_update_group(T2.parent)
else
air_master.queue_update_tile(T2)
for(var/obj/O in doors)
O:update_nearby_tiles(1)
// return description of how full a container is
proc/get_fullness(var/percent)
if(percent == 0)
return "empty"
if(percent < 2)
return "nearly empty"
if(percent < 24)
return "less than a quarter full"
if(percent < 26)
return "a quarter full"
if(percent < 37)
return "more than a quarter full"
if(percent < 49)
return "less than half full"
if(percent < 51)
return "half full"
if(percent < 62)
return "more than half full"
if(percent < 74)
return "less than three-quarters full"
if(percent < 76)
return "three-quarters full"
if(percent < 97)
return "more than three-quarters full"
if(percent < 99.5)
return "nearly full"
return "full"
// return description of transparency/opaqueness
proc/get_opaqueness(var/trans) // 0=transparent, 255=fully opaque
if(trans < 25)
return "clear"
if(trans < 60)
return "transparent"
if(trans< 150)
return "mostly transparent"
if(trans <200)
return "dense"
return "opaque"
proc/LoadSavefile(name)
. = new/savefile(name)
+195
View File
@@ -0,0 +1,195 @@
/proc/gibs(atom/location, var/list/diseases, var/list/ejectables, var/blood_DNA, var/blood_type)
// Added blood type and DNA for forensics (Convair880).
var/obj/decal/cleanable/blood/gibs/gib = null
var/list/gibs = new()
spawn(0)
playsound(location, "sound/effects/gib.ogg", 50, 1)
// NORTH
gib = new /obj/decal/cleanable/blood/gibs(location)
if (prob(30))
gib.icon_state = "gibup1"
gib.streak(list(NORTH, NORTHEAST, NORTHWEST))
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
// SOUTH
gib = new /obj/decal/cleanable/blood/gibs(location)
if (prob(30))
gib.icon_state = "gibdown1"
gib.streak(list(SOUTH, SOUTHEAST, SOUTHWEST))
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
// WEST
gib = new /obj/decal/cleanable/blood/gibs(location)
gib.streak(list(WEST, NORTHWEST, SOUTHWEST))
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
// EAST
gib = new /obj/decal/cleanable/blood/gibs(location)
gib.streak(list(EAST, NORTHEAST, SOUTHEAST))
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
// RANDOM BODY
gib = new /obj/decal/cleanable/blood/gibs/body(location)
gib.streak(alldirs)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
// CORE
gib = new /obj/decal/cleanable/blood/gibs/core(location)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gibs.Add(gib)
var/turf/Q = get_turf(location)
if (!Q)
return
if (ejectables && ejectables.len)
for (var/atom/movable/I in ejectables)
var/turf/target = null
var/tries = 0
while (!target)
if (tries == 4)
target = get_edge_target_turf(location, pick(alldirs))
break
var/tx = rand(-6, 6)
var/ty = rand(-6, 6)
if (tx == ty && tx == 0)
continue
target = locate(Q.x + tx, Q.y + ty, Q.z)
var/atom/movable/newobj = I.set_loc(location)
newobj.layer = initial(newobj.layer)
spawn
newobj.throw_at(target, 12, 3)
. = gibs
/proc/robogibs(atom/location, var/list/diseases)
var/obj/decal/cleanable/robot_debris/gib = null
var/list/gibs = new()
spawn(0)
playsound(location, "sound/effects/robogib.ogg", 50, 1)
// RUH ROH
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
s.set_up(2, 1, location)
s.start()
// NORTH
gib = new /obj/decal/cleanable/robot_debris(location)
if (prob(25))
gib.icon_state = "gibup1"
gib.streak(list(NORTH, NORTHEAST, NORTHWEST))
gibs.Add(gib)
// SOUTH
gib = new /obj/decal/cleanable/robot_debris(location)
if (prob(25))
gib.icon_state = "gibdown1"
gib.streak(list(SOUTH, SOUTHEAST, SOUTHWEST))
gibs.Add(gib)
// WEST
gib = new /obj/decal/cleanable/robot_debris(location)
gib.streak(list(WEST, NORTHWEST, SOUTHWEST))
gibs.Add(gib)
// EAST
gib = new /obj/decal/cleanable/robot_debris(location)
gib.streak(list(EAST, NORTHEAST, SOUTHEAST))
gibs.Add(gib)
// RANDOM
gib = new /obj/decal/cleanable/robot_debris(location)
gib.streak(alldirs)
gibs.Add(gib)
// RANDOM LIMBS
for (var/i = 0, i < pick(0, 1, 2), i++)
gib = new /obj/decal/cleanable/robot_debris/limb(location)
gib.streak(alldirs)
gibs.Add(gib)
.=gibs
/proc/partygibs(atom/location, var/list/diseases, var/blood_DNA, var/blood_type)
// Added blood type and DNA for forensics (Convair880).
var/list/party_colors = list(rgb(0,0,255),rgb(204,0,102),rgb(255,255,0),rgb(51,153,0))
var/obj/decal/cleanable/blood/gibs/gib = null
// NORTH
gib = new /obj/decal/cleanable/blood/gibs(location)
if (prob(30))
gib.icon_state = "gibup1"
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
gib.streak(list(NORTH, NORTHEAST, NORTHWEST))
// SOUTH
gib = new /obj/decal/cleanable/blood/gibs(location)
if (prob(30))
gib.icon_state = "gibdown1"
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
gib.streak(list(SOUTH, SOUTHEAST, SOUTHWEST))
// WEST
gib = new /obj/decal/cleanable/blood/gibs(location)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
gib.streak(list(WEST, NORTHWEST, SOUTHWEST))
// EAST
gib = new /obj/decal/cleanable/blood/gibs(location)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
gib.streak(list(EAST, NORTHEAST, SOUTHEAST))
// RANDOM BODY
gib = new /obj/decal/cleanable/blood/gibs/body(location)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
gib.streak(alldirs)
// RANDOM LIMBS
for (var/i = 0, i < pick(0, 1, 2), i++)
var/limb_type = pick(/obj/item/parts/human_parts/arm/left, /obj/item/parts/human_parts/arm/right, /obj/item/parts/human_parts/leg/left, /obj/item/parts/human_parts/leg/right)
gib = new limb_type(location)
gib.throw_at(get_edge_target_turf(location, pick(alldirs)), 4, 3)
gib.color = pick(party_colors)
// CORE
gib = new /obj/decal/cleanable/blood/gibs/core(location)
gib.diseases += diseases
gib.blood_DNA = blood_DNA
gib.blood_type = blood_type
gib.color = pick(party_colors)
File diff suppressed because it is too large Load Diff
+490
View File
@@ -0,0 +1,490 @@
/proc/SetupOccupationsList()
set background = 1
var/list/new_occupations = list()
for(var/occupation in occupations)
if (!(new_occupations.Find(occupation)))
new_occupations[occupation] = 1
else
new_occupations[occupation] += 1
occupations = new_occupations
return
/proc/FindOccupationCandidates(list/unassigned, job, level)
set background = 1
var/list/candidates = list()
for (var/mob/new_player/player in unassigned)
var/datum/job/J = find_job_in_controller_by_string(job)
if(checktraitor(player))
if ((ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution)) && J.cant_spawn_as_rev)
// Fixed AI, security etc spawning as rev heads. The special job picker doesn't care about that var yet,
// but I'm not gonna waste too much time tending to a basically abandoned game mode (Convair880).
continue
else if((ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/gang)) && (job != "Staff Assistant"))
continue
if (!J.allow_traitors && player.mind.special_role)
continue
if (J.requires_whitelist && !NT.Find(ckey(player.mind.key)))
continue
if (jobban_isbanned(player, job) || job in player.client.preferences.jobs_unwanted)
continue
if (level == 1 && player.client.preferences.job_favorite == job)
candidates += player
else if (level == 2 && job in player.client.preferences.jobs_med_priority)
candidates += player
else if (level == 3 && job in player.client.preferences.jobs_low_priority)
candidates += player
return candidates
/proc/PickOccupationCandidate(list/candidates)
if (candidates.len > 0)
// var/list/randomcandidates = shuffle(candidates) //Is there really any need to use shuffle() when it just uses pick internally anyway, and you throw away all but one result?
// candidates -= randomcandidates[1]
// return randomcandidates[1]
return pick(candidates)
//
return null
/proc/DivideOccupations()
set background = 1
var/list/unassigned = list()
for (var/mob/new_player/player in mobs)
if (player.client && player.ready && !player.mind.assigned_role)
unassigned += player
if (unassigned.len == 0)
return 0
// If the mode is construction, ignore all this shit and sort everyone into the construction worker job.
if (master_mode == "construction")
for (var/mob/new_player/player in unassigned)
player.mind.assigned_role = "Construction Worker"
return
var/list/pick1 = list()
var/list/pick2 = list()
var/list/pick3 = list()
// Stick all the available jobs into its own list so we can wiggle the fuck outta it
var/list/available_job_roles = list()
// Apart from ones in THIS list, which are jobs we want to assign before any others
var/list/high_priority_jobs = list()
// This list is for jobs like staff assistant which have no limits, or other special-case
// shit to hand out to people who didn't get one of the main limited slot jobs
var/list/low_priority_jobs = list()
for(var/datum/job/JOB in job_controls.staple_jobs)
// If it's hi-pri, add it to that list. Simple enough
if (JOB.high_priority_job)
high_priority_jobs.Add(JOB)
// If we've got a job with the low priority var set or no limit, chuck it in the
// low-pri list and move onto the next job - if we don't do this, the first time
// it hits a limitless job it'll get stuck on it and hand it out to everyone then
// boot the game up resulting in ~WEIRD SHIT~
else if (JOB.low_priority_job || JOB.limit < 0)
low_priority_jobs += JOB.name
continue
// otherwise it's a normal role so it goes in that list instead
else
available_job_roles.Add(JOB)
// Wiggle it like a pissy caterpillar
available_job_roles = shuffle(available_job_roles)
// Wiggle the players too so that priority isn't determined by key alphabetization
unassigned = shuffle(unassigned)
// First we deal with high-priority jobs like Captain or AI which generally will always
// be present on the station - we want these assigned first just to be sure
// Though we don't want to do this in sandbox mode where it won't matter anyway
if(master_mode != "sandbox")
for(var/datum/job/JOB in high_priority_jobs)
if (unassigned.len == 0) break
if (JOB.limit > 0 && JOB.assigned >= JOB.limit) continue
// get all possible candidates for it
pick1 = FindOccupationCandidates(unassigned,JOB.name,1)
pick2 = FindOccupationCandidates(unassigned,JOB.name,2)
pick3 = FindOccupationCandidates(unassigned,JOB.name,3)
// now assign them - i'm not hardcoding limits on these because i don't think any
// of us are quite stupid enough to edit the AI's limit to -1 preround and have a
// horrible multicore PC station round.. (i HOPE anyway)
for(var/mob/new_player/candidate in pick1)
if (JOB.assigned >= JOB.limit || unassigned.len == 0) break
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from High Priority Job Picker Lv1")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
for(var/mob/new_player/candidate in pick2)
if (JOB.assigned >= JOB.limit || unassigned.len == 0) break
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from High Priority Job Picker Lv2")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
for(var/mob/new_player/candidate in pick3)
if (JOB.assigned >= JOB.limit || unassigned.len == 0) break
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from High Priority Job Picker Lv3")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
else
// if we are in sandbox mode just roll the hi-pri jobs back into the regular list so
// people can still get them if they chose them
available_job_roles = available_job_roles | high_priority_jobs
// Next we go through each player and see if we can get them into their favorite jobs
// If we don't do this loop then the main loop below might get to a job they have in their
// medium or low priority lists first and give them that one rather than their favorite
for (var/mob/new_player/player in unassigned)
// If they don't have a favorite, skip em
if (derelict_mode) // stop freaking out at the weird jobs
continue
if (!player.client.preferences || player.client.preferences.job_favorite == null)
continue
// Now get the in-system job via the string
var/datum/job/JOB = find_job_in_controller_by_string(player.client.preferences.job_favorite)
// Do a few checks to make sure they're allowed to have this job
if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution))
if(checktraitor(player) && JOB.cant_spawn_as_rev)
// Fixed AI, security etc spawning as rev heads. The special job picker doesn't care about that var yet,
// but I'm not gonna waste too much time tending to a basically abandoned game mode (Convair880).
continue
if (!JOB || jobban_isbanned(player,JOB.name))
continue
if (JOB.requires_whitelist && !NT.Find(ckey(player.mind.key)))
continue
if (!JOB.allow_traitors && player.mind.special_role)
continue
// If there's an open job slot for it, give the player the job and remove them from
// the list of unassigned players, hey presto everyone's happy (except clarks probly)
if (JOB.limit < 0 || !(JOB.assigned >= JOB.limit))
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [player] took [JOB.name] from favorite selector")
player.mind.assigned_role = JOB.name
logTheThing("debug", player, null, "assigned job: [player.mind.assigned_role]")
unassigned -= player
JOB.assigned++
// Do this loop twice - once for med priority and once for low priority, because elsewise
// it was causing weird shit to happen where having something in low priority would
// sometimes cause you to get that instead of a higher prioritized job
for(var/datum/job/JOB in available_job_roles)
// If we've got everyone a job, then stop wasting cycles and get on with the show
if (unassigned.len == 0) break
// If there's no more slots for this job available, move onto the next one
if (JOB.limit > 0 && JOB.assigned >= JOB.limit) continue
// First, rebuild the lists of who wants to be this job
pick2 = FindOccupationCandidates(unassigned,JOB.name,2)
// Now loop through the candidates in order of priority, and elect them to the
// job position if possible - if at any point the job is filled, break the loops
for(var/mob/new_player/candidate in pick2)
if (JOB.assigned >= JOB.limit || unassigned.len == 0)
break
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from Level 2 Job Picker")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
// And then again for low priority
for(var/datum/job/JOB in available_job_roles)
if (unassigned.len == 0)
break
if (JOB.limit == 0)
continue
if (JOB.limit > 0 && JOB.assigned >= JOB.limit)
continue
pick3 = FindOccupationCandidates(unassigned,JOB.name,3)
for(var/mob/new_player/candidate in pick3)
if (JOB.assigned >= JOB.limit || unassigned.len == 0) break
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from Level 3 Job Picker")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
/* commenting this out because it's causing people to randomly become monkeys and shit and I guess it was set up before special jobs were enabled on default
// If there are any special jobs that have been made available pre-round, sort any
// remaining players into them
if (job_controls.allow_special_jobs)
for(var/datum/job/JOB in job_controls.special_jobs)
if (unassigned.len == 0)
break
if (JOB.limit == 0)
continue
if (JOB.limit > 0 && JOB.assigned >= JOB.limit)
continue
var/mob/new_player/candidate = pick(unassigned)
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [candidate] took [JOB.name] from special job picker")
candidate.mind.assigned_role = JOB.name
logTheThing("debug", candidate, null, "assigned job: [candidate.mind.assigned_role]")
unassigned -= candidate
JOB.assigned++
*/
// If there's anyone left without a job after this, lump them with a randomly
// picked low priority role and be done with it
if (!low_priority_jobs.len)
// we really need to fix this or it'll be some kinda weird inf loop shit
low_priority_jobs += "Staff Assistant"
for (var/mob/new_player/player in unassigned)
logTheThing("debug", null, null, "<b>I Said No/Jobs:</b> [player] given a low priority role")
player.mind.assigned_role = pick(low_priority_jobs)
logTheThing("debug", player, null, "assigned job: [player.mind.assigned_role]")
return 1
/mob/living/carbon/human/proc/Equip_Rank(rank, joined_late)
var/datum/job/JOB = find_job_in_controller_by_string(rank)
if (!JOB)
boutput(src, "<span style=\"color:red\"><b>Something went wrong setting up your rank and equipment! Report this to a coder.</b></span>")
return
//if(JOB.name == "Captain")
//boutput(world, "<b>[src] is the Captain!</b>")
if (JOB.announce_on_join)
boutput(world, "<b>[src] is the [JOB.name]!</b>")
boutput(src, "<B>You are the [JOB.name].</B>")
src.job = JOB.name
src.mind.assigned_role = JOB.name
if (!joined_late)
if ((ticker && ticker.mode && !istype(ticker.mode, /datum/game_mode/construction)) && JOB.name != "Tourist")
var/obj/S = null
if (job_start_locations && islist(job_start_locations[JOB.name]))
var/list/locations = job_start_locations[JOB.name]
S = pick(locations)
if (locate(/mob) in S.loc)
for (var/i=5, i>0, i--)
S = pick(locations)
if (!(locate(/mob) in S.loc))
break
else
for (var/obj/landmark/start/sloc in world)
if (sloc.name != JOB.name)
continue
if (locate(/mob) in sloc.loc)
continue
S = sloc
break
if (!S)
S = locate("start*[JOB.name]") // use old stype
if (istype(S, /obj/landmark/start) && isturf(S.loc))
src.set_loc(S.loc)
else
src.set_loc(pick(latejoin))
else
src.unlock_medal("Fish", 1)
if (time2text(world.realtime, "MM DD") == "12 25")
src.unlock_medal("A Holly Jolly Spacemas")
if (JOB.slot_back)
src.equip_if_possible(new JOB.slot_back(src), slot_back)
if (JOB.items_in_backpack.len && istype(src.back, /obj/item/storage))
for (var/X in JOB.items_in_backpack)
src.equip_if_possible(new X(src), slot_in_backpack)
if (JOB.slot_jump)
src.equip_if_possible(new JOB.slot_jump(src), slot_w_uniform)
if (JOB.slot_belt)
if (src.bioHolder && src.bioHolder.HasEffect("fat"))
src.equip_if_possible(new JOB.slot_belt(src), slot_in_backpack)
else
src.equip_if_possible(new JOB.slot_belt(src), slot_belt)
if (src.traitHolder && src.traitHolder.hasTrait("immigrant") && istype(src.belt, /obj/item/device/pda2))
del(src.belt) //UGHUGHUGHUGUUUUUUUU
if (JOB.items_in_belt.len && istype(src.belt, /obj/item/storage))
for (var/X in JOB.items_in_belt)
src.equip_if_possible(new X(src), slot_in_belt)
if (JOB.slot_foot)
src.equip_if_possible(new JOB.slot_foot(src), slot_shoes)
if (JOB.slot_suit)
src.equip_if_possible(new JOB.slot_suit(src), slot_wear_suit)
if (JOB.slot_ears)
src.equip_if_possible(new JOB.slot_ears(src), slot_ears)
if (JOB.slot_mask)
src.equip_if_possible(new JOB.slot_mask(src), slot_wear_mask)
if (JOB.slot_glov)
src.equip_if_possible(new JOB.slot_glov(src), slot_gloves)
if (JOB.slot_eyes)
src.equip_if_possible(new JOB.slot_eyes(src), slot_glasses)
if (JOB.slot_head)
src.equip_if_possible(new JOB.slot_head(src), slot_head)
if (JOB.slot_poc1)
if (src.bioHolder && src.bioHolder.HasEffect("fat"))
src.equip_if_possible(new JOB.slot_poc1(src), slot_in_backpack)
else
src.equip_if_possible(new JOB.slot_poc1(src), slot_l_store)
if (JOB.slot_poc2)
if (src.bioHolder && src.bioHolder.HasEffect("fat"))
src.equip_if_possible(new JOB.slot_poc2(src), slot_in_backpack)
else
src.equip_if_possible(new JOB.slot_poc2(src), slot_r_store)
if (JOB.slot_rhan)
src.equip_if_possible(new JOB.slot_rhan(src), slot_r_hand)
if (JOB.slot_lhan)
src.equip_if_possible(new JOB.slot_lhan(src), slot_l_hand)
var/T = pick(trinket_safelist)
var/obj/item/trinket = null
if (src.traitHolder && src.traitHolder.hasTrait("loyalist"))
trinket = new/obj/item/clothing/head/NTberet(src)
else if (src.traitHolder && src.traitHolder.hasTrait("petasusaphilic"))
var/picked = pick(typesof(/obj/item/clothing/head) - list(/obj/item/clothing/head, /obj/item/clothing/head/power, /obj/item/clothing/head/fancy, /obj/item/clothing/head/monkey, /obj/item/clothing/head/monkey/paper_hat) ) //IM A MONSTER DONT LOOK AT ME. NOOOOOOOOOOO
trinket = new picked(src)
else
trinket = new T(src)
if (trinket) // rewrote this a little bit so hopefully people will always get their trinket
trinket.name = "[src.real_name][pick(trinket_names)] [trinket.name]"
trinket.quality = rand(5,80)
var/equipped = 0
if (istype(src.back, /obj/item/storage) && src.equip_if_possible(trinket, slot_in_backpack))
equipped = 1
else if (istype(src.belt, /obj/item/storage) && src.equip_if_possible(trinket, slot_in_belt))
equipped = 1
if (!equipped)
if (!src.l_store && src.equip_if_possible(trinket, slot_l_store))
equipped = 1
else if (!src.r_store && src.equip_if_possible(trinket, slot_r_store))
equipped = 1
else if (!src.l_hand && src.equip_if_possible(trinket, slot_l_hand))
equipped = 1
else if (!src.r_hand && src.equip_if_possible(trinket, slot_r_hand))
equipped = 1
if (!equipped) // we've tried most available storage solutions here now so uh just put it on the ground
trinket.set_loc(get_turf(src))
JOB.special_setup(src)
// Manifest stuff
data_core.addManifest(src)
spawn(0)
if (src.traitHolder && !src.traitHolder.hasTrait("immigrant"))
spawnId(rank)
if (prob(10) && islist(random_pod_codes) && random_pod_codes.len)
var/obj/machinery/vehicle/V = pick(random_pod_codes)
random_pod_codes -= V
if (V && V.lock && V.lock.code)
boutput(src, "<span style=\"color:blue\">The unlock code to your pod ([V]) is: [V.lock.code]</span>")
if (src.mind)
src.mind.store_memory("The unlock code to your pod ([V]) is: [V.lock.code]")
if (src.mind && src.mind.late_special_role == 1 && src.mind.special_role == "traitor")
//put this here because otherwise it's called before they have a PDA
equip_traitor(src)
set_clothing_icon_dirty()
sleep(1)
update_icons_if_needed()
return
/mob/living/carbon/human/proc/spawnId(rank)
var/obj/item/card/id/C = null
var/datum/job/JOB = find_job_in_controller_by_string(rank)
if (!JOB || !JOB.slot_card)
return null
C = new JOB.slot_card(src)
if(C)
var/realName = src.real_name
if(src.traitHolder && src.traitHolder.hasTrait("clericalerror"))
realName = dd_replacetext(realName, "a", "o")
realName = dd_replacetext(realName, "e", "i")
realName = dd_replacetext(realName, "u", pick("a", "e"))
if(prob(50)) realName = dd_replacetext(realName, "n", "m")
if(prob(50)) realName = dd_replacetext(realName, "t", pick("d", "k"))
if(prob(50)) realName = dd_replacetext(realName, "p", pick("b", "t"))
var/datum/data/record/B = FindBankAccountByName(src.real_name)
if (B && B.fields["name"])
B.fields["name"] = realName
C.registered = realName
C.assignment = JOB.name
C.name = "[C.registered]'s ID Card ([C.assignment])"
C.access = JOB.access.Copy()
if(src.bioHolder && src.bioHolder.HasEffect("fat"))
src.equip_if_possible(C, slot_in_backpack)
else
src.equip_if_possible(C, slot_wear_id)
if(src.pin)
C.pin = src.pin
for (var/obj/item/device/pda2/PDA in src.contents)
PDA.owner = src.real_name
PDA.name = "PDA-[src.real_name]"
boutput(src, "<span style=\"color:blue\">Your pin to your ID is: [C.pin]</span>")
if (src.mind)
src.mind.store_memory("Your pin to your ID is: [C.pin]")
if (wagesystem.jobs[JOB.name])
src.equip_if_possible(new /obj/item/spacecash(src,wagesystem.jobs[JOB.name]), slot_r_store)
else
var/shitstore = rand(1,3)
switch(shitstore)
if(1)
src.equip_if_possible(new /obj/item/pen(src), slot_r_store)
if(2)
src.equip_if_possible(new /obj/item/reagent_containers/food/drinks/water(src), slot_r_store)
//////////////////////////////////////////////
// cogwerks - personalized trinkets project //
/////////////////////////////////////////////
var/list/trinket_safelist = list(/obj/item/basketball,/obj/item/bikehorn, /obj/item/brick, /obj/item/clothing/glasses/eyepatch,
/obj/item/clothing/glasses/regular, /obj/item/clothing/glasses/sunglasses, /obj/item/clothing/gloves/boxing,
/obj/item/clothing/mask/horse_mask, /obj/item/clothing/mask/clown_hat, /obj/item/clothing/head/cowboy, /obj/item/clothing/shoes/cowboy, /obj/item/clothing/shoes/moon,
/obj/item/clothing/suit/sweater, /obj/item/clothing/suit/sweater/red, /obj/item/clothing/suit/sweater/green, /obj/item/clothing/suit/sweater/grandma, /obj/item/clothing/under/shorts,
/obj/item/clothing/under/suit/pinstripe, /obj/item/cigpacket, /obj/item/coin, /obj/item/crowbar,
/obj/item/dice, /obj/item/dice/d20, /obj/item/device/flashlight, /obj/item/device/key/random, /obj/item/extinguisher, /obj/item/firework,
/obj/item/football, /obj/item/material_piece/gold, /obj/item/harmonica, /obj/item/horseshoe,
/obj/item/kitchen/utensil/knife, /obj/item/raw_material/rock, /obj/item/pen/fancy, /obj/item/pen/odd, /obj/item/plant/herb/cannabis/spawnable,
/obj/item/razor_blade,/obj/item/rubberduck, /obj/item/saxophone, /obj/item/scissors, /obj/item/screwdriver, /obj/item/skull, /obj/item/stamp,
/obj/item/vuvuzela, /obj/item/wrench, /obj/item/zippo, /obj/item/reagent_containers/food/drinks/bottle/beer, /obj/item/reagent_containers/food/drinks/bottle/vintage,
/obj/item/reagent_containers/food/drinks/bottle/vodka, /obj/item/reagent_containers/food/drinks/rum, /obj/item/reagent_containers/food/drinks/bottle/hobo_wine/safe,
/obj/item/reagent_containers/food/snacks/burger, /obj/item/reagent_containers/food/snacks/burger/cheeseburger,
/obj/item/reagent_containers/food/snacks/burger/moldy,/obj/item/reagent_containers/food/snacks/candy/chocolate, /obj/item/reagent_containers/food/snacks/chips,
/obj/item/reagent_containers/food/snacks/cookie,/obj/item/reagent_containers/food/snacks/ingredient/egg,
/obj/item/reagent_containers/food/snacks/ingredient/egg/bee,/obj/item/reagent_containers/food/snacks/plant/apple,
/obj/item/reagent_containers/food/snacks/plant/banana, /obj/item/reagent_containers/food/snacks/plant/potato, /obj/item/reagent_containers/food/snacks/sandwich/pb,
/obj/item/reagent_containers/food/snacks/sandwich/cheese, /obj/item/reagent_containers/syringe/krokodil, /obj/item/reagent_containers/syringe/morphine,
/obj/item/reagent_containers/patch/LSD, /obj/item/reagent_containers/patch/nicotine, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/food/drinks/drinkingglass, /obj/item/reagent_containers/food/drinks/drinkingglass/shot,/obj/item/storage/pill_bottle/bathsalts,
/obj/item/storage/pill_bottle/catdrugs, /obj/item/storage/pill_bottle/crank, /obj/item/storage/pill_bottle/cyberpunk, /obj/item/storage/pill_bottle/methamphetamine,
/obj/item/spraybottle,/obj/item/staple_gun,/obj/item/clothing/head/NTberet,/obj/item/clothing/head/biker_cap, /obj/item/clothing/head/black, /obj/item/clothing/head/blue,
/obj/item/clothing/head/chav, /obj/item/clothing/head/det_hat, /obj/item/clothing/head/green, /obj/item/clothing/head/helmet/hardhat, /obj/item/clothing/head/merchant_hat,
/obj/item/clothing/head/mj_hat, /obj/item/clothing/head/red, /obj/item/clothing/head/that, /obj/item/clothing/head/wig, /obj/item/clothing/head/turban, /obj/item/dice/magic8ball,
/obj/item/reagent_containers/food/drinks/mug/random_color, /obj/item/reagent_containers/food/drinks/skull_chalice, /obj/item/pen/marker/random, /obj/item/pen/crayon/random)
var/list/trinket_names = list("'s dad's","'s mom's", "'s grampa's", "'s grandma's", "'s favorite", "'s trusty", "'s favorite", "'s heirloom", "'s pet",
"'s beloved", "'s lucky", "'s best", "'s antique", "'s old", "'s ol'", "'s prized", "'s neat", "'s good old", "'s good ol'", "'s son's", "'s daughter's",
"'s aunt's", "'s uncle's", "'s finest", "'s shiniest", "'s lovely", "'s stupid", "'s prize winning", "'s top shelf", "'s 'prize winning'", "'s 'top shelf'",
"'s autographed", "'s monogramed", "'s bejazzled", "'s jewel encrusted", "'s fanciest", "'s worn out", "'s custom", "'s luxurious", "'s superb", "'s precious")
+196
View File
@@ -0,0 +1,196 @@
/* Hello these are the new logs wow gosh look at this isn't it exciting
Some placeholders exist for replacement within text:
%target% - Replaced by a link + traitor info for the name
Example in-game log call:
logTheThing("admin", src, M, "shot that nerd %target% at [showCoords(usr.x, usr.y, usr.z)]")
Example out of game log call:
logTheThing("diary", src, null, "gibbed everyone ever", "admin")
*/
/proc/logTheThing(type, source, target, text, diaryType)
var/diaryLogging
if (source)
source = constructName(source, type)
else
if (type != "diary") source = "<span class='blank'>(blank)</span>"
if (target) //If we have a target we assume the text has a %target% placeholder to shove it in
if (type == "diary") target = constructName(target, type)
else target = "<span class='target'>[constructName(target, type)]</span>"
text = dd_replacetext(text, "%target%", target)
var/ingameLog = "<td class='duration'>[round(((world.time / 10) / 60))]M</td><td class='source'>[source]</td><td class='text'>[text]</td>"
switch(type)
//These are things we log in-game (accessible via the Secrets menu)
if ("admin") logs["admin"] += ingameLog
if ("admin_help") logs["admin_help"] += ingameLog
if ("mentor_help") logs["mentor_help"] += ingameLog
if ("say") logs["speech"] += ingameLog
if ("ooc") logs["ooc"] += ingameLog
if ("whisper") logs["speech"] += ingameLog
if ("station") logs["station"] += ingameLog
if ("combat") logs["combat"] += ingameLog
if ("telepathy") logs["telepathy"] += ingameLog
if ("debug") logs["debug"] += ingameLog
if ("wiredebug") logs["wire_debug"] += ingameLog
if ("pdamsg") logs["pdamsg"] += ingameLog
if ("signalers") logs["signalers"] += ingameLog
if ("bombing") logs["bombing"] += ingameLog
if ("atmos") logs["atmos"] += ingameLog
if ("pathology") logs["pathology"] += ingameLog
if ("deleted") logs["deleted"] += ingameLog
if ("vehicle") logs["vehicle"] += ingameLog
if ("diary")
switch (diaryType)
//These are things we log in the out of game logs (the diary)
if ("admin") if (config.log_admin) diaryLogging = 1
if ("ahelp") if (config.log_say) diaryLogging = 1 //log_ahelp
if ("mhelp") if (config.log_say) diaryLogging = 1 //log_mhelp
if ("game") if (config.log_game) diaryLogging = 1
if ("vote") if (config.log_vote) diaryLogging = 1
if ("access") if (config.log_access) diaryLogging = 1
if ("say") if (config.log_say) diaryLogging = 1
if ("ooc") if (config.log_ooc) diaryLogging = 1
if ("whisper") if (config.log_whisper) diaryLogging = 1
if ("station") if (config.log_station) diaryLogging = 1
if ("combat") if (config.log_combat) diaryLogging = 1
if ("telepathy") if (config.log_telepathy) diaryLogging = 1
if ("debug") if (config.log_debug) diaryLogging = 1
if ("vehicle") if (config.log_vehicles) diaryLogging = 1
if (diaryLogging)
diary << "[time2text(world.timeofday, "\[hh:mm:ss\]")] [uppertext(diaryType)]: [source ? "[source] ": ""][text]"
return
/proc/constructName(ref, type)
var/name
var/ckey
var/key
var/traitor
var/online
var/dead = 1
var/mobType
var/mob/mobRef
if (ismob(ref))
mobRef = ref
traitor = checktraitor(mobRef)
if (mobRef.real_name)
name = mobRef.real_name
if (mobRef.key)
key = mobRef.key
if (mobRef.ckey)
ckey = mobRef.ckey
if (mobRef.client)
online = 1
if (mobRef.stat != 2)
dead = 0
else if (istype(ref,/client))
var/client/clientRef = ref
online = 1
if (clientRef.mob)
mobRef = clientRef.mob
traitor = checktraitor(mobRef)
if (mobRef.real_name)
name = clientRef.mob.real_name
if (mobRef.stat != 2)
dead = 0
if (clientRef.key)
key = clientRef.key
if (clientRef.ckey)
ckey = clientRef.ckey
else
return ref
if (mobRef)
if (ismonkey(mobRef)) mobType = "Monkey"
else if (isrobot(mobRef)) mobType = "Robot"
else if (isshell(mobRef)) mobType = "AI Shell"
else if (isAI(mobRef)) mobType = "AI"
else if (!ckey) mobType = "NPC"
var/data
if (name)
if (type == "diary")
data += name
else
data += "<span class='name'>[name]</span>"
if (mobType)
data += " ([mobType])"
if (ckey && key)
if (type == "diary")
data += "[name ? " (" : ""][key][name ? ")" : ""]"
else
data += "[name ? " (" : ""]<a href='?src=%admin_ref%;action=adminplayeropts;targetckey=[ckey]' title='Player Options'>[key]</a>[name ? ")" : ""]"
if (traitor)
if (type == "diary")
data += " \[TRAITOR\]"
else
data += " \[<span class='traitorTag'>T</span>\]"
if (type != "diary" && !online && ckey)
data += " \[<span class='offline'>OFF</span>\]"
if (dead && ticker && ticker.current_state && ticker.current_state > GAME_STATE_PREGAME)
if (type == "diary")
data += " \[DEAD\]"
else
data += " \[<span class='text-red'>DEAD</span>\]"
return data
proc/log_shot(var/obj/projectile/P,var/obj/SHOT, var/target_is_immune = 0)
if (!P || !SHOT)
return
var/shooter_data = null
var/vehicle
if (P.mob_shooter)
shooter_data = P.mob_shooter
else if (ismob(P.shooter))
var/mob/M = P.shooter
shooter_data = M
var/obj/machinery/vehicle/V
if (istype(P.shooter,/obj/machinery/vehicle/))
V = P.shooter
if (!shooter_data)
shooter_data = V.pilot
vehicle = 1
//Wire: Added this so I don't get a bunch of logs for fukken drones shooting pods WHO CARES
if (istype(P.shooter, /obj/critter/))
return
logTheThing("combat", shooter_data, SHOT, "[vehicle ? "driving [V.name] " : ""]shoots %target%[P.was_pointblank != 0 ? " point-blank" : ""][target_is_immune ? " (immune due to spellshield/nodamage)" : ""] at [log_loc(SHOT)]. <b>Projectile:</b> <I>[P.name]</I>[P.proj_data && P.proj_data.type ? ", <b>Type:</b> [P.proj_data.type]" :""]")
/proc/log_reagents(var/atom/A as turf|obj|mob)
var/log_reagents = ""
// In case we don't get a physical reagent holder. Required for chemSmoke particles (Convair880).
if (!isnull(A) && istype(A, /datum/reagents/))
var/datum/reagents/R = A
for (var/current_id in R.reagent_list)
var/datum/reagent/current_reagent = R.reagent_list[current_id]
log_reagents += " [current_reagent] ([current_reagent.volume]),"
if (log_reagents == "") log_reagents = "Nothing "
var/final_log = copytext(log_reagents, 1, -1)
return "(<b>Contents:</b> <i>[final_log]</i>. <b>Temp:</b> <i>[R.total_temperature] K</i>)"
if (!A)
return "(<b>Error:</b> <i>no source provided</i>)"
if (!A.reagents)
return "(<i>[A] has no reagent holder</i>)"
if (!A.reagents.total_volume)
return "(<b>Contents:</b> <i>nothing</i>)"
for (var/current_id2 in A.reagents.reagent_list)
var/datum/reagent/current_reagent2 = A.reagents.reagent_list[current_id2]
log_reagents += " [current_reagent2] ([current_reagent2.volume]),"
var/final_log2 = copytext(log_reagents, 1, -1)
return "(<b>Contents:</b> <i>[final_log2]</i>. <b>Temp:</b> <i>[A.reagents.total_temperature] K</i>)" // Added temperature. Even non-lethal chems can be harmful at unusually low or high temperatures (Convair880).
/proc/log_loc(var/atom/A as turf|obj|mob)
if (!istype(A))
return
var/turf/our_turf = null
if (!isturf(A.loc))
our_turf = get_turf(A)
return "([our_turf ? "[showCoords(our_turf.x, our_turf.y, our_turf.z)]" : "[showCoords(A.x, A.y, A.z)]"] in [get_area(A)])"
// Does what is says on the tin. We're using the global proc, though (Convair880).
/proc/log_atmos(var/atom/A as turf|obj|mob)
return scan_atmospheric(A, 0, 1)
+31
View File
@@ -0,0 +1,31 @@
////////////////////////////////////////////////////////////////////////////////////
// client procs
//
// these verbs allow admins to monitor and adjust the master controller
// and process loops live during the round
/client/proc/main_loop_context()
set category = "Debug"
set name = "Main Loop Context"
set desc = "Displays the current main loop context information (lastproc: lasttask \[world.timeofday\])"
if(src.holder)
if(!src.mob)
return
processSchedulerView.getContext()
// this is a godawful hack for now, pending cleanup as part of a better main loop control panel. but hey it works
/client/proc/main_loop_tick_detail()
set category = "Debug"
set name = "Main Loop Tick Detail"
set desc = "Displays detailed tick information for the main loops that support it."
if(src.holder)
if(!src.mob)
return
if(src.holder.rank in list("Coder", "Host"))
boutput(src, "Dumping detailed tick counters...")
for (var/datum/controller/process/child in processScheduler.processes)
child.tickDetail()
else
alert("Fuck off, no crashing dis server")
return
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
var/religion_name = null
/proc/religion_name()
if (religion_name)
return religion_name
//
var/name = ""
name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob")
name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity")
return capitalize(name)
+182
View File
@@ -0,0 +1,182 @@
/*********************************
* GENERIC HELPERS FOR BOTH SYSTEMS
*********************************/
//Generates file paths for browser resources when used in html tags e.g. <img>
/proc/resource(file)
if (!file) return
var/path
if (CDN_ENABLED && cdn && config.env == "prod") //Or local tester with internet...
path = "[cdn]/[file]"
else
if (findtext(file, "/"))
var/list/parts = dd_text2list(file, "/")
file = parts[parts.len]
path = file
return path
//Returns the file contents for storage in memory or further processing during runtime (e.g. many html files)
/proc/grabResource(path)
if (!path) return 0
var/file
//File exists in cache, just return that
if (!disableResourceCache && cachedResources[path])
file = cachedResources[path]
//Not in cache, go grab it
else
if (CDN_ENABLED && cdn && config.env == "prod") //Or local tester with internet...
//Actually get the file contents from the CDN
var/http[] = world.Export("[cdn]/[path]")
if (!http || !http["CONTENT"])
CRASH("CDN DEBUG: No file found for path: [path]")
return ""
file = file2text(http["CONTENT"])
else //No CDN, grab from local directory
file = parseAssetLinks(file("browserassets/[path]"))
if (!disableResourceCache)
cachedResources[path] = file
return file
/proc/debugResourceCacheItem(path)
if (cachedResources[path])
return html_encode(cachedResources[path])
else
return "Not found"
/client/proc/debugResourceCache()
set category = "Debug"
set name = "Debug Resource Cache"
set hidden = 1
admin_only
var/msg = "Resource cache contents:"
for (var/r in cachedResources)
msg += "<br>[r]"
out(src, msg)
/client/proc/toggleResourceCache()
set category = "Toggles"
set name = "Toggle Resource Cache"
set desc = "Enable or disable the resource cache system"
admin_only
disableResourceCache = !disableResourceCache
boutput(usr, "<span style=\"color:blue\">Toggled the resource cache [disableResourceCache ? "off" : "on"]</span>")
logTheThing("admin", usr, null, "toggled the resource cache [disableResourceCache ? "off" : "on"]")
logTheThing("diary", usr, null, "toggled the resource cache [disableResourceCache ? "off" : "on"]", "admin")
message_admins("[key_name(usr)] toggled the resource cache [disableResourceCache ? "off" : "on"]")
/*********************************
* CDN PROCS FOR LIVE SERVERS
*********************************/
//aint shit
/*********************************
* PROCS FOR LOCAL SERVER FALLBACK
*********************************/
//Replace placeholder tags with the raw filename (minus any subdirs), only for localservers
/proc/doAssetParse(path)
if (findtext(path, "/"))
var/list/parts = dd_text2list(path, "/")
path = parts[parts.len]
return path
//Converts placeholder tags to filepaths appropriate for local-hosting offline (absolute, no subdirs)
/proc/parseAssetLinks(file, path)
if (!file) return 0
//Get file extension
if (path)
var/list/parts = dd_text2list(path, ".")
var/ext = parts[parts.len]
ext = lowertext(ext)
//Is this file a binary thing
if (ext in list("jpg", "jpeg", "png", "svg", "bmp", "gif", "eot", "woff", "woff2", "ttf", "otf"))
return 0
//Look for resource placeholder tags. {{resource("path/to/file")}}
var/fileText = file
if (isfile(file))
fileText = file2text(file)
if (fileText && findtext(fileText, "{{resource"))
var/regex/R = new("/\\{\\{resource\\(\"(.*?)\"\\)\\}\\}/\[resource($1)\]/ige")
var/newtxt = R.Replace(fileText)
while(newtxt)
fileText = newtxt
newtxt = R.ReplaceNext(fileText)
return fileText
//Puts all files in a directory into a list
/proc/recursiveFileLoader(dir)
for(var/i in flist(dir))
//logTheThing("wiredebug", "<b>LOADER:</b> [i]")
if (copytext(i, -1) == "/") //Is Directory
if (i == "unused/" || i == "html/")
continue
else
recursiveFileLoader(dir + i)
else //Is file
if (dir == "browserassets/") //skip files in base dir (hardcoding dir name here because im lazy ok)
continue
else
localResources["[dir][i]"] = file("[dir][i]")
//#LongProcNames #yolo
/client/proc/loadResourcesFromList(list/rscList)
for (var/r in rscList) //r is a file path
var/fileRef = file(r)
var/parsedFile = parseAssetLinks(fileRef, r)
if (parsedFile) //file is text and has been parsed for filepaths
var/newPath = "data/resources/[r]"
if (copytext(newPath, -1) != "/" && fexists(newPath)) //"server" already has this file? apparently that causes ~problems~
fdel(newPath)
if (text2file(parsedFile, newPath)) //make a new file with the parsed text because byond fucking sucks at sending text as anything besides html
src << browse(file(newPath), "file=[r];display=0")
else
world.log << "RESOURCE ERROR: Failed to convert text in '[r]' to a temporary file"
else //file is binary just throw it at the client as is
src << browse(fileRef, "file=[r];display=0")
return 1
//A thing for coders locally testing to use (as they might be offline = can't reach the CDN)
/client/proc/loadResources()
if ((CDN_ENABLED && config.env == "prod") || src.resourcesLoaded) return 0
boutput(src, "<span style='color: blue;'><b>Resources are now loading, browser windows will open normally when complete.</b></span>")
src.loadResourcesFromList(localResources)
var/s = {"<html>
<head></head>
<body>
<script type="text/javascript">
window.location='byond://?src=\ref[src];action=resourcePreloadComplete';
</script>
</body
</html>
"}
src << browse(s, "window=resourcePreload;titlebar=0;size=1x1;can_close=0;can_resize=0;can_scroll=0;border=0")
src.resourcesLoaded = 1
return 1
+512
View File
@@ -0,0 +1,512 @@
/proc/scan_health(var/mob/M as mob, var/verbose_reagent_info = 0, var/disease_detection = 1)
if (!M)
return "<span style='color:red'>ERROR: NO SUBJECT DETECTED</span>"
if (isghostdrone(M))
return "<span style='color:red'>ERROR: INVALID DATA FROM SUBJECT</span>"
var/death_state = M.stat
if (M.bioHolder && M.bioHolder.HasEffect("dead_scan"))
death_state = 2
var/health_percent = round(100 * M.health / M.max_health)
var/colored_health
if (health_percent >= 51 && health_percent <= 100)
colored_health = "<span style='color:#138015'>[health_percent]</span>"
else if (health_percent >= 1 && health_percent <= 50)
colored_health = "<span style='color:#CC7A1D'>[health_percent]</span>"
else colored_health = "<span style='color:red'>[health_percent]</span>"
var/optimal_temp = M.base_body_temp
var/body_temp = "[M.bodytemperature - T0C]&deg;C ([M.bodytemperature * 1.8-459.67]&deg;F)"
var/colored_temp = ""
if (M.bodytemperature >= (optimal_temp + 60))
colored_temp = "<span style='color:red'>[body_temp]</span>"
else if (M.bodytemperature >= (optimal_temp + 30))
colored_temp = "<span style='color:#CC7A1D'>[body_temp]</span>"
else if (M.bodytemperature <= (optimal_temp - 60))
colored_temp = "<span style='color:blue'>[body_temp]</span>"
else if (M.bodytemperature <= (optimal_temp - 30))
colored_temp = "<span style='color:#1F75D1'>[body_temp]</span>"
else
colored_temp = "[body_temp]"
var/oxy = M.get_oxygen_deprivation()
var/tox = M.get_toxin_damage()
var/burn = M.get_burn_damage()
var/brute = M.get_brute_damage()
// contained here in order to change them easier
var/oxy_font = "<span style='color:#1F75D1'>"
var/tox_font = "<span style='color:#138015'>"
var/burn_font = "<span style='color:#CC7A1D'>"
var/brute_font = "<span style='color:#E60E4E'>"
var/oxy_data = "[oxy > 50 ? "<span style='color:red'>" : "[oxy_font]"][oxy]</span>"
var/tox_data = "[tox > 50 ? "<span style='color:red'>" : "[tox_font]"][tox]</span>"
var/burn_data = "[burn > 50 ? "<span style='color:red'>" : "[burn_font]"][burn]</span>"
var/brute_data = "[brute > 50 ? "<span style='color:red'>" : "[brute_font]"][brute]</span>"
var/rad_data = null
var/blood_data = null
var/brain_data = null
var/heart_data = null
var/reagent_data = null
var/pathogen_data = null
var/disease_data = null
if (ishuman(M))
var/mob/living/carbon/human/H = M
if (blood_system)
if (verbose_reagent_info)
if (isvampire(H)) // Added a pair of vampire checks here (Convair880).
blood_data = "<span style='color:red'>Blood level: 500 units</span>"
else
blood_data = "<span style='color:red'>Blood level: [H.blood_volume] unit[H.blood_volume == 1 ? "" : "s"]</span>"
if (H.bleeding)
blood_data += " | <span style='color:red'>Blood loss: [H.bleeding] unit[H.bleeding == 1 ? "" : "s"]</span>"
else
if (isvampire(H))
blood_data = "<span style='color:red'>Blood level: NORMAL</span>"
else
switch (H.blood_volume)
if (401 to INFINITY)
blood_data = "<span style='color:red'>Blood level: NORMAL</span>"
if (251 to 400)
blood_data = "<span style='color:red'>Blood level: <B>LOW</B></span>"
if (151 to 250)
blood_data = "<span style='color:red'>Blood level: <B>VERY LOW</B></span>"
if (1 to 150)
blood_data = "<span style='color:red'>Blood level: <B>DANGEROUSLY LOW</B></span>"
if (-INFINITY to 0)
blood_data = "<span style='color:red'>Blood level: <B>NO BLOOD DETECTED</B></span>"
switch (H.bleeding)
if (1 to 3)
blood_data += " | <span style='color:red'><B>Minor bleeding wounds detected</B></span>"
if (4 to 6)
blood_data += " | <span style='color:red'><B>Bleeding wounds detected</B></span>"
if (7 to INFINITY)
blood_data += " | <span style='color:red'><B>Major bleeding wounds detected</B></span>"
if (H.implant && H.implant.len > 0)
var/bad_stuff = 0
for (var/obj/item/implant/I in H)
if (istype(I, /obj/item/implant/projectile))
bad_stuff ++
if (bad_stuff)
blood_data += " | <span style='color:red'><B>Foreign object[bad_stuff == 1 ? "" : "s"] detected</B></span>"
if (H.pathogens.len)
pathogen_data = "<span style='color:red'>Scans indicate the presence of [H.pathogens.len > 1 ? "[H.pathogens.len] " : null]pathogenic bodies.</span>"
var/list/therapy = list()
var/remissive = 0
for (var/uid in H.pathogens)
var/datum/pathogen/P = H.pathogens[uid]
if (P.in_remission)
remissive ++
if (!(P.suppressant.therapy in therapy))
therapy += P.suppressant.therapy
var/count_part
if (!remissive)
count_part = "None of them appear"
else if (remissive == 1)
count_part = "One pathogen appears"
else
count_part = "[remissive] of them appear"
pathogen_data += "<br>&emsp;<span style='color:red'>[count_part] to be in a remissive state.</span>"
pathogen_data += "<br><span style='font-weight:bold'>Suggested pathogen suppression therapies: [dd_list2text(therapy, ", ")]."
if (H.organHolder)
if (H.organHolder.brain)
if (H.get_brain_damage() >= 100)
brain_data = "<span style='color:red'>Subject is braindead.</span>"
else if (H.get_brain_damage() >= 60)
brain_data = "<span style='color:red'>Severe brain damage detected. Subject likely unable to function well.</span>"
else if (H.get_brain_damage() >= 10)
brain_data = "<span style='color:red'>Significant brain damage detected. Subject may have had a concussion.</span>"
else
brain_data = "<span style='color:red'>Subject has no brain.</span>"
else
brain_data = "<span style='color:red'>Subject has no brain.</span>"
if (H.organHolder && !H.organHolder.heart)
heart_data = "<span style='color:red'>Subject has no heart.</span>"
if (M.radiation)
rad_data = "&emsp;<span style='color:red'>Radiation: [round(M.radiation / 10, 0.1)] Gy</span>"
for (var/datum/ailment_data/A in M.ailments)
if (disease_detection >= A.detectability)
disease_data += "<br>[A.scan_info()]"
if (M.reagents)
if (verbose_reagent_info)
reagent_data = scan_reagents(M, 0)
else
var/ephe_amt = M.reagents:get_reagent_amount("ephedrine")
var/epi_amt = M.reagents:get_reagent_amount("epinephrine")
var/atro_amt = M.reagents:get_reagent_amount("atropine")
var/total_amt = ephe_amt + epi_amt + atro_amt
if (total_amt)
reagent_data = "<span style='color:blue'>Bloodstream Analysis located [total_amt] units of rejuvenation chemicals.</span>"
if (!ishuman(M)) // vOv
if (M.get_brain_damage() >= 100)
brain_data = "<span style='color:red'>Subject is braindead.</span>"
else if (M.get_brain_damage() >= 60)
brain_data = "<span style='color:red'>Severe brain damage detected. Subject likely unable to function well.</span>"
else if (M.get_brain_damage() >= 10)
brain_data = "<span style='color:red'>Significant brain damage detected. Subject may have had a concussion.</span>"
var/data = "--------------------------------<br>\
Analyzing Results for <span style='color:blue'>[M]</span>:<br>\
&emsp; Overall Status: [death_state > 1 ? "<span style='color:red'>DEAD</span>" : "[colored_health]% healthy"]<br>\
&emsp; Damage Specifics: [oxy_data] - [tox_data] - [burn_data] - [brute_data]<br>\
&emsp; Key: [oxy_font]Suffocation</span>/[tox_font]Toxin</span>/[burn_font]Burns</span>/[brute_font]Brute</span><br>\
Body Temperature: [colored_temp]\
[rad_data ? "<br>[rad_data]" : null]\
[blood_data ? "<br>[blood_data]" : null]\
[brain_data ? "<br>[brain_data]" : null]\
[heart_data ? "<br>[heart_data]" : null]\
[reagent_data ? "<br>[reagent_data]" : null]\
[pathogen_data ? "<br>[pathogen_data]" : null]\
[disease_data ? "[disease_data]" : null]"
return data
/proc/update_medical_record(var/mob/living/carbon/human/M)
if (!M || !ishuman(M))
return
var/patientname = M.name
if (M:wear_id && M:wear_id:registered)
patientname = M.wear_id:registered
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == patientname)
switch (M.stat)
if (0)
if (M.bioHolder && M.bioHolder.HasEffect("fat"))
E.fields["p_stat"] = "Physically Unfit"
else
E.fields["p_stat"] = "Active"
if (1)
E.fields["p_stat"] = "*Unconscious*"
if (2)
E.fields["p_stat"] = "*Deceased*"
for (var/datum/data/record/R in data_core.medical)
if ((R.fields["id"] == E.fields["id"]))
R.fields["bioHolder.bloodType"] = M.bioHolder.bloodType
R.fields["cdi"] = english_list(M.ailments, "No diseases have been diagnosed at the moment.")
if (M.ailments.len)
R.fields["cdi_d"] = "Diseases detected at [time2text(world.realtime,"hh:mm")]."
else
R.fields["cdi_d"] = "No notes."
break
break
return
/proc/scan_reagents(var/atom/A as turf|obj|mob, var/show_temp = 1, var/single_line = 0)
if (!A)
return "<span style='color:red'>ERROR: NO SUBJECT DETECTED</span>"
var/data = null
var/reagent_data = null
if (A.reagents)
if (A.reagents.reagent_list.len > 0)
var/reagents_length = A.reagents.reagent_list.len
data = "<span style='color:blue'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found in [A].</span>"
for (var/current_id in A.reagents.reagent_list)
var/datum/reagent/current_reagent = A.reagents.reagent_list[current_id]
if (single_line)
reagent_data += " [current_reagent] ([current_reagent.volume]),"
else
reagent_data += "<br>&emsp;[current_reagent.name] - [current_reagent.volume]"
if (single_line)
data += "<span style='color:blue'>[copytext(reagent_data, 1, -1)]</span>"
else
data += "<span style='color:blue'>[reagent_data]</span>"
if (show_temp)
data += "<br><span style='color:blue'>Overall temperature: [A.reagents.total_temperature - T0C]&deg;C ([A.reagents.total_temperature * 1.8-459.67]&deg;F)</span>"
else
data = "<span style='color:blue'>No active chemical agents found in [A].</span>"
else
data = "<span style='color:blue'>No significant chemical agents found in [A].</span>"
return data
// Should make it easier to maintain the detective's scanner and PDA program (Convair880).
/proc/scan_forensic(var/atom/A as turf|obj|mob)
var/fingerprint_data = null
var/blood_data = null
var/forensic_data = null
var/glove_data = null
var/contraband_data = null
if (!A)
return "<span style='color:red'>ERROR: NO SUBJECT DETECTED</span>"
if (istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/H = A
if (!isnull(H.gloves))
var/obj/item/clothing/gloves/WG = H.gloves
if (WG.glove_ID)
glove_data += "[WG.glove_ID] (<span style='color:blue'>[H]'s worn [WG.name]</span>)"
if (!WG.hide_prints)
fingerprint_data += "<br><span style='color:blue'>[H]'s fingerprints:</span> [md5(H.bioHolder.Uid)]"
else
fingerprint_data += "<br><span style='color:blue'>Unable to scan [H]'s fingerprints.</span>"
else
fingerprint_data += "<br><span style='color:blue'>[H]'s fingerprints:</span> [md5(H.bioHolder.Uid)]"
if (H.gunshot_residue) // Left by firing a kinetic gun.
forensic_data += "<br><span style='color:blue'>Gunshot residue found.</span>"
if (H.implant && H.implant.len > 0)
var/wounds = null
for (var/obj/item/implant/I in H)
if (istype(I, /obj/item/implant/projectile))
wounds ++
if (wounds)
forensic_data += "<br><span style='color:blue'>[wounds] gunshot [wounds == 1 ? "wound" : "wounds"] detected.</span>"
if (H.fingerprints) // Left by grabbing or pulling people.
var/list/FFP = params2list(H:fingerprints)
for(var/i in FFP)
fingerprint_data += "<br><span style='color:blue'>Foreign fingerprint on [H]:</span> [i]"
if (H.bioHolder.Uid) // For quick reference. Also, attacking somebody only makes their clothes bloody, not the mob (think naked dudes).
blood_data += "<br><span style='color:blue'>[H]'s blood DNA:</span> [H.bioHolder.Uid]"
if (H.blood_DNA && isnull(H.gloves)) // Don't magically detect blood through worn gloves.
var/list/BH = params2list(H:blood_DNA)
for(var/i in BH)
blood_data += "<br><span style='color:blue'>Blood on [H]'s hands:</span> [i]"
var/list/gear_to_check = list(H.head, H.wear_mask, H.w_uniform, H.wear_suit, H.belt, H.gloves, H.back)
for (var/obj/item/check in gear_to_check)
if (check && check.blood_DNA)
var/list/BC = params2list(check.blood_DNA)
for(var/i in BC)
blood_data += "<br><span style='color:blue'>Blood on worn [check.name]:</span> [i]"
if (H.r_hand && H.r_hand.blood_DNA)
var/list/BIR = params2list(H.r_hand.blood_DNA)
for(var/i in BIR)
blood_data += "<br><span style='color:blue'>Blood on held [H.r_hand.name]:</span> [i]"
if (H.l_hand && H.l_hand.blood_DNA)
var/list/BIL = params2list(H.l_hand.blood_DNA)
for(var/i in BIL)
blood_data += "<br><span style='color:blue'>Blood on held [H.l_hand.name]:</span> [i]"
else
if (!A.fingerprints)
fingerprint_data += "<br><span style='color:blue'>Unable to locate any fingerprints.</span>"
else
var/list/FP = params2list(A:fingerprints)
for(var/i in FP)
fingerprint_data += "<br><span style='color:blue'>[i]</span>"
if(!A.blood_DNA)
blood_data += "<br><span style='color:blue'>Unable to locate any blood traces.</span>"
else
var/list/DNA = params2list(A:blood_DNA)
for(var/i in DNA)
blood_data += "<br><span style='color:blue'>[i]</span>"
if (istype(A, /obj/item))
var/obj/item/I = A
if(I.contraband)
contraband_data = "<span style='color:red'>(CONTRABAND: LEVEL [I.contraband])</span>"
if (istype(A, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = A
if (G.glove_ID)
glove_data += "[G.glove_ID] [G.material_prints ? "([G.material_prints])" : null]"
if (istype(A, /obj/item/casing/))
var/obj/item/casing/C = A
if(C.forensic_ID)
forensic_data += "<br><span style='color:blue'>Forensic profile of [C]:</span> [C.forensic_ID]"
if (istype(A, /obj/item/implant/projectile))
var/obj/item/implant/projectile/P = A
if(P.forensic_ID)
forensic_data += "<br><span style='color:blue'>Forensic profile of [P]:</span> [P.forensic_ID]"
if (istype(A, /obj/item/gun))
var/obj/item/gun/G = A
if(G.forensic_ID)
forensic_data += "<br><span style='color:blue'>Forensic profile of [G]:</span> [G.forensic_ID]"
if (istype(A, /turf/simulated/wall))
var/turf/simulated/wall/W = A
if (W.forensic_impacts && islist(W.forensic_impacts) && W.forensic_impacts.len)
for(var/i in W.forensic_impacts)
forensic_data += "<br><span style='color:blue'>Forensic signature found:</span> [i]"
if (!fingerprint_data) // Just in case, we'd always want to have a readout for these.
fingerprint_data = "<br><span style='color:blue'>Unable to locate any fingerprints.</span>"
if (!blood_data)
blood_data = "<br><span style='color:blue'>Unable to locate any blood traces.</span>"
// This was the least enjoyable part of the entire exercise. Formatting is nothing but a chore.
var/data = "--------------------------------<br>\
<span style='color:blue'>Forensic analysis of <b>[A]</b></span> [contraband_data ? "[contraband_data]" : null]<br>\
<br>\
<i>Isolated fingerprints:</i>[fingerprint_data]<br>\
<br>\
<i>Isolated blood samples:</i>[blood_data]<br>\
[forensic_data ? "<br><i>Additional forensic data:</i>[forensic_data]<br>" : null]\
[glove_data ? "<br><i>Material analysis:</i><span style='color:blue'> [glove_data]</span>" : null]\
"
return data
// Made this a global proc instead of 10 or so instances of duplicate code spread across the codebase (Convair880).
/proc/scan_atmospheric(var/atom/A as turf|obj, var/pda_readout = 0, var/simple_output = 0)
if (!A)
if (pda_readout == 1)
return "Unable to obtain a reading."
else if (simple_output == 1)
return "(<b>Error:</b> <i>no source provided</i>)"
else
return "<span style='color:red'>Unable to obtain a reading.</span>"
var/datum/gas_mixture/check_me = null
var/pressure = null
var/total_moles = null
if (hasvar(A, "air_contents"))
check_me = A:air_contents // Not pretty, but should be okay here.
if (isturf(A))
check_me = A.return_air()
if (istype(A, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = A
check_me = P.parent.air
if (istype(A, /obj/item/assembly/time_bomb))
var/obj/item/assembly/time_bomb/TB = A
if (TB.part3)
check_me = TB.part3.air_contents
if (istype(A, /obj/item/assembly/radio_bomb))
var/obj/item/assembly/radio_bomb/RB = A
if (RB.part3)
check_me = RB.part3.air_contents
if (istype(A, /obj/item/assembly/proximity_bomb))
var/obj/item/assembly/proximity_bomb/PB = A
if (PB.part3)
check_me = PB.part3.air_contents
if (istype(A, /obj/item/flamethrower/))
var/obj/item/flamethrower/FT = A
if (FT.part4)
check_me = FT.part4.air_contents
if (!check_me || !istype(check_me, /datum/gas_mixture/))
if (pda_readout == 1)
return "[A] does not contain any gas."
else if (simple_output == 1)
return "(<i>[A] has no gas holder</i>)"
else
return "<span style='color:red'>[A] does not contain any gas.</span>"
pressure = check_me.return_pressure()
total_moles = check_me.total_moles()
//DEBUG("[A] contains: [pressure] kPa, [total_moles] moles.")
var/data = ""
if (total_moles > 0)
var/o2_concentration = check_me.oxygen/total_moles
var/n2_concentration = check_me.nitrogen/total_moles
var/co2_concentration = check_me.carbon_dioxide/total_moles
var/plasma_concentration = check_me.toxins/total_moles
var/unknown_concentration = 1 - (o2_concentration + n2_concentration + co2_concentration + plasma_concentration)
if (pda_readout == 1) // Output goes into PDA interface, not the user's chatbox.
data = "Air Pressure: [round(pressure, 0.1)] kPa<br>\
Nitrogen: [round(n2_concentration * 100)]%<br>\
Oxygen: [round(o2_concentration * 100)]%<br>\
CO2: [round(co2_concentration * 100)]%<br>\
Plasma: [round(plasma_concentration * 100)]%<br>\
[unknown_concentration > 0.01 ? "Unknown: [round(unknown_concentration * 100)]%<br>" : ""]\
Temperature: [round(check_me.temperature - T0C)]&deg;C<br>"
else if (simple_output == 1) // For the log_atmos() proc.
data = "(<b>Pressure:</b> <i>[round(pressure, 0.1)] kPa</i>, <b>Temp:</b> <i>[round(check_me.temperature - T0C)]&deg;C</i>\
, <b>Contents:</b> <i>[round(n2_concentration * 100)]% N2 / [round(o2_concentration * 100)]% O2 / [round(co2_concentration * 100)]% CO2 / [round(plasma_concentration * 100)]% PL</i>\
[unknown_concentration > 0.01 ? "<i> / [round(unknown_concentration * 100)]% other</i>)" : ")"]"
else
data = "--------------------------------<br>\
<span style='color:blue'>Atmospheric analysis of <b>[A]</b></span><br>\
<br>\
Pressure: [round(pressure, 0.1)] kPa<br>\
Nitrogen: [round(n2_concentration * 100)]%<br>\
Oxygen: [round(o2_concentration * 100)]%<br>\
CO2: [round(co2_concentration * 100)]%<br>\
Plasma: [round(plasma_concentration * 100)]%<br>\
[unknown_concentration > 0.01 ? "</span><span style='color:red'>Unknown: [round(unknown_concentration * 100)]%</span><span style='color:blue'><br>" : ""]\
Temperature: [round(check_me.temperature - T0C)]&deg;C<br>"
else
// Only used for "Atmospheric Scan" accessible through the PDA interface, which targets the turf
// the PDA user is standing on. Everything else (i.e. clicking with the PDA on objects) goes in the chatbox.
if (pda_readout == 1)
data = "This area does not contain any gas."
else if (simple_output == 1)
data = "(<b>Contents:</b> <i>empty</i></b>)"
else
data = "<span style='color:red'>[A] does not contain any gas.</span>"
return data
// Yeah, another scan I made into a global proc (Convair880).
/proc/scan_plant(var/atom/A as turf|obj, var/mob/user as mob)
if (!A || !user || !ismob(user))
return
var/datum/plant/P = null
var/datum/plantgenes/DNA = null
if (istype(A, /obj/machinery/plantpot))
var/obj/machinery/plantpot/PP = A
if (!PP.current || PP.dead)
return "<span style=\"color:red\">Cannot scan.</span>"
P = PP.current
DNA = PP.plantgenes
else if (istype(A, /obj/item/seed/))
var/obj/item/seed/S = A
if (S.isstrange || !S.planttype)
return "<span style=\"color:red\">This seed has non-standard DNA and thus cannot be scanned.</span>"
P = S.planttype
DNA = S.plantgenes
else if (istype(A, /obj/item/reagent_containers/food/snacks/plant/))
var/obj/item/reagent_containers/food/snacks/plant/F = A
P = F.planttype
DNA = F.plantgenes
else
return
if (!P || !istype(P, /datum/plant/) || !DNA || !istype(DNA, /datum/plantgenes/))
return "<span style=\"color:red\">Cannot scan.</span>"
HYPgeneticanalysis(user, A, P, DNA) // Just use the existing proc.
return
+235
View File
@@ -0,0 +1,235 @@
/mob/proc/scorestats()
var/dat = {"<B>Round Statistics and Score</B><BR><HR>"}
if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/nuclear))
var/foecount = 0
var/crewcount = 0
var/bombdat = null
for(var/datum/mind/M in ticker.mode:syndicates)
foecount++
for(var/mob/living/C in mobs)
if (!istype(C,/mob/living/carbon/human) || !istype(C,/mob/living/silicon/robot) || !istype(C,/mob/living/silicon/ai)) continue
if (C.stat == 2) continue
if (!C.client) continue
crewcount++
dat += {"<B><U>MODE STATS</U></B><BR>
<B>Number of Operatives:</B> [foecount]<BR>
<B>Number of Surviving Crew:</B> [crewcount]<BR>
<B>Final Location of Nuke:</B> [bombdat]<BR><BR>
<B>Nuclear Disk Secure:</B> [score_disc ? "Yes" : "No"] ([score_disc * 500] Points)<BR>
<B>Operatives Arrested:</B> [score_arrested] ([score_arrested * 1000] Points)<BR>
<B>Operatives Killed:</B> [score_opkilled] ([score_opkilled * 250] Points)<BR>
<B>Station Destroyed:</B> [score_nuked ? "Yes" : "No"] (-10000 Points)<BR>
<B>All Operatives Arrested:</B> [score_allarrested ? "Yes" : "No"] (Score tripled)<BR>
<HR>"}
if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution))
var/foecount = 0
var/comcount = 0
var/revcount = 0
var/loycount = 0
for(var/datum/mind/M in ticker.mode:head_revolutionaries)
if (M.current && M.current.stat != 2) foecount++
for(var/datum/mind/M in ticker.mode:revolutionaries)
if (M.current && M.current.stat != 2) revcount++
for(var/mob/living/carbon/human/player in mobs)
if(player.mind)
var/role = player.mind.assigned_role
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director", "Medical Director"))
if (player.stat != 2) comcount++
else
if(player.mind in ticker.mode:revolutionaries) continue
loycount++
for(var/mob/living/silicon/X in mobs)
if (X.stat != 2) loycount++
var/revpenalty = 10000
dat += {"<B><U>MODE STATS</U></B><BR>
<B>Number of Surviving Revolution Heads:</B> [foecount]<BR>
<B>Number of Surviving Command Staff:</B> [comcount]<BR>
<B>Number of Surviving Revolutionaries:</B> [revcount]<BR>
<B>Number of Surviving Loyal Crew:</B> [loycount]<BR><BR>
<B>Revolution Heads Arrested:</B> [score_arrested] ([score_arrested * 1000] Points)<BR>
<B>Revolution Heads Slain:</B> [score_opkilled] ([score_opkilled * 500] Points)<BR>
<B>Command Staff Slain:</B> [score_deadcommand] (-[score_deadcommand * 500] Points)<BR>
<B>Revolution Successful:</B> [score_traitorswon ? "Yes" : "No"] (-[score_traitorswon * revpenalty] Points)<BR>
<B>All Revolution Heads Arrested:</B> [score_allarrested ? "Yes" : "No"] (Score tripled)<BR>
<HR>"}
var/totalfunds = wagesystem.station_budget + wagesystem.research_budget + wagesystem.shipping_budget
dat += {"<B><U>GENERAL STATS</U></B><BR>
<U>THE GOOD:</U><BR>
<B>Useful Items Shipped:</B> [score_stuffshipped] ([score_stuffshipped * 5] Points)<BR>
<B>Hydroponics Harvests:</B> [score_stuffharvested] ([score_stuffharvested * 5] Points)<BR>
<B>Ore Mined:</B> [score_oremined] ([score_oremined * 2] Points)<BR>
<B>Refreshments Prepared:</B> [score_meals] ([score_meals * 5] Points)<BR>
<B>Research Completed:</B> [score_researchdone] ([score_researchdone * 30] Points)<BR>
<B>Cyborgs Constructed:</B> [score_cyborgsmade] ([score_cyborgsmade * 50] Points)<BR>"}
if (emergency_shuttle.location == 2) dat += "<B>Shuttle Escapees:</B> [score_escapees] ([score_escapees * 25] Points)<BR>"
dat += {"<B>Random Events Endured:</B> [score_eventsendured] ([score_eventsendured * 50] Points)<BR>
<B>Whole Station Powered:</B> [score_powerbonus ? "Yes" : "No"] ([score_powerbonus * 2500] Points)<BR>
<B>Ultra-Clean Station:</B> [score_mess ? "No" : "Yes"] ([score_messbonus * 3000] Points)<BR><BR>
<U>THE BAD:</U><BR>
<B>Dead Bodies on Station:</B> [score_deadcrew] (-[score_deadcrew * 25] Points)<BR>
<B>Uncleaned Messes:</B> [score_mess] (-[score_mess] Points)<BR>
<B>Station Power Issues:</B> [score_powerloss] (-[score_powerloss * 20] Points)<BR>
<B>Rampant Diseases:</B> [score_disease] (-[score_disease * 30] Points)<BR>
<B>AI Destroyed:</B> [score_deadaipenalty ? "Yes" : "No"] (-[score_deadaipenalty * 250] Points)<BR><BR>
<U>THE WEIRD</U><BR>
<B>Final Station Budget:</B> $[num2text(totalfunds,50)]<BR>"}
var/profit = totalfunds - 100000
if (profit > 0) dat += "<B>Station Profit:</B> +[num2text(profit,50)]<BR>"
else if (profit < 0) dat += "<B>Station Deficit:</B> [num2text(profit,50)]<BR>"
dat += {"<B>Food Eaten:</b> [score_foodeaten]<BR>
<B>Shots Fired:</B> [game_stats.GetStat("gunfire")]<BR>
<B>Times a Clown was Abused:</B> [score_clownabuse]<BR><BR>"}
if (score_escapees)
dat += {"<B>Richest Escapee:</B> [score_richestname], [score_richestjob]: $[num2text(score_richestcash,50)] ([score_richestkey])<BR>
<B>Most Battered Escapee:</B> [score_dmgestname], [score_dmgestjob]: [score_dmgestdamage] damage ([score_dmgestkey])<BR>"}
else
if (emergency_shuttle.location != 2) dat += "The station wasn't evacuated!<BR>"
else dat += "No-one escaped!<BR>"
if (score_allstock_html)
dat += "<B>Stock market top 5:</B><BR>[score_allstock_html]<BR><BR>"
dat += {"<HR><BR>
<B><U>FINAL SCORE: [score_crewscore]</U></B><BR>"}
var/score_rating = "The Aristocrats!"
switch(score_crewscore)
if(-99999 to -50000) score_rating = "Even the Engine Deserves Better"
if(-49999 to -5000) score_rating = "Engine Fodder"
if(-4999 to -1000) score_rating = "You're All Fired"
if(-999 to -500) score_rating = "A Waste of Perfectly Good Oxygen"
if(-499 to -250) score_rating = "A Wretched Heap of Scum and Incompetence"
if(-249 to -100) score_rating = "Outclassed by Lab Monkeys"
if(-99 to -21) score_rating = "The Undesirables"
if(-20 to 20) score_rating = "Ambivalently Average"
if(21 to 99) score_rating = "Not Bad, but Not Good"
if(100 to 249) score_rating = "Skillful Servants of Science"
if(250 to 499) score_rating = "Best of a Good Bunch"
if(500 to 999) score_rating = "Lean Mean Machine Thirteen"
if(1000 to 4999) score_rating = "Promotions for Everyone"
if(5000 to 9999) score_rating = "Ambassadors of Discovery"
if(10000 to 49999) score_rating = "The Pride of Science Itself"
if(50000 to INFINITY) score_rating = "NanoTrasen's Finest"
dat += "<B><U>RATING:</U></B> [score_rating]<BR>"
var/score_randomfact = "Somebody fucked something up."
var/factselector = rand(0,100)
if (factselector <= 30)
//Game and chat related facts. (0-30)
switch(factselector)
if(0 to 3) score_randomfact = "That game lasted [ (world.time) / 600] minutes."
if(4 to 7) score_randomfact = "[game_stats.GetStat("farts")] farts occurred during that game."
if(8 to 11) score_randomfact = "There were [game_stats.GetStat("violence")] acts of violence during that game."
if(12 to 15) score_randomfact = "[game_stats.GetStat("catches")] items were caught during that game."
if(16 to 18) score_randomfact = "[game_stats.GetStat("fornoreason")] people reportedly did something terrible 'for no reason' during that game."
if(19 to 22)
var/griefwrongsum = game_stats.GetStat("grife") + game_stats.GetStat("grif") + game_stats.GetStat("griff") + game_stats.GetStat("greif") + game_stats.GetStat("grief_other")
score_randomfact = "'Grief' was misspelled [griefwrongsum] times."
if(factselector > 20 && game_stats.GetStat("grief") > 0) score_randomfact += " Conversely, somebody got it right [game_stats.GetStat("grief")] times."
if(23 to 26) score_randomfact = "The AI was described using the French word for red a total of [game_stats.GetStat("rouge")] times."
if(27 to 30) score_randomfact = "The word 'verily' was uttered [game_stats.GetStat("verily")] times."
else if (factselector <= 60)
//Environment facts. (31-60)
if(factselector < 40)
//Monkeys!
var/fact_monkeycount = 0
var/fact_monkeysdead = 0
var/fact_monkeydiseases = 0
var/fact_monkeysescaped = 0
//Count all themonkeys.
for (var/mob/M in mobs)
if (!ismonkey(M))
continue
fact_monkeycount++
//Count the dead ones.
if (M.stat == 2) fact_monkeysdead++
//Count diseased ones.
if (M.ailments != null) fact_monkeydiseases++
//See how many escaped.
var/turf/location = get_turf(M.loc)
var/area/escape_zone = locate(/area/shuttle/escape/centcom)
if (location in escape_zone && M.stat != 2)
fact_monkeysescaped++
score_randomfact = "There were a total of [fact_monkeycount] monkeys in that game"
switch(factselector)
if(31 to 33) score_randomfact += "."
if(34 to 35) score_randomfact += ", [fact_monkeysdead] of them are dead."
if(36 to 37) score_randomfact += ", [fact_monkeydiseases] carried diseases."
if(38 to 39)
score_randomfact += ", [fact_monkeysescaped] safely made it to the escape shuttle. "
if (fact_monkeysescaped == 0) score_randomfact += "You monsters."
else if(factselector <= 50)
//Butts!
var/fact_butts = 0
for (var/obj/item/clothing/head/butt/B in world)
fact_butts++
score_randomfact = "There were [fact_butts] disembodied butts existing at the end of the round."
else
//Farts!
score_randomfact = "There were [game_stats.GetStat("farts")] farts during the round."
else
//Snail facts.
score_randomfact = pick("A snail can sleep for three years.",
"A snail can actually glide over the sharp edge of a knife or razor without harming itself. This has something to do with the mucus it produces.",
"A garden snail has thousands of tiny teeth located on a ribbon-like tongue. They work like a file and rip the food to bits.",
"Snails can gnaw through limestone. They eat the little bits of chalk in the rock which they need for their shells.",
"As a snail grows its shell grows too.",
"Snails can mate when they are about one year old.",
"Snails are hermaphrodites (one organism is both male and female). However, they need to exchange sperm with each other to reproduce.",
"Some snails can live up to 15 years.",
"Snails are gastropods, which means 'belly footed'.",
"Snails are one of around 50000 species of mollusc.",
"The largest land snail ever found was 15 inches long and weighed 2 pounds!",
"Snails rely mainly on touch and smell because they have very poor eyesight.",
"Snails cannot hear.",
"Snails are nocturnal animals which means they are more active at night.",
"The fastest snails are the speckled garden snails which can move up to 55 yards per hour compared 23 inches per hour of most other land snails.",
"Garden snails hibernate during the winter and live on their stored fat.",
"Garden snails breathe with lungs.",
"The largest land snail recorded was 12 inches long and weighed near 2 pounds.",
"Snails are nocturnal animals, which means most of their movements take place at night.",
"Snails don't like the brightness of sunlight, which is why you will find them out more on cloudy days.",
"Snails will die if you put salt on them.",
"The Giant African Land Snail is known to eat more than 500 different types of plants.",
"Snails are very strong and can lift up to 10 times their own body weight in a vertical position.",
"It is believed that there are at least 200,000 species of mollusks out there including snails. Although only 50,000 have been classified.")
dat += "<B>FACT: </B> [score_randomfact]"
src << browse(dat, "window=roundstats;size=500x650")
return
/mob/proc/showtickets()
if(!data_core.tickets.len && !data_core.fines.len) return
var/dat = {"<B>Tickets</B><BR><HR>"}
if(data_core.tickets.len)
var/list/people_with_tickets = list()
for (var/datum/ticket/T in data_core.tickets)
if(!(T.target in people_with_tickets))
people_with_tickets += T.target
for(var/N in people_with_tickets)
dat += "<b>[N]</b><br><br>"
for(var/datum/ticket/T in data_core.tickets)
if(T.target == N)
dat += "[T.text]<br>"
dat += "<br>"
else
dat += "No tickets were issued!<br><br>"
dat += {"<B>Fines</B><BR><HR>"}
if(data_core.fines.len)
var/list/people_with_fines = list()
for (var/datum/fine/F in data_core.fines)
if(!(F.target in people_with_fines))
people_with_fines += F.target
for(var/N in people_with_fines)
dat += "<b>[N]</b><br><br>"
for(var/datum/fine/F in data_core.fines)
if(F.target == N)
dat += "[F.target]: [F.amount] credits<br>Reason: [F.reason]<br>[F.approver ? "[F.issuer != F.approver ? "Requested by: [F.issuer] - [F.issuer_job]<br>Approved by: [F.approver] - [F.approver_job]" : "Issued by: [F.approver] - [F.approver_job]"]" : "Not Approved"]<br>Paid: [F.paid_amount] credits<br><br>"
else
dat += "No fines were issued!"
src << browse(dat, "window=roundstats;size=500x650")
return
+76
View File
@@ -0,0 +1,76 @@
/proc/setupgenetics()
//if (prob(50))
// BLOCKADD = rand(150,300)
if (prob(75))
DIFFMUT = rand(0,20)
var/list/avnums = new/list()
var/tempnum
avnums.Add(2)
avnums.Add(12)
avnums.Add(10)
avnums.Add(8)
avnums.Add(4)
avnums.Add(11)
avnums.Add(13)
avnums.Add(6)
tempnum = pick(avnums)
avnums.Remove(tempnum)
HULKBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
TELEBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
FIREBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
XRAYBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
CLUMSYBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
FAKEBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
DEAFBLOCK = tempnum
tempnum = pick(avnums)
avnums.Remove(tempnum)
BLINDBLOCK = tempnum
/proc/setup_radiocodes()
var/list/codewords = list("Alpha","Beta","Gamma","Zeta","Omega", "Bravo", "Epsilon", "Jeff", "Delta")
var/tempword = null
tempword = pick(codewords)
netpass_heads = "[rand(1111,9999)] [tempword]-[rand(111,999)]"
codewords -= tempword
tempword = pick(codewords)
netpass_security = "[rand(1111,9999)] [tempword]-[rand(111,999)]"
codewords -= tempword
tempword = pick(codewords)
netpass_medical = "[rand(1111,9999)] [tempword]-[rand(111,999)]"
codewords -= tempword
tempword = pick(codewords)
netpass_banking = "[rand(1111,9999)] [tempword]-[rand(111,999)]"
codewords -= tempword
tempword = pick(codewords)
netpass_cargo = "[rand(1111,9999)] [tempword]-[rand(111,999)]"
codewords -= tempword
tempword = pick(codewords)
netpass_syndicate = "[rand(111,999)]DET[tempword]=[rand(1111,9999)]"
codewords -= tempword
//boutput(world, "debug:<br>head: [netpass_heads] <br> med: [netpass_medical] <br> sec: [netpass_security]<br> atm: [netpass_banking]<br> cargo: [netpass_cargo]")
+130
View File
@@ -0,0 +1,130 @@
/client/proc/wiz_corruption()
set category = "Spells"
set name = "Corruption Ritual"
set desc="Pollutes an area with evil magic to please the dark gods."
if(usr.stat)
boutput(usr, "Not when you're incapacitated.")
return
var/area/getarea = get_area(usr)
if(!getarea)
boutput(usr, "Something went wrong with the ritual!")
return
if(getarea.name == "Space")
boutput(usr, "This spell will not work in the void!")
return
if(getarea.z != 1)
boutput(usr, "The dark gods do not desire this region of space.")
return
if(istype(getarea, /area/wizard_station) || istype(getarea, /area/syndicate_station)|| istype(getarea, /area/supply)|| istype(getarea, /area/shuttle/))
boutput(usr, "The dark gods do not desire this area of the station.")
return
if(getarea.corrupted)
boutput(usr, "This area is already corrupted!")
return
if(getarea.name == "Chapel" || getarea.name == "Chapel Office")
if (get_corruption_percent() < 40)
boutput(usr, "<span style=\"color:red\">You cannot cast spells on hallowed ground! Maybe if the station were more corrupted...</span>")
return
var/sizecount = 0
for(var/turf/simulated/floor/T in getarea)
sizecount++
for(var/mob/O in AIviewers(usr, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> begins to channel dark energy!</span>", usr), 1)
playsound(usr, 'sound/effects/chanting.ogg', 80, 1)
var/crpttime = sizecount
var/staystill = usr.loc
crpttime *= 1
if (!usr.wizard_spellpower())
boutput(usr, "<span style=\"color:red\">Without your enchanted gear, the ritual takes much longer!</span>")
crpttime *= 2
if (istype(usr.l_hand, /obj/item/staff/cthulhu)) crpttime /= 6
else if (istype(usr.r_hand, /obj/item/staff/cthulhu)) crpttime /= 6
crpttime /= 5
boutput(usr, "It will take [crpttime] seconds to finish the ritual.")
var/list/chant = list("Kali ma...","Klaatu barada nikto...","Ia ia Fthaghn...")
for(var/Ti = crpttime, Ti > 0, Ti--)
if (usr.loc != staystill || usr.stat || usr.stunned || usr.paralysis || usr.weakened)
boutput(usr, "<span style=\"color:red\">You lose your concentration!</span>")
return
if (prob(8)) usr.say(pick(chant))
sleep(10)
getarea.areacorrupt()
boutput(usr, "You finish the ritual.")
/proc/get_total_corruptible_terrain()
var/list/ignoreareas = list("Space","Arrival Shuttle","Emergency Shuttle","Supply Shuttle","Fore Solar Array","Aft Solar Array","Port Solar Array","Starboard Solar Array","Wizard's Den","Syndicate Station")
var/turfcount = 0
for(var/turf/simulated/floor/T in world)
if(T.z != 1) continue
if(T.loc.name in ignoreareas) continue
turfcount++
var/percentage
percentage = (turfcount * 0.4)
logTheThing("debug", null, null, "<b>I Said No/Corruptible Terrain:</b> Found [turfcount] corruptible terrains, 40% corruption is [percentage]")
return turfcount
/proc/get_corruption_percent()
/* Hello, this proc is called a billion times by wizard shit. Do not iterate through all turfs in the world with it tia
var/corrupt = 0
for(var/turf/simulated/floor/T in world)
if(T.z != 1) continue
if(T.loc:corrupted) corrupt++
*/
var/percentage = round((total_corrupted_terrain / total_corruptible_terrain) * 100, 0.25)
return percentage
/client/proc/sense_corruption()
set category = "Spells"
set name = "Sense Corruption"
set desc="Tells you what percentage of the station is corrupted with dark magic."
var/corrupt = get_corruption_percent()
boutput(usr, "<b>[corrupt]%</b> of the station has been corrupted.")
/client/proc/remove_corruption()
set category = "Spells"
set name = "Prayer"
set desc="Clears dark magic corruption from an area."
if(usr.stat)
boutput(usr, "Not when you're incapacitated.")
return
var/area/getarea = get_area(usr)
if(!getarea)
boutput(usr, "Something went wrong with the prayer!")
return
if(getarea.name == "Space")
boutput(usr, "This spell will not work in space!")
return
if(!getarea.corrupted)
boutput(usr, "This area is not corrupted!")
return
var/sizecount = 0
for(var/turf/simulated/floor/T in getarea)
sizecount++
for(var/mob/O in AIviewers(usr, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> closes \his eyes and begins to pray!</span>", usr), 1)
var/crpttime = sizecount
var/staystill = usr.loc
crpttime *= 1
crpttime /= 6
boutput(usr, "It will take [crpttime] seconds to finish purifying this area.")
for(var/Ti = crpttime, Ti > 0, Ti--)
if (usr.loc != staystill || usr.stat || usr.stunned || usr.paralysis || usr.weakened)
boutput(usr, "<span style=\"color:red\">You lose your concentration!</span>")
return
sleep(10)
getarea.areauncorrupt()
boutput(usr, "You finish the ritual.")
playsound(usr, 'sound/effects/heavenly.ogg', 80, 1)
+253
View File
@@ -0,0 +1,253 @@
/////////FOR LOGGING TO STATS FILE/////////
//Called in tickets New() in datacore.dm
/proc/statlog_ticket(var/datum/ticket/T, var/mob/living/M)
var/message[] = new()
message["data_type"] = "tickets"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["target"] = T.target
message["reason"] = T.reason
message["issuer"] = M.real_name
message["issuer_job"] = M.job
message["target_byond_key"] = T.target_byond_key
message["issuer_byond_key"] = M.key
hublog << list2params(message)
//Called in fines New() in datacore.dm
/proc/statlog_fine(var/datum/fine/F, var/mob/living/M)
var/message[] = new()
message["data_type"] = "fines"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["byond_uid"] = F.ID
message["target"] = F.target
message["reason"] = F.reason
message["issuer"] = M.real_name
message["issuer_job"] = M.job
message["amount"] = F.amount
message["target_byond_key"] = F.target_byond_key
message["issuer_byond_key"] = M.key
hublog << list2params(message)
//Called in crittergauntlet.dm
/proc/statlog_gauntlet(var/mobs, var/final_score, var/last_completed_wave)
if (final_score == 0 && last_completed_wave < 2)
return
var/message[] = new()
message["data_type"] = "gauntlet_high_scores"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["names"] = mobs
message["score"] = final_score
message["highest_wave"] = last_completed_wave
hublog << list2params(message)
//Called in living death() in living.dm
/proc/statlog_death(var/mob/living/M,var/gibbed)
var/message[] = new()
message["data_type"] = "deaths"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["mob_name"] = M.real_name
message["mob_job"] = M.job
message["mob_byond_key"] = M.key
var/atom/T = get_turf(M)
if (!T) T = M
message["x"] = T.x
message["y"] = T.y
message["z"] = T.z
message["bruteloss"] = M.get_brute_damage()
message["fireloss"] = M.get_burn_damage()
message["toxloss"] = M.get_toxin_damage()
message["oxyloss"] = M.get_oxygen_deprivation()
message["gibbed"] = gibbed ? 1 : 0
hublog << list2params(message)
//Called in syndicate and integrated Topic() in uplinks.dm
/proc/statlog_traitor_item(var/mob/living/M, var/itemIdentifier, var/cost)
if (!istype(M))
return 1
var/message[] = new()
message["data_type"] = "traitor_items"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["mob_name"] = M.real_name
message["mob_job"] = M.job
message["mob_byond_key"] = M.key
var/atom/T = get_turf(M)
if (!T) T = M
message["x"] = T.x
message["y"] = T.y
message["z"] = T.z
message["item"] = itemIdentifier ? itemIdentifier : "???"
message["cost"] = isnum(cost) ? "[cost]" : "0"
hublog << list2params(message)
//Called in gameticker.dm in proc/declare_completion
/proc/statlog_traitors()
var/list/datum/mind/traitors = get_all_enemies()
for (var/datum/mind/M in traitors)
var/message[] = new()
message["data_type"] = "traitors"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["mob_name"] = M.current.real_name
message["mob_job"] = M.current.job
message["mob_byond_key"] = M.key
if (M.objectives)
var/overallSuccess = 1
var/count = 1
for(var/datum/objective/objective in M.objectives)
#ifdef CREW_OBJECTIVES
if (istype(objective, /datum/objective/crew)) continue
#endif
message["objective[count]"] = objective.explanation_text
if(objective.check_completion())
message["success[count]"] = 1
else
message["success[count]"] = 0
overallSuccess = 0
count++
message["success"] = overallSuccess
message["objective_count"] = count - 1
var/traitor_type = M.special_role
message["traitor_type"] = traitor_type
var/special
switch(traitor_type)
if ("changeling")
if (M.current)
var/datum/abilityHolder/changeling/C = M.current.get_ability_holder(/datum/abilityHolder/changeling)
if (C && istype(C))
special = C.absorbtions
if ("vampire")
if (M.current)
special = M.current.get_vampire_blood(1)
if ("wizard")
if (M.current)
var/datum/abilityHolder/wizard/W = M.current.get_ability_holder(/datum/abilityHolder/wizard)
if (W && istype(W))
var/spells = ""
for (var/datum/targetable/spell/S in W.abilities)
if (spells != "")
spells += ", "
spells += S.name
if ("werewolf")
for (var/datum/objective/specialist/werewolf/feed/O in M.objectives)
if (O && istype(O, /datum/objective/specialist/werewolf/feed/))
special = O.mobs_fed_on.len
if ("vampthrall")
if (M.master)
var/mob/mymaster = whois_ckey_to_mob_reference(M.master)
if (mymaster) special = mymaster.real_name
if ("spyslave")
if (M.master)
var/mob/mymaster = whois_ckey_to_mob_reference(M.master)
if (mymaster) special = mymaster.real_name
if ("mindslave")
if (M.master)
var/mob/mymaster = whois_ckey_to_mob_reference(M.master)
if (mymaster) special = mymaster.real_name
if ("nukeop")
if (istype(ticker.mode, /datum/game_mode/nuclear))
special = syndicate_name()
if (ticker.mode:nuke_detonated)
message["success"] = 1
message["special"] = special
if (M.late_special_role)
message["late_joiner"] = 1
/*else if (M.random_event_special_role)
message["random_event"] = 1*/
else
message["late_joiner"] = 0
//message["random_event"] = 0
hublog << list2params(message)
//BEES
/proc/statlog_bees(var/obj/critter/domestic_bee/B)
var/message[] = new()
message["data_type"] = "bees"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["name"] = B.name
if(B.beeMom)
message["mom"] = B.beeMom.real_name
hublog << list2params(message)
//Called in gameticker.dm at proc/declare_completion, ai_laws.dm at set_zeroth_law and add_supplied_law
/proc/statlog_ailaws(var/during, var/law, adder)
//For individual laws
if (during)
var/message[] = new()
message["data_type"] = "ai_laws"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
if (ismob(adder))
var/mob/M = adder
message["uploader_name"] = M.real_name
message["uploader_key"] = M.key
message["uploader_job"] = M.job
else
message["uploader_name"] = "Ion Storm"
message["uploader_key"] = "Random Event"
message["uploader_job"] = ""
message["type"] = "during"
message["law_text"] = html_decode(law)
hublog << list2params(message)
return 1
//For end of round laws
else
for (var/mob/living/silicon/ai/aiPlayer in mobs)
var/laws[] = new()
if (ticker.centralized_ai_laws.zeroth)
laws["0"] = ticker.centralized_ai_laws.zeroth
var/list/suppliedLaws = ticker.centralized_ai_laws.supplied
var/count = 4
for (var/i = 1, i <= suppliedLaws.len, i++)
var/lawText = suppliedLaws[i]
if (length(lawText) > 0)
laws["[count]"] = lawText
count++
for (var/key in laws)
var/message[] = new()
message["data_type"] = "ai_laws"
message["data_status"] = "insert"
message["data_timestamp"] = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
message["ai_name"] = aiPlayer.real_name
message["ai_key"] = aiPlayer.key
message["type"] = "end"
message["law_number"] = key
message["law_text"] = html_decode(laws[key])
hublog << list2params(message)
return 1
+75
View File
@@ -0,0 +1,75 @@
/*
Hello good coder sir!
Recently the quality of these lists went down, like WAY DOWN.
The only things that should be in the random name lists are
science fiction themed things and references to
existing science fiction media (movies, books, etc).
If you wish to add anything else, FUCK YOU AND DIE.
(and don't add it)
-Rick
*/
/proc/station_name()
if (station_name)
return station_name
var/name = ""
//halloween prefixes, temporary thing
#ifdef HALLOWEEN
name += pick_string("station_name.txt", "halloweenPrefixes")
name += " "
#endif
if (map_setting == "DESTINY")
name += "NSS Destiny"
else
if (prob(10))
name += pick_string("station_name.txt", "prefixes1")
name += pick("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Ceres", "Pluto", "Haumea", "Makemake", "Eris", "Luna", "engineering", "Gen", "gen", "Co", "You", "Galactic", "Node", "Capital", "Moon", "Main", "Labs", "Lab", "trasen", "tum")
else if (prob(10))
name += pick_string("station_name.txt", "prefixes2")
name += " "
// Prefix
name += pick_string("station_name.txt", "prefixes3")
if (name)
name += " "
// Suffix
name += pick_string("station_name.txt", "suffixes")
name += " "
// ID Number
if (prob(40))
name += "[rand(1, 99)]"
else if (prob(5))
name += "3000"
else if (prob(5))
name += "9000"
else if (prob(5))
name += "14000000000"
else if (prob(5))
name += "205[pick(1, 3)]"
else if (prob(50))
name += pick_string("station_name.txt", "greek")
else if (prob(30))
name += pick_string("station_name.txt", "romanNum")
else if (prob(40))
name += pick_string("station_name.txt", "militaryLetters")
else
name += pick_string("station_name.txt", "numbers")
station_name = name
if (config && config.server_name)
world.name = "[config.server_name]: [name]"
else
world.name = name
return name
+32
View File
@@ -0,0 +1,32 @@
var/global/list/string_cache
/proc/strings(filename as text, key as text, var/accept_absent = 0)
var/list/fileList
if(!string_cache)
string_cache = new
if(!(filename in string_cache))
if(fexists("strings/[filename]"))
string_cache[filename] = list()
var/list/stringsList = list()
fileList = dd_file2list("strings/[filename]")
var/lineCount = 0
for(var/s in fileList)
lineCount++
if (!s)
continue
stringsList = dd_text2list(s, "@=")
if(stringsList.len != 2)
CRASH("Invalid string list in strings/[filename] - line: [lineCount]")
if(findtext(stringsList[2], "@,"))
string_cache[filename][stringsList[1]] = dd_text2list(stringsList[2], "@,")
else
string_cache[filename][stringsList[1]] = stringsList[2] // Its a single string!
else
CRASH("file not found: strings/[filename]")
if((filename in string_cache) && (key in string_cache[filename]))
return string_cache[filename][key]
else if (accept_absent) //Don't crash, just return null. It's fine. Honest
return null
else
CRASH("strings list not found: strings/[filename], index=[key]")
File diff suppressed because it is too large Load Diff
+107
View File
@@ -0,0 +1,107 @@
/client/proc/waldo_decoys()
set category = "Spells"
set name = "Summon Decoys"
set desc = "Conjures up a distraction while you make a getaway."
if(usr.stat)
boutput(usr, "Not when you're incapacitated.")
return
usr.say("Now you see me, now you don't! Heh!")
var/list/turfs = new/list()
for(var/turf/T in orange(6))
if(istype(T,/turf/space)) continue
if(T.density) continue
if(T.x>world.maxx-4 || T.x<4) continue //putting them at the edge is dumb
if(T.y>world.maxy-4 || T.y<4) continue
turfs += T
if(!turfs.len) turfs += pick(/turf in orange(6))
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
smoke.set_up(10, 0, usr.loc)
smoke.start()
for(var/turf/T in range(1))
spawn(0)
new /mob/living/carbon/human/fake_waldo(T)
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
usr.set_loc(picked)
usr.verbs -= /client/proc/waldo_decoys
spawn(300)
usr.verbs += /client/proc/waldo_decoys
/client/proc/mass_teleport()
set category = "Spells"
set name = "Mass Teleport"
set desc = "Teleport yourself and your friends to an area of your choice."
if(usr.stat)
boutput(usr, "Not when you're incapacitated.")
return
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe))
boutput(usr, "You don't feel strong enough without a magical robe.")
return
if(!istype(usr:head, /obj/item/clothing/head/wizard))
boutput(usr, "You don't feel strong enough without a magical hat.")
return
var/SPcool = 3000
if (usr.wizard_spellpower()) SPcool = 600
var/A
usr.verbs -= /client/proc/mass_teleport
spawn(SPcool)
usr.verbs += /client/proc/mass_teleport
var/list/theareas = new/list()
for(var/area/AR in world)
if(theareas.Find(AR.name)) continue
var/turf/picked = pick(get_area_turfs(AR.type))
if (picked.z == usr.z)
theareas += AR.name
theareas[AR.name] = AR
A = input("Area to jump to", "BOOYEA", A) in theareas
var/area/thearea = theareas[A]
var/atom/movable/overlay/animation = null
usr.buckled = usr.loc
animation = new(usr.loc)
animation.icon_state = "enshield"
animation.icon = 'icons/effects/effects.dmi'
animation.master = usr
sleep(30)
qdel(animation)
usr.buckled = null
if(!usr.stat)
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
smoke.set_up(5, 0, usr.loc)
smoke.attach(usr)
smoke.start()
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
if(T.z != usr.z) continue
if(!T.density)
var/clear = 1
for(var/obj/O in T)
if(O.density)
clear = 0
break
if(clear)
L+=T
var/list/mob/teleportees = list()
for(var/mob/living/M in orange(usr, 4))
if(M.stat != 2 && M.mind && (M.mind.special_role in list("waldo", "odlaw", "wizard")))
teleportees.Add(M)
usr.set_loc(pick(L))
var/list/turf/dest_turfs = list()
for(var/turf/T in orange(usr, 1))
if(T.density) continue
dest_turfs.Add(T)
for(var/mob/M in teleportees)
M.set_loc(pick(dest_turfs))
smoke.start()