mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-29 08:56:16 +01:00
Initial Commit
This commit is contained in:
@@ -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
|
||||
@@ -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/>
|
||||
*/
|
||||
@@ -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(
|
||||
"̍", "̎", "̄", "̅",
|
||||
"̿", "̑", "̆", "̐",
|
||||
"͒", "͗", "͑", "̇",
|
||||
"̈", "̊", "͂", "̓",
|
||||
"̈́", "͊", "͋", "͌",
|
||||
"̃", "̂", "̌", "͐",
|
||||
"̀", "́", "̋", "̏",
|
||||
"̒", "̓", "̔", "̽",
|
||||
"̉", "ͣ", "ͤ", "ͥ",
|
||||
"ͦ", "ͧ", "ͨ", "ͩ",
|
||||
"ͪ", "ͫ", "ͬ", "ͭ",
|
||||
"ͮ", "ͯ", "̾", "͛",
|
||||
"͆", "̚"
|
||||
)
|
||||
|
||||
//those go DOWN
|
||||
var/list/zalgo_down = list(
|
||||
"̖", "̗", "̘", "̙",
|
||||
"̜", "̝", "̞", "̟",
|
||||
"̠", "̤", "̥", "̦",
|
||||
"̩", "̪", "̫", "̬",
|
||||
"̭", "̮", "̯", "̰",
|
||||
"̱", "̲", "̳", "̹",
|
||||
"̺", "̻", "̼", "ͅ",
|
||||
"͇", "͈", "͉", "͍",
|
||||
"͎", "͓", "͔", "͕",
|
||||
"͖", "͙", "͚", "̣"
|
||||
)
|
||||
|
||||
//those always stay in the middle
|
||||
var/list/zalgo_mid = list(
|
||||
"̕", "̛", "̀", "́",
|
||||
"͘", "̡", "̢", "̧",
|
||||
"̨", "̴", "̵", "̶",
|
||||
"͏", "͜", "͝", "͞",
|
||||
"͟", "͠", "͢", "̸",
|
||||
"̷", "͡", "҉"
|
||||
)
|
||||
|
||||
/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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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)]")
|
||||
@@ -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)
|
||||
@@ -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
@@ -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")
|
||||
@@ -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)
|
||||
@@ -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
@@ -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)
|
||||
@@ -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
|
||||
@@ -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]°C ([M.bodytemperature * 1.8-459.67]°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> <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 = " <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>\
|
||||
  Overall Status: [death_state > 1 ? "<span style='color:red'>DEAD</span>" : "[colored_health]% healthy"]<br>\
|
||||
  Damage Specifics: [oxy_data] - [tox_data] - [burn_data] - [brute_data]<br>\
|
||||
  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> [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]°C ([A.reagents.total_temperature * 1.8-459.67]°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)]°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)]°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)]°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
|
||||
@@ -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
|
||||
@@ -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]")
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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()
|
||||
Reference in New Issue
Block a user