mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-31 07:58:22 +01:00
Merge branch 'master' into oldTurrets
This commit is contained in:
@@ -36,8 +36,6 @@ obj/machinery/atmospherics/mains_pipe
|
||||
icon = 'icons/obj/atmospherics/mainspipe.dmi'
|
||||
layer = 2.4 //under wires with their 2.5
|
||||
|
||||
force = 20
|
||||
|
||||
var/volume = 0
|
||||
|
||||
var/alert_pressure = 80*ONE_ATMOSPHERE
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke
|
||||
var/datum/pipeline/parent
|
||||
var/volume = 0
|
||||
force = 20
|
||||
|
||||
layer = 2.4 //under wires with their 2.44
|
||||
use_power = 0
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ mob/check_airflow_movable(n)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
mob/dead/observer/check_airflow_movable()
|
||||
mob/observer/check_airflow_movable()
|
||||
return 0
|
||||
|
||||
mob/living/silicon/check_airflow_movable()
|
||||
@@ -247,6 +247,6 @@ zone/proc/movables()
|
||||
. = list()
|
||||
for(var/turf/T in contents)
|
||||
for(var/atom/movable/A in T)
|
||||
if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/eye))
|
||||
if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/observer))
|
||||
continue
|
||||
. += A
|
||||
|
||||
@@ -348,7 +348,7 @@ var/global/vs_control/vsc = new
|
||||
else if(istext(vars["[V]_RANDOM"]))
|
||||
var/txt = vars["[V]_RANDOM"]
|
||||
if(findtextEx(txt,"PROB"))
|
||||
txt = text2list(txt,"/")
|
||||
txt = splittext(txt,"/")
|
||||
txt[1] = replacetext(txt[1],"PROB","")
|
||||
var/p = text2num(txt[1])
|
||||
var/r = txt[2]
|
||||
@@ -358,7 +358,7 @@ var/global/vs_control/vsc = new
|
||||
newvalue = vars[V]
|
||||
else if(findtextEx(txt,"PICK"))
|
||||
txt = replacetext(txt,"PICK","")
|
||||
txt = text2list(txt,",")
|
||||
txt = splittext(txt,",")
|
||||
newvalue = pick(txt)
|
||||
else
|
||||
newvalue = roll(txt)
|
||||
|
||||
@@ -63,7 +63,6 @@ var/list/be_special_flags = list(
|
||||
|
||||
// Mode/antag template macros.
|
||||
#define MODE_BORER "borer"
|
||||
#define MODE_XENOMORPH "xeno"
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MUTINEER "mutineer"
|
||||
#define MODE_COMMANDO "commando"
|
||||
@@ -82,6 +81,7 @@ var/list/be_special_flags = list(
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MALFUNCTION "malf"
|
||||
#define MODE_TRAITOR "traitor"
|
||||
#define MODE_AUTOTRAITOR "autotraitor"
|
||||
|
||||
#define DEFAULT_TELECRYSTAL_AMOUNT 12
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Species flags.
|
||||
#define NO_MINOR_CUT 0x1 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows)
|
||||
#define NO_MINOR_CUT 0x1 // Can step on broken glass with no ill-effects. Either thick skin (diona), cut resistant (slimes) or incorporeal (shadows)
|
||||
#define IS_PLANT 0x2 // Is a treeperson.
|
||||
#define NO_SCAN 0x4 // Cannot be scanned in a DNA machine/genome-stolen.
|
||||
#define NO_PAIN 0x8 // Cannot suffer halloss/recieves deceptive health indicator.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#if DM_VERSION < 510
|
||||
|
||||
json_token
|
||||
var
|
||||
value
|
||||
@@ -202,4 +204,6 @@ json_reader
|
||||
|
||||
die(json_token/T)
|
||||
if(!T) T = get_token()
|
||||
CRASH("Unexpected token: [T.value].")
|
||||
CRASH("Unexpected token: [T.value].")
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,5 @@
|
||||
#if DM_VERSION < 510
|
||||
|
||||
json_writer
|
||||
var
|
||||
use_cache = 0
|
||||
@@ -48,7 +50,7 @@ json_writer
|
||||
var/lrep = length(json_escape[targ])
|
||||
txt = copytext(txt, 1, i) + json_escape[targ] + copytext(txt, i + length(targ))
|
||||
start = i + lrep
|
||||
|
||||
|
||||
return {""[txt]""}
|
||||
|
||||
is_associative(list/L)
|
||||
@@ -56,3 +58,5 @@ json_writer
|
||||
// if the key is a list that means it's actually an array of lists (stupid Byond...)
|
||||
if(!isnum(key) && !isnull(L[key]) && !istype(key, /list))
|
||||
return TRUE
|
||||
|
||||
#endif
|
||||
@@ -1,17 +1,14 @@
|
||||
#if DM_VERSION < 510
|
||||
/*
|
||||
n_Json v11.3.21
|
||||
*/
|
||||
|
||||
proc
|
||||
json2list(json)
|
||||
json_decode(json)
|
||||
var/static/json_reader/_jsonr = new()
|
||||
return _jsonr.ReadObject(_jsonr.ScanJson(json))
|
||||
|
||||
list2json(list/L)
|
||||
json_encode(list/L)
|
||||
var/static/json_writer/_jsonw = new()
|
||||
return _jsonw.write(L)
|
||||
|
||||
list2json_usecache(list/L)
|
||||
var/static/json_writer/_jsonw = new()
|
||||
_jsonw.use_cache = 1
|
||||
return _jsonw.write(L)
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
#if DM_VERSION < 510
|
||||
|
||||
/proc/replacetext(text, find, replacement)
|
||||
return jointext(splittext(text, find), replacement)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,102 @@
|
||||
#if DM_VERSION < 510
|
||||
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
|
||||
/proc/jointext(list/ls, sep)
|
||||
if (ls.len <= 1) // Early-out code for empty or singleton lists.
|
||||
return ls.len ? ls[1] : ""
|
||||
|
||||
var/l = ls.len // Made local for sanic speed.
|
||||
var/i = 0 // Incremented every time a list index is accessed.
|
||||
|
||||
if (sep <> null)
|
||||
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
|
||||
#define S1 sep, ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][][][][][]", ., S4) // And so on....
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
else
|
||||
// Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc...
|
||||
#define S1 ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][]", ., S4) // And so on...
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
|
||||
// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
|
||||
/proc/splittext(text, delimiter="\n")
|
||||
var/delim_len = length(delimiter)
|
||||
if (delim_len < 1)
|
||||
return list(text)
|
||||
|
||||
. = list()
|
||||
var/last_found = 1
|
||||
var/found
|
||||
|
||||
do
|
||||
found = findtext(text, delimiter, last_found, 0)
|
||||
. += copytext(text, last_found, found)
|
||||
last_found = found + delim_len
|
||||
while (found)
|
||||
#endif
|
||||
@@ -244,7 +244,7 @@
|
||||
var/turf/ear = get_turf(M)
|
||||
if(ear)
|
||||
// Ghostship is magic: Ghosts can hear radio chatter from anywhere
|
||||
if(speaker_coverage[ear] || (istype(M, /mob/dead/observer) && (M.client) && (M.client.prefs.toggles & CHAT_GHOSTRADIO)))
|
||||
if(speaker_coverage[ear] || (istype(M, /mob/observer/dead) && (M.client) && (M.client.prefs.toggles & CHAT_GHOSTRADIO)))
|
||||
. |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down.
|
||||
return .
|
||||
|
||||
@@ -323,7 +323,7 @@ proc/isInSight(var/atom/A, var/atom/B)
|
||||
var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
|
||||
var/i = 0
|
||||
while(candidates.len <= 0 && i < 5)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
for(var/mob/observer/dead/G in player_list)
|
||||
if(((G.client.inactivity/10)/60) <= buffer + i) // the most active players are more likely to become an alien
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
candidates += G.key
|
||||
@@ -337,7 +337,7 @@ proc/isInSight(var/atom/A, var/atom/B)
|
||||
var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
|
||||
var/i = 0
|
||||
while(candidates.len <= 0 && i < 5)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
for(var/mob/observer/dead/G in player_list)
|
||||
if(G.client.prefs.be_special & BE_ALIEN)
|
||||
if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
|
||||
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
|
||||
|
||||
@@ -46,13 +46,18 @@ var/global/list/facial_hair_styles_male_list = list()
|
||||
var/global/list/facial_hair_styles_female_list = list()
|
||||
var/global/list/skin_styles_female_list = list() //unused
|
||||
//Underwear
|
||||
var/global/list/underwear_m = list(
|
||||
"White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6",
|
||||
"Boxers Heart" = "m7", "Boxers Black" = "m8", "Boxers Grey" = "m9", "Boxers Stripe" = "m10", "None") //Curse whoever made male/female underwear diffrent colours
|
||||
var/global/list/underwear_f = list(
|
||||
"Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6",
|
||||
"Black Sports" = "f7","White Sports" = "f8", "Black Sports Alt" = "f9", "White Sports Alt" = "f10", "Baby Blue" = "f11", "Green" = "f12", "Pink" = "f13",
|
||||
"Violet" = "f14", "Thong Alt" = "f15", "Thong Alt Violet" = "f16", "None")
|
||||
var/global/list/underwear_top_t = list(
|
||||
"Bra, Red" = "t1", "Bra, White" = "t2", "Bra, Yellow" = "t3", "Bra, Blue" = "t4", "Bra, Black" = "t5", "Lacy Bra" = "t6", "Sports Bra, Black" = "t7", "Sports Bra, White" = "t8",
|
||||
"Sports Bra Alt, Black" = "t9", "Sporta Bra Alt, White" = "t10", "Bra, Baby-Blue" = "t11", "Bra, Green" = "t12", "Bra, Pink" = "t13", "Bra, Violet" = "t14",
|
||||
"Lacy Bra Alt" = "t15", "Lacy Bra Alt, Violet" = "t16", "Halterneck Bra, Black" = "t17", "Halterneck Bra, Blue" = "t18", "Halterneck Bra, Green" = "t19", "Halterneck Bra, Purple" = "t20",
|
||||
"Halterneck Bra, Red" = "t21", "Halterneck Bra, Teal" = "t22", "Halterneck Bra, Violet" = "t23", "Halterneck Bra, White" = "t24", "None")
|
||||
var/global/list/underwear_bottom_t = list(
|
||||
"Briefs, White" = "b1", "Briefs, Grey" = "b2", "Briefs, Green" = "b3", "Briefs, Blue" = "b4", "Briefs, Black" = "b5", "Boxers, Loveheart" = "b7", "Boxers, Black" = "b8",
|
||||
"Boxers, Grey" = "b9", "Boxers, Green & Blue Striped" = "b10", "Panties, Red" = "b11", "Panties, White" = "b12", "Panties, Yellow" = "b13", "Panties, Blue" = "b14",
|
||||
"Panties, Light-Black" = "b15", "Thong" = "b16", "Panties, Black" = "b17", "Panties Alt, White" = "b18", "Compression Shorts, Black" = "b19", "Compression Shorts, White" = "b20",
|
||||
"Compression Shorts, Baby-Blue" = "b21", "Panties, Green" = "b22", "Compression Shorts, Pink" = "b23", "Thong, Violet" = "b24", "Thong Alt" = "b25", "Thong Alt, Violet" = "b26",
|
||||
"Alt Thong, Black" = "b27", "Alt Thong, Blue" = "b28", "Alt Thong, Green" = "b29", "Alt Thong, Purple" = "b30", "Alt Thong, Red" = "b31", "Alt Thong, Teal" = "b32",
|
||||
"Alt Thong, Violet" = "b33", "Alt Thong, White" = "b34", "None")
|
||||
//undershirt
|
||||
var/global/list/undershirt_t = list(
|
||||
"White tank top" = "u1", "Black tank top" = "u2", "Black shirt" = "u3",
|
||||
|
||||
@@ -48,9 +48,7 @@ proc/listgetindex(var/list/list,index)
|
||||
return
|
||||
|
||||
proc/islist(list/list)
|
||||
if(istype(list))
|
||||
return 1
|
||||
return 0
|
||||
return(istype(list))
|
||||
|
||||
//Return either pick(list) or null if list is not of type /list or is empty
|
||||
proc/safepick(list/list)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/atom/movable/proc/get_mob()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/get_mob()
|
||||
if(load && istype(load,/mob/living))
|
||||
return load
|
||||
|
||||
/obj/mecha/get_mob()
|
||||
return occupant
|
||||
|
||||
@@ -14,6 +10,11 @@
|
||||
/mob/get_mob()
|
||||
return src
|
||||
|
||||
/mob/living/bot/mulebot/get_mob()
|
||||
if(load && istype(load, /mob/living))
|
||||
return list(src, load)
|
||||
return src
|
||||
|
||||
/proc/mobs_in_view(var/range, var/source)
|
||||
var/list/mobs = list()
|
||||
for(var/atom/movable/AM in view(range, source))
|
||||
|
||||
@@ -175,13 +175,6 @@
|
||||
/*
|
||||
* Text modification
|
||||
*/
|
||||
|
||||
/proc/replacetext(text, find, replacement)
|
||||
return list2text(text2list(text, find), replacement)
|
||||
|
||||
/proc/replacetextEx(text, find, replacement)
|
||||
return list2text(text2listEx(text, find), replacement)
|
||||
|
||||
/proc/replace_characters(var/t,var/list/repl_chars)
|
||||
for(var/char in repl_chars)
|
||||
t = replacetext(t, char, repl_chars[char])
|
||||
|
||||
+2
-128
@@ -50,141 +50,15 @@
|
||||
while (left-- > 0)
|
||||
. = "0[.]"
|
||||
|
||||
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
|
||||
/proc/list2text(list/ls, sep)
|
||||
if (ls.len <= 1) // Early-out code for empty or singleton lists.
|
||||
return ls.len ? ls[1] : ""
|
||||
|
||||
var/l = ls.len // Made local for sanic speed.
|
||||
var/i = 0 // Incremented every time a list index is accessed.
|
||||
|
||||
if (sep <> null)
|
||||
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
|
||||
#define S1 sep, ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][][][][][]", ., S4) // And so on....
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
else
|
||||
// Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc...
|
||||
#define S1 ls[++i]
|
||||
#define S4 S1, S1, S1, S1
|
||||
#define S16 S4, S4, S4, S4
|
||||
#define S64 S16, S16, S16, S16
|
||||
|
||||
. = "[ls[++i]]" // Make sure the initial element is converted to text.
|
||||
|
||||
if (l-1 & 0x01) // 'i' will always be 1 here.
|
||||
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
|
||||
if (l-i & 0x02)
|
||||
. = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
|
||||
if (l-i & 0x04)
|
||||
. = text("[][][][][]", ., S4) // And so on...
|
||||
if (l-i & 0x08)
|
||||
. = text("[][][][][][][][][]", ., S4, S4)
|
||||
if (l-i & 0x10)
|
||||
. = text("[][][][][][][][][][][][][][][][][]", ., S16)
|
||||
if (l-i & 0x20)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
|
||||
if (l-i & 0x40)
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
|
||||
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
|
||||
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
|
||||
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
|
||||
|
||||
#undef S64
|
||||
#undef S16
|
||||
#undef S4
|
||||
#undef S1
|
||||
|
||||
// Slower then list2text, but correctly processes associative lists.
|
||||
proc/tg_list2text(list/list, glue=",")
|
||||
if (!istype(list) || !list.len)
|
||||
return
|
||||
var/output
|
||||
for(var/i=1 to list.len)
|
||||
output += (i!=1? glue : null)+(!isnull(list["[list[i]]"])?"[list["[list[i]]"]]":"[list[i]]")
|
||||
return output
|
||||
|
||||
// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
|
||||
/proc/text2list(text, delimiter="\n")
|
||||
var/delim_len = length(delimiter)
|
||||
if (delim_len < 1)
|
||||
return list(text)
|
||||
|
||||
. = list()
|
||||
var/last_found = 1
|
||||
var/found
|
||||
|
||||
do
|
||||
found = findtext(text, delimiter, last_found, 0)
|
||||
. += copytext(text, last_found, found)
|
||||
last_found = found + delim_len
|
||||
while (found)
|
||||
|
||||
// Case sensitive version of /proc/text2list().
|
||||
/proc/text2listEx(text, delimiter="\n")
|
||||
var/delim_len = length(delimiter)
|
||||
if (delim_len < 1)
|
||||
return list(text)
|
||||
|
||||
. = list()
|
||||
var/last_found = 1
|
||||
var/found
|
||||
|
||||
do
|
||||
found = findtextEx(text, delimiter, last_found, 0)
|
||||
. += copytext(text, last_found, found)
|
||||
last_found = found + delim_len
|
||||
while (found)
|
||||
|
||||
/proc/text2numlist(text, delimiter="\n")
|
||||
var/list/num_list = list()
|
||||
for(var/x in text2list(text, delimiter))
|
||||
for(var/x in splittext(text, delimiter))
|
||||
num_list += text2num(x)
|
||||
return num_list
|
||||
|
||||
// Splits the text of a file at seperator and returns them in a list.
|
||||
/proc/file2list(filename, seperator="\n")
|
||||
return text2list(return_file_text(filename),seperator)
|
||||
return splittext(return_file_text(filename),seperator)
|
||||
|
||||
// Turns a direction into text
|
||||
/proc/num2dir(direction)
|
||||
|
||||
@@ -462,7 +462,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
if (M.real_name && M.real_name != M.name)
|
||||
name += " \[[M.real_name]\]"
|
||||
if (M.stat == 2)
|
||||
if(istype(M, /mob/dead/observer/))
|
||||
if(istype(M, /mob/observer/dead/))
|
||||
name += " \[ghost\]"
|
||||
else
|
||||
name += " \[dead\]"
|
||||
@@ -474,7 +474,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
/proc/sortmobs()
|
||||
var/list/moblist = list()
|
||||
var/list/sortmob = sortAtom(mob_list)
|
||||
for(var/mob/eye/M in sortmob)
|
||||
for(var/mob/observer/eye/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/living/silicon/ai/M in sortmob)
|
||||
moblist.Add(M)
|
||||
@@ -488,7 +488,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
moblist.Add(M)
|
||||
for(var/mob/living/carbon/alien/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/dead/observer/M in sortmob)
|
||||
for(var/mob/observer/dead/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/new_player/M in sortmob)
|
||||
moblist.Add(M)
|
||||
@@ -861,7 +861,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
if(!istype(O,/obj)) continue
|
||||
O.loc = X
|
||||
for(var/mob/M in T)
|
||||
if(!istype(M,/mob) || istype(M, /mob/eye)) continue // If we need to check for more mobs, I'll add a variable
|
||||
if(!istype(M,/mob) || istype(M, /mob/observer/eye)) continue // If we need to check for more mobs, I'll add a variable
|
||||
M.loc = X
|
||||
|
||||
// var/area/AR = X.loc
|
||||
@@ -995,7 +995,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
|
||||
for(var/mob/M in T)
|
||||
|
||||
if(!istype(M,/mob) || istype(M, /mob/eye)) continue // If we need to check for more mobs, I'll add a variable
|
||||
if(!istype(M,/mob) || istype(M, /mob/observer/eye)) continue // If we need to check for more mobs, I'll add a variable
|
||||
mobs += M
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@
|
||||
|
||||
#define iscorgi(A) istype(A, /mob/living/simple_animal/corgi)
|
||||
|
||||
#define isEye(A) istype(A, /mob/eye)
|
||||
#define isEye(A) istype(A, /mob/observer/eye)
|
||||
|
||||
#define ishuman(A) istype(A, /mob/living/carbon/human)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#define isnewplayer(A) istype(A, /mob/new_player)
|
||||
|
||||
#define isobserver(A) istype(A, /mob/dead/observer)
|
||||
#define isobserver(A) istype(A, /mob/observer/dead)
|
||||
|
||||
#define isorgan(A) istype(A, /obj/item/organ/external)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(stat || lockcharge || weakened || stunned || paralysis)
|
||||
if(stat || lockdown || weakened || stunned || paralysis)
|
||||
return
|
||||
|
||||
if(!canClick())
|
||||
|
||||
@@ -61,6 +61,21 @@
|
||||
#define ui_borg_module "EAST-2:26,SOUTH+1:7"
|
||||
#define ui_borg_panel "EAST-1:28,SOUTH+1:7"
|
||||
|
||||
#define ui_ai_core "SOUTH:6,WEST:16"
|
||||
#define ui_ai_camera_list "SOUTH:6,WEST+1:16"
|
||||
#define ui_ai_track_with_camera "SOUTH:6,WEST+2:16"
|
||||
#define ui_ai_camera_light "SOUTH:6,WEST+3:16"
|
||||
#define ui_ai_crew_monitor "SOUTH:6,WEST+4:16"
|
||||
#define ui_ai_crew_manifest "SOUTH:6,WEST+5:16"
|
||||
#define ui_ai_alerts "SOUTH:6,WEST+6:16"
|
||||
#define ui_ai_announcement "SOUTH:6,WEST+7:16"
|
||||
#define ui_ai_shuttle "SOUTH:6,WEST+8:16"
|
||||
#define ui_ai_state_laws "SOUTH:6,WEST+9:16"
|
||||
#define ui_ai_pda_send "SOUTH:6,WEST+10:16"
|
||||
#define ui_ai_pda_log "SOUTH:6,WEST+11:16"
|
||||
#define ui_ai_take_picture "SOUTH:6,WEST+12:16"
|
||||
#define ui_ai_view_images "SOUTH:6,WEST+13:16"
|
||||
|
||||
//Gun buttons
|
||||
#define ui_gun1 "EAST-2:26,SOUTH+2:7"
|
||||
#define ui_gun2 "EAST-1:28, SOUTH+3:7"
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/datum/hud/proc/ai_hud()
|
||||
adding = list()
|
||||
other = list()
|
||||
|
||||
var/obj/screen/using
|
||||
|
||||
//AI core
|
||||
using = new /obj/screen()
|
||||
using.name = "AI Core"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "ai_core"
|
||||
using.screen_loc = ui_ai_core
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Camera list
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Camera List"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "camera"
|
||||
using.screen_loc = ui_ai_camera_list
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Track
|
||||
using = new /obj/screen()
|
||||
using.name = "Track With Camera"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "track"
|
||||
using.screen_loc = ui_ai_track_with_camera
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Camera light
|
||||
using = new /obj/screen()
|
||||
using.name = "Toggle Camera Light"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "camera_light"
|
||||
using.screen_loc = ui_ai_camera_light
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Crew Monitorting
|
||||
using = new /obj/screen()
|
||||
using.name = "Crew Monitorting"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "crew_monitor"
|
||||
using.screen_loc = ui_ai_crew_monitor
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Crew Manifest
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Crew Manifest"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "manifest"
|
||||
using.screen_loc = ui_ai_crew_manifest
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Alerts
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Alerts"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "alerts"
|
||||
using.screen_loc = ui_ai_alerts
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Announcement
|
||||
using = new /obj/screen()
|
||||
using.name = "Announcement"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "announcement"
|
||||
using.screen_loc = ui_ai_announcement
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Shuttle
|
||||
using = new /obj/screen()
|
||||
using.name = "Call Emergency Shuttle"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "call_shuttle"
|
||||
using.screen_loc = ui_ai_shuttle
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Laws
|
||||
using = new /obj/screen()
|
||||
using.name = "State Laws"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "state_laws"
|
||||
using.screen_loc = ui_ai_state_laws
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//PDA message
|
||||
using = new /obj/screen()
|
||||
using.name = "PDA - Send Message"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "pda_send"
|
||||
using.screen_loc = ui_ai_pda_send
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//PDA log
|
||||
using = new /obj/screen()
|
||||
using.name = "PDA - Show Message Log"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "pda_receive"
|
||||
using.screen_loc = ui_ai_pda_log
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//Take image
|
||||
using = new /obj/screen()
|
||||
using.name = "Take Image"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "take_picture"
|
||||
using.screen_loc = ui_ai_take_picture
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
//View images
|
||||
using = new /obj/screen()
|
||||
using.name = "View Images"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "view_images"
|
||||
using.screen_loc = ui_ai_view_images
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
mymob.client.screen += adding + other
|
||||
|
||||
return
|
||||
@@ -388,7 +388,8 @@
|
||||
if(dna.species == "Human") //no more xenos losing ears/tentacles
|
||||
h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
|
||||
undershirt = null
|
||||
underwear = null
|
||||
underwear_top = null
|
||||
underwear_bottom = null
|
||||
socks = null
|
||||
regenerate_icons()
|
||||
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
return
|
||||
|
||||
//Split screen-loc up into X+Pixel_X and Y+Pixel_Y
|
||||
var/list/screen_loc_params = text2list(PM["screen-loc"], ",")
|
||||
var/list/screen_loc_params = splittext(PM["screen-loc"], ",")
|
||||
|
||||
//Split X+Pixel_X up into list(X, Pixel_X)
|
||||
var/list/screen_loc_X = text2list(screen_loc_params[1],":")
|
||||
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
|
||||
screen_loc_X[1] = encode_screen_X(text2num(screen_loc_X[1]))
|
||||
//Split Y+Pixel_Y up into list(Y, Pixel_Y)
|
||||
var/list/screen_loc_Y = text2list(screen_loc_params[2],":")
|
||||
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
|
||||
screen_loc_Y[1] = encode_screen_Y(text2num(screen_loc_Y[1]))
|
||||
|
||||
if(snap2grid) //Discard Pixel Values
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
mymob.blind.screen_loc = "1,1"
|
||||
mymob.blind.layer = 0
|
||||
|
||||
/datum/hud/proc/ai_hud()
|
||||
return
|
||||
|
||||
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
|
||||
|
||||
blobpwrdisplay = new /obj/screen()
|
||||
|
||||
@@ -397,6 +397,78 @@
|
||||
if("module3")
|
||||
if(istype(usr, /mob/living/silicon/robot))
|
||||
usr:toggle_module(3)
|
||||
|
||||
if("AI Core")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.view_core()
|
||||
|
||||
if("Show Camera List")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/camera = input(AI) in AI.get_camera_list()
|
||||
AI.ai_camera_list(camera)
|
||||
|
||||
if("Track With Camera")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/target_name = input(AI) in AI.trackable_mobs()
|
||||
AI.ai_camera_track(target_name)
|
||||
|
||||
if("Toggle Camera Light")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.toggle_camera_light()
|
||||
|
||||
if("Crew Monitorting")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_crew_monitor()
|
||||
|
||||
if("Show Crew Manifest")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_roster()
|
||||
|
||||
if("Show Alerts")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_alarm_monitor()
|
||||
|
||||
if("Announcement")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_announcement()
|
||||
|
||||
if("Call Emergency Shuttle")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_call_shuttle()
|
||||
|
||||
if("State Laws")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_checklaws()
|
||||
|
||||
if("PDA - Send Message")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiPDA.cmd_send_pdamesg(usr)
|
||||
|
||||
if("PDA - Show Message Log")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiPDA.cmd_show_message_log(usr)
|
||||
|
||||
if("Take Image")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.take_image()
|
||||
|
||||
if("View Images")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.view_images()
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -57,15 +57,15 @@
|
||||
overlays.Add(open_state)
|
||||
|
||||
/obj/screen/movable/spell_master/proc/open_spellmaster()
|
||||
var/list/screen_loc_xy = text2list(screen_loc,",")
|
||||
var/list/screen_loc_xy = splittext(screen_loc,",")
|
||||
|
||||
//Create list of X offsets
|
||||
var/list/screen_loc_X = text2list(screen_loc_xy[1],":")
|
||||
var/list/screen_loc_X = splittext(screen_loc_xy[1],":")
|
||||
var/x_position = decode_screen_X(screen_loc_X[1])
|
||||
var/x_pix = screen_loc_X[2]
|
||||
|
||||
//Create list of Y offsets
|
||||
var/list/screen_loc_Y = text2list(screen_loc_xy[2],":")
|
||||
var/list/screen_loc_Y = splittext(screen_loc_xy[2],":")
|
||||
var/y_position = decode_screen_Y(screen_loc_Y[1])
|
||||
var/y_pix = screen_loc_Y[2]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/client/var/inquisitive_ghost = 1
|
||||
/mob/dead/observer/verb/toggle_inquisition() // warning: unexpected inquisition
|
||||
/mob/observer/dead/verb/toggle_inquisition() // warning: unexpected inquisition
|
||||
set name = "Toggle Inquisitiveness"
|
||||
set desc = "Sets whether your ghost examines everything on click by default"
|
||||
set category = "Ghost"
|
||||
@@ -10,7 +10,7 @@
|
||||
else
|
||||
src << "<span class='notice'>You will no longer examine things you click on.</span>"
|
||||
|
||||
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
|
||||
/mob/observer/dead/DblClickOn(var/atom/A, var/params)
|
||||
if(client.buildmode)
|
||||
build_click(src, client.buildmode, params, A)
|
||||
return
|
||||
@@ -20,7 +20,7 @@
|
||||
return // seems legit.
|
||||
|
||||
// Things you might plausibly want to follow
|
||||
if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/singularity))
|
||||
if((ismob(A) && A != src) || istype(A,/obj/singularity))
|
||||
ManualFollow(A)
|
||||
|
||||
// Otherwise jump
|
||||
@@ -28,7 +28,7 @@
|
||||
following = null
|
||||
forceMove(get_turf(A))
|
||||
|
||||
/mob/dead/observer/ClickOn(var/atom/A, var/params)
|
||||
/mob/observer/dead/ClickOn(var/atom/A, var/params)
|
||||
if(client.buildmode)
|
||||
build_click(src, client.buildmode, params, A)
|
||||
return
|
||||
@@ -39,7 +39,7 @@
|
||||
A.attack_ghost(src)
|
||||
|
||||
// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you
|
||||
/atom/proc/attack_ghost(mob/dead/observer/user as mob)
|
||||
/atom/proc/attack_ghost(mob/observer/dead/user as mob)
|
||||
if(user.client && user.client.inquisitive_ghost)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
@@ -58,7 +58,7 @@ world/loop_checks = 0
|
||||
if(A.loc != null)
|
||||
testing("GC: [A] | [A.type] is located in [A.loc] instead of null")
|
||||
if(A.contents.len)
|
||||
testing("GC: [A] | [A.type] has contents: [list2text(A.contents)]")
|
||||
testing("GC: [A] | [A.type] has contents: [jointext(A.contents)]")
|
||||
if(searching.len)
|
||||
for(var/atom/D in world)
|
||||
LookForRefs(D, searching)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
if(config.kick_inactive)
|
||||
for(var/client/C in clients)
|
||||
if(!C.holder && C.is_afk(config.kick_inactive MINUTES))
|
||||
if(!istype(C.mob, /mob/dead))
|
||||
if(!istype(C.mob, /mob/observer/dead))
|
||||
log_access("AFK: [key_name(C)]")
|
||||
C << "<SPAN CLASS='warning'>You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.</SPAN>"
|
||||
del(C) // Don't qdel, cannot override finalize_qdel behaviour for clients.
|
||||
|
||||
@@ -265,7 +265,7 @@ var/list/gamemode_cache = list()
|
||||
if(type == "config")
|
||||
switch (name)
|
||||
if ("resource_urls")
|
||||
config.resource_urls = text2list(value, " ")
|
||||
config.resource_urls = splittext(value, " ")
|
||||
|
||||
if ("admin_legacy_system")
|
||||
config.admin_legacy_system = 1
|
||||
@@ -337,7 +337,7 @@ var/list/gamemode_cache = list()
|
||||
config.generate_asteroid = 1
|
||||
|
||||
if ("asteroid_z_levels")
|
||||
config.asteroid_z_levels = text2list(value, ";")
|
||||
config.asteroid_z_levels = splittext(value, ";")
|
||||
//Numbers get stored as strings, so we'll fix that right now.
|
||||
for(var/z_level in config.asteroid_z_levels)
|
||||
z_level = text2num(z_level)
|
||||
@@ -696,7 +696,7 @@ var/list/gamemode_cache = list()
|
||||
config.starlight = value >= 0 ? value : 0
|
||||
|
||||
if("ert_species")
|
||||
config.ert_species = text2list(value, ";")
|
||||
config.ert_species = splittext(value, ";")
|
||||
if(!config.ert_species.len)
|
||||
config.ert_species += "Human"
|
||||
|
||||
@@ -707,7 +707,7 @@ var/list/gamemode_cache = list()
|
||||
config.aggressive_changelog = 1
|
||||
|
||||
if("default_language_prefixes")
|
||||
var/list/values = text2list(value, " ")
|
||||
var/list/values = splittext(value, " ")
|
||||
if(values.len > 0)
|
||||
language_prefixes = values
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ var/global/datum/getrev/revdata = new()
|
||||
var/list/head_log = file2list(".git/logs/HEAD", "\n")
|
||||
for(var/line=head_log.len, line>=1, line--)
|
||||
if(head_log[line])
|
||||
var/list/last_entry = text2list(head_log[line], " ")
|
||||
var/list/last_entry = splittext(head_log[line], " ")
|
||||
if(last_entry.len < 2) continue
|
||||
revision = last_entry[2]
|
||||
// Get date/time
|
||||
|
||||
+87
-67
@@ -50,7 +50,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/swabs,
|
||||
/obj/item/weapon/storage/box/slides,
|
||||
/obj/item/device/uv_light,
|
||||
/obj/item/weapon/reagent_containers/spray/luminol)
|
||||
cost = 30
|
||||
@@ -278,11 +277,11 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
group = "Miscellaneous"
|
||||
|
||||
/datum/supply_packs/mule
|
||||
name = "MULEbot Crate"
|
||||
contains = list(/obj/machinery/bot/mulebot)
|
||||
name = "Mulebot Crate"
|
||||
contains = list()
|
||||
cost = 20
|
||||
containertype = /obj/structure/largecrate/mule
|
||||
containername = "MULEbot Crate"
|
||||
containertype = /obj/structure/largecrate/animal/mulebot
|
||||
containername = "Mulebot Crate"
|
||||
group = "Operations"
|
||||
|
||||
/datum/supply_packs/cargotrain
|
||||
@@ -771,13 +770,11 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
contains = list(/obj/item/weapon/gun/energy/xray,
|
||||
/obj/item/weapon/gun/energy/xray,
|
||||
/obj/item/weapon/shield/energy,
|
||||
/obj/item/weapon/shield/energy,
|
||||
/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/suit/armor/laserproof)
|
||||
/obj/item/weapon/shield/energy)
|
||||
cost = 125
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Experimental weapons crate"
|
||||
access = access_heads
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/randomised/armor
|
||||
@@ -801,8 +798,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
access = access_security
|
||||
group = "Security"
|
||||
|
||||
|
||||
/datum/supply_packs/riot
|
||||
/datum/supply_packs/riot_gear
|
||||
name = "Riot gear crate"
|
||||
contains = list(/obj/item/weapon/melee/baton,
|
||||
/obj/item/weapon/melee/baton,
|
||||
@@ -813,21 +809,87 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/weapon/storage/box/flashbangs,
|
||||
/obj/item/weapon/storage/box/beanbags,
|
||||
/obj/item/weapon/storage/box/handcuffs)
|
||||
cost = 60
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Riot gear crate"
|
||||
containername = "riot gear crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/riot_armor
|
||||
name = "Riot armor set crate"
|
||||
contains = list(/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/gloves/arm_guard/riot,
|
||||
/obj/item/clothing/shoes/leg_guard/riot)
|
||||
cost = 30
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "riot armor set crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/ablative_armor
|
||||
name = "Ablative armor set crate"
|
||||
contains = list(/obj/item/clothing/head/helmet/laserproof,
|
||||
/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/gloves/arm_guard/laserproof,
|
||||
/obj/item/clothing/shoes/leg_guard/laserproof)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "ablative armor set crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/bullet_resistant_armor
|
||||
name = "Bullet resistant armor set crate"
|
||||
contains = list(/obj/item/clothing/head/helmet/bulletproof,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/gloves/arm_guard/bulletproof,
|
||||
/obj/item/clothing/shoes/leg_guard/bulletproof)
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "bullet resistant armor set crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/combat_armor
|
||||
name = "Combat armor set crate"
|
||||
contains = list(/obj/item/clothing/head/helmet/combat,
|
||||
/obj/item/clothing/suit/armor/combat,
|
||||
/obj/item/clothing/gloves/arm_guard/combat,
|
||||
/obj/item/clothing/shoes/leg_guard/combat)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "combat armor set crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/tactical
|
||||
name = "Tactical suits"
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Tactical Suit Locker"
|
||||
cost = 60
|
||||
group = "Security"
|
||||
access = access_armory
|
||||
contains = list(/obj/item/clothing/under/tactical,
|
||||
/obj/item/clothing/suit/armor/tactical,
|
||||
/obj/item/clothing/head/helmet/tactical,
|
||||
/obj/item/clothing/mask/balaclava/tactical,
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/tactical,
|
||||
/obj/item/weapon/storage/belt/security/tactical,
|
||||
/obj/item/clothing/shoes/jackboots,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/under/tactical,
|
||||
/obj/item/clothing/suit/armor/tactical,
|
||||
/obj/item/clothing/head/helmet/tactical,
|
||||
/obj/item/clothing/mask/balaclava/tactical,
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/tactical,
|
||||
/obj/item/weapon/storage/belt/security/tactical,
|
||||
/obj/item/clothing/shoes/jackboots,
|
||||
/obj/item/clothing/gloves/black)
|
||||
|
||||
/datum/supply_packs/energyweapons
|
||||
name = "Energy weapons crate"
|
||||
contains = list(/obj/item/weapon/gun/energy/laser,
|
||||
@@ -841,9 +903,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
|
||||
/datum/supply_packs/shotgun
|
||||
name = "Shotgun crate"
|
||||
contains = list(/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/weapon/storage/box/shotgunammo,
|
||||
contains = list(/obj/item/weapon/storage/box/shotgunammo,
|
||||
/obj/item/weapon/storage/box/shotgunshells,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat)
|
||||
@@ -855,9 +915,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
|
||||
/datum/supply_packs/erifle
|
||||
name = "Energy marksman crate"
|
||||
contains = list(/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/weapon/gun/energy/sniperrifle,
|
||||
contains = list(/obj/item/weapon/gun/energy/sniperrifle,
|
||||
/obj/item/weapon/gun/energy/sniperrifle)
|
||||
cost = 90
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
@@ -922,27 +980,13 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
group = "Security"
|
||||
*/
|
||||
|
||||
/datum/supply_packs/expenergy
|
||||
name = "Experimental energy gear crate"
|
||||
contains = list(/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/weapon/gun/energy/gun,
|
||||
/datum/supply_packs/energy_guns
|
||||
name = "energy guns crate"
|
||||
contains = list(/obj/item/weapon/gun/energy/gun,
|
||||
/obj/item/weapon/gun/energy/gun)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Experimental energy gear crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/exparmor
|
||||
name = "Experimental armor crate"
|
||||
contains = list(/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/suit/armor/bulletproof,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot)
|
||||
cost = 35
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Experimental armor crate"
|
||||
containername = "energy guns crate"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
@@ -1320,30 +1364,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containername = "Radiation suit locker"
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/tactical
|
||||
name = "Tactical suits"
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Tactical Suit Locker"
|
||||
cost = 45
|
||||
group = "Security"
|
||||
access = access_armory
|
||||
contains = list(/obj/item/clothing/under/tactical,
|
||||
/obj/item/clothing/suit/armor/tactical,
|
||||
/obj/item/clothing/head/helmet/tactical,
|
||||
/obj/item/clothing/mask/balaclava/tactical,
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/tactical,
|
||||
/obj/item/weapon/storage/belt/security/tactical,
|
||||
/obj/item/clothing/shoes/jackboots,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/under/tactical,
|
||||
/obj/item/clothing/suit/armor/tactical,
|
||||
/obj/item/clothing/head/helmet/tactical,
|
||||
/obj/item/clothing/mask/balaclava/tactical,
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/tactical,
|
||||
/obj/item/weapon/storage/belt/security/tactical,
|
||||
/obj/item/clothing/shoes/jackboots,
|
||||
/obj/item/clothing/gloves/black)
|
||||
|
||||
/datum/supply_packs/carpet
|
||||
name = "Imported carpet"
|
||||
containertype = /obj/structure/closet
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/datum/wires/mulebot
|
||||
random = 1
|
||||
holder_type = /obj/machinery/bot/mulebot
|
||||
wire_count = 10
|
||||
|
||||
var/const/WIRE_POWER1 = 1 // power connections
|
||||
var/const/WIRE_POWER2 = 2
|
||||
var/const/WIRE_AVOIDANCE = 4 // mob avoidance
|
||||
var/const/WIRE_LOADCHECK = 8 // load checking (non-crate)
|
||||
var/const/WIRE_MOTOR1 = 16 // motor wires
|
||||
var/const/WIRE_MOTOR2 = 32 //
|
||||
var/const/WIRE_REMOTE_RX = 64 // remote recv functions
|
||||
var/const/WIRE_REMOTE_TX = 128 // remote trans status
|
||||
var/const/WIRE_BEACON_RX = 256 // beacon ping recv
|
||||
|
||||
/datum/wires/mulebot/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/bot/mulebot/M = holder
|
||||
if(M.open)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// So the wires do not open a new window, handle the interaction ourselves.
|
||||
/datum/wires/mulebot/Interact(var/mob/living/user)
|
||||
if(CanUse(user))
|
||||
var/obj/machinery/bot/mulebot/M = holder
|
||||
M.interact(user)
|
||||
|
||||
/datum/wires/mulebot/UpdatePulsed(var/index)
|
||||
switch(index)
|
||||
if(WIRE_POWER1, WIRE_POWER2)
|
||||
holder.visible_message("<span class='notice'>\icon[holder] The charge light flickers.</span>")
|
||||
if(WIRE_AVOIDANCE)
|
||||
holder.visible_message("<span class='notice'>\icon[holder] The external warning lights flash briefly.</span>")
|
||||
if(WIRE_LOADCHECK)
|
||||
holder.visible_message("<span class='notice'>\icon[holder] The load platform clunks.</span>")
|
||||
if(WIRE_MOTOR1, WIRE_MOTOR2)
|
||||
holder.visible_message("<span class='notice'>\icon[holder] The drive motor whines briefly.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>\icon[holder] You hear a radio crackle.</span>")
|
||||
|
||||
// HELPER PROCS
|
||||
|
||||
/datum/wires/mulebot/proc/Motor1()
|
||||
return !(wires_status & WIRE_MOTOR1)
|
||||
|
||||
/datum/wires/mulebot/proc/Motor2()
|
||||
return !(wires_status & WIRE_MOTOR2)
|
||||
|
||||
/datum/wires/mulebot/proc/HasPower()
|
||||
return !(wires_status & WIRE_POWER1) && !(wires_status & WIRE_POWER2)
|
||||
|
||||
/datum/wires/mulebot/proc/LoadCheck()
|
||||
return !(wires_status & WIRE_LOADCHECK)
|
||||
|
||||
/datum/wires/mulebot/proc/MobAvoid()
|
||||
return !(wires_status & WIRE_AVOIDANCE)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteTX()
|
||||
return !(wires_status & WIRE_REMOTE_TX)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteRX()
|
||||
return !(wires_status & WIRE_REMOTE_RX)
|
||||
|
||||
/datum/wires/mulebot/proc/BeaconRX()
|
||||
return !(wires_status & WIRE_BEACON_RX)
|
||||
@@ -16,7 +16,7 @@ var/const/BORG_WIRE_CAMERA = 16
|
||||
. += text("<br>\n[(R.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]")
|
||||
. += text("<br>\n[(R.connected_ai ? "The AI link light is on." : "The AI link light is off.")]")
|
||||
. += text("<br>\n[((!isnull(R.camera) && R.camera.status == 1) ? "The Camera light is on." : "The Camera light is off.")]")
|
||||
. += text("<br>\n[(R.lockcharge ? "The lockdown light is on." : "The lockdown light is off.")]")
|
||||
. += text("<br>\n[(R.lockdown ? "The lockdown light is on." : "The lockdown light is off.")]")
|
||||
return .
|
||||
|
||||
/datum/wires/robot/UpdateCut(var/index, var/mended)
|
||||
@@ -64,7 +64,7 @@ var/const/BORG_WIRE_CAMERA = 16
|
||||
R << "Your camera lense focuses loudly."
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
R.SetLockdown(!R.lockcharge) // Toggle
|
||||
R.SetLockdown(!R.lockdown) // Toggle
|
||||
|
||||
/datum/wires/robot/CanUse(var/mob/living/L)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
|
||||
+2
-2
@@ -114,7 +114,7 @@ var/global/ManifestJSON
|
||||
department = 1
|
||||
if(depthead && sci.len != 1)
|
||||
sci.Swap(1,sci.len)
|
||||
|
||||
|
||||
if(real_rank in cargo_positions)
|
||||
car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive)
|
||||
department = 1
|
||||
@@ -146,7 +146,7 @@ var/global/ManifestJSON
|
||||
"bot" = bot,\
|
||||
"misc" = misc\
|
||||
)
|
||||
ManifestJSON = list2json(PDA_Manifest)
|
||||
ManifestJSON = json_encode(PDA_Manifest)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ mob/proc/handle_regular_hud_updates() //Used in the life.dm of mobs that can use
|
||||
mob/proc/in_view(var/turf/T)
|
||||
return view(T)
|
||||
|
||||
/mob/eye/in_view(var/turf/T)
|
||||
/mob/observer/eye/in_view(var/turf/T)
|
||||
var/list/viewed = new
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(get_dist(H, T) <= 7)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
var/datum/antagonist/xenos/borer/borers
|
||||
var/datum/antagonist/borer/borers
|
||||
|
||||
/datum/antagonist/xenos/borer
|
||||
/datum/antagonist/borer
|
||||
id = MODE_BORER
|
||||
role_type = BE_ALIEN
|
||||
role_text = "Cortical Borer"
|
||||
role_text_plural = "Cortical Borers"
|
||||
mob_path = /mob/living/simple_animal/borer
|
||||
@@ -10,6 +11,8 @@ var/datum/antagonist/xenos/borer/borers
|
||||
antag_indicator = "brainworm"
|
||||
antaghud_indicator = "hudborer"
|
||||
|
||||
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
|
||||
|
||||
faction_role_text = "Borer Thrall"
|
||||
faction_descriptor = "Unity"
|
||||
faction_welcome = "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head."
|
||||
@@ -17,21 +20,26 @@ var/datum/antagonist/xenos/borer/borers
|
||||
initial_spawn_req = 3
|
||||
initial_spawn_target = 5
|
||||
|
||||
/datum/antagonist/xenos/borer/New()
|
||||
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
|
||||
spawn_announcement_title = "Lifesign Alert"
|
||||
spawn_announcement_sound = 'sound/AI/aliens.ogg'
|
||||
spawn_announcement_delay = 5000
|
||||
|
||||
/datum/antagonist/borer/New()
|
||||
..(1)
|
||||
borers = src
|
||||
|
||||
/datum/antagonist/xenos/borer/get_extra_panel_options(var/datum/mind/player)
|
||||
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[put in host\]</a>"
|
||||
|
||||
/datum/antagonist/xenos/borer/create_objectives(var/datum/mind/player)
|
||||
/datum/antagonist/borer/create_objectives(var/datum/mind/player)
|
||||
if(!..())
|
||||
return
|
||||
player.objectives += new /datum/objective/borer_survive()
|
||||
player.objectives += new /datum/objective/borer_reproduce()
|
||||
player.objectives += new /datum/objective/escape()
|
||||
|
||||
/datum/antagonist/xenos/borer/place_mob(var/mob/living/mob)
|
||||
/datum/antagonist/borer/place_mob(var/mob/living/mob)
|
||||
var/mob/living/simple_animal/borer/borer = mob
|
||||
if(istype(borer))
|
||||
var/mob/living/carbon/human/host
|
||||
@@ -51,4 +59,16 @@ var/datum/antagonist/xenos/borer/borers
|
||||
borer.host_brain.name = host.name
|
||||
borer.host_brain.real_name = host.real_name
|
||||
return
|
||||
..() // Place them at a vent if they can't get a host.
|
||||
// Place them at a vent if they can't get a host.
|
||||
borer.forceMove(get_turf(pick(get_vents())))
|
||||
|
||||
/datum/antagonist/borer/attempt_random_spawn()
|
||||
if(config.aliens_allowed) ..()
|
||||
|
||||
/datum/antagonist/borer/proc/get_vents()
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
|
||||
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
|
||||
if(temp_vent.network.normal_members.len > 50)
|
||||
vents += temp_vent
|
||||
return vents
|
||||
@@ -1,47 +0,0 @@
|
||||
var/datum/antagonist/xenos/xenomorphs
|
||||
|
||||
/datum/antagonist/xenos
|
||||
id = MODE_XENOMORPH
|
||||
role_type = BE_ALIEN
|
||||
role_text = "Xenomorph"
|
||||
role_text_plural = "Xenomorphs"
|
||||
mob_path = /mob/living/carbon/alien/larva
|
||||
bantype = "Xenomorph"
|
||||
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
|
||||
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
|
||||
antaghud_indicator = "hudalien"
|
||||
|
||||
hard_cap = 5
|
||||
hard_cap_round = 8
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
|
||||
spawn_announcement_title = "Lifesign Alert"
|
||||
spawn_announcement_sound = 'sound/AI/aliens.ogg'
|
||||
spawn_announcement_delay = 5000
|
||||
|
||||
/datum/antagonist/xenos/New(var/no_reference)
|
||||
..()
|
||||
if(!no_reference)
|
||||
xenomorphs = src
|
||||
|
||||
/datum/antagonist/xenos/attempt_random_spawn()
|
||||
if(config.aliens_allowed) ..()
|
||||
|
||||
/datum/antagonist/xenos/proc/get_vents()
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
|
||||
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
|
||||
if(temp_vent.network.normal_members.len > 50)
|
||||
vents += temp_vent
|
||||
return vents
|
||||
|
||||
/datum/antagonist/xenos/create_objectives(var/datum/mind/player)
|
||||
if(!..())
|
||||
return
|
||||
player.objectives += new /datum/objective/survive()
|
||||
player.objectives += new /datum/objective/escape()
|
||||
|
||||
/datum/antagonist/xenos/place_mob(var/mob/living/player)
|
||||
player.forceMove(get_turf(pick(get_vents())))
|
||||
@@ -63,6 +63,8 @@
|
||||
var/list/global_objectives = list() // Universal objectives if any.
|
||||
var/list/candidates = list() // Potential candidates.
|
||||
var/list/faction_members = list() // Semi-antags (in-round revs, borer thralls)
|
||||
|
||||
var/allow_latejoin = 0 //Determines whether or not the game mode will allow for the template to spawn try_latespawn
|
||||
|
||||
// ID card stuff.
|
||||
var/default_access = list()
|
||||
@@ -92,7 +94,7 @@
|
||||
// Prune restricted status. Broke it up for readability.
|
||||
// Note that this is done before jobs are handed out.
|
||||
for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id))
|
||||
if(ghosts_only && !istype(player.current, /mob/dead))
|
||||
if(ghosts_only && !istype(player.current, /mob/observer/dead))
|
||||
log_debug("[key_name(player)] is not eligible to become a [role_text]: Only ghosts may join as this role!")
|
||||
else if(player.special_role)
|
||||
log_debug("[key_name(player)] is not eligible to become a [role_text]: They already have a special role ([player.special_role])!")
|
||||
@@ -124,7 +126,7 @@
|
||||
return 0
|
||||
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
|
||||
message_admins("[uppertext(ticker.mode.name)]: Selected [player] as a [role_text].")
|
||||
if(istype(player.current, /mob/dead))
|
||||
if(istype(player.current, /mob/observer/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
add_antagonist(player,0,0,0,1,1)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
player.assigned_role = role_text
|
||||
player.special_role = role_text
|
||||
|
||||
if(istype(player.current, /mob/dead))
|
||||
if(istype(player.current, /mob/observer/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
return (flags & ANTAG_VOTABLE)
|
||||
|
||||
/datum/antagonist/proc/can_late_spawn()
|
||||
if(!(allow_latejoin))
|
||||
return 0
|
||||
update_current_antag_max()
|
||||
if(get_antag_count() >= cur_max)
|
||||
return 0
|
||||
|
||||
@@ -161,7 +161,7 @@ var/datum/antagonist/raider/raiders
|
||||
else
|
||||
win_type = "Minor"
|
||||
win_group = "Crew"
|
||||
//Now we modify that result by the state of the vox crew.
|
||||
//Now we modify that result by the state of the crew.
|
||||
if(antags_are_dead())
|
||||
win_type = "Major"
|
||||
win_group = "Crew"
|
||||
@@ -198,26 +198,23 @@ var/datum/antagonist/raider/raiders
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
if(player.species && player.species.get_bodytype() == "Vox")
|
||||
equip_vox(player)
|
||||
else
|
||||
var/new_shoes = pick(raider_shoes)
|
||||
var/new_uniform = pick(raider_uniforms)
|
||||
var/new_glasses = pick(raider_glasses)
|
||||
var/new_helmet = pick(raider_helmets)
|
||||
var/new_suit = pick(raider_suits)
|
||||
var/new_shoes = pick(raider_shoes)
|
||||
var/new_uniform = pick(raider_uniforms)
|
||||
var/new_glasses = pick(raider_glasses)
|
||||
var/new_helmet = pick(raider_helmets)
|
||||
var/new_suit = pick(raider_suits)
|
||||
|
||||
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
|
||||
if(!player.shoes)
|
||||
//If equipping shoes failed, fall back to equipping sandals
|
||||
var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
|
||||
player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
|
||||
player.equip_to_slot_or_del(new new_shoes(player),slot_shoes)
|
||||
if(!player.shoes)
|
||||
//If equipping shoes failed, fall back to equipping sandals
|
||||
var/fallback_type = pick(/obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/jackboots/unathi)
|
||||
player.equip_to_slot_or_del(new fallback_type(player), slot_shoes)
|
||||
|
||||
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
|
||||
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
|
||||
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
|
||||
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
|
||||
equip_weapons(player)
|
||||
player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform)
|
||||
player.equip_to_slot_or_del(new new_glasses(player),slot_glasses)
|
||||
player.equip_to_slot_or_del(new new_helmet(player),slot_head)
|
||||
player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit)
|
||||
equip_weapons(player)
|
||||
|
||||
var/obj/item/weapon/card/id/id = create_id("Visitor", player, equip = 0)
|
||||
id.name = "[player.real_name]'s Passport"
|
||||
@@ -293,21 +290,3 @@ var/datum/antagonist/raider/raiders
|
||||
var/grenade_type = pick(grenades)
|
||||
new grenade_type(ammobox)
|
||||
player.put_in_any_hand_if_possible(ammobox)
|
||||
|
||||
/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player)
|
||||
|
||||
var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual))
|
||||
|
||||
player.equip_to_slot_or_del(new uniform_type(player), slot_w_uniform)
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(player), slot_gloves) // AS ABOVE.
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat/vox(player), slot_wear_mask)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store)
|
||||
|
||||
player.internal = locate(/obj/item/weapon/tank) in player.contents
|
||||
if(istype(player.internal,/obj/item/weapon/tank) && player.internals)
|
||||
player.internals.icon_state = "internal1"
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@ var/datum/antagonist/traitor/traitors
|
||||
id = MODE_TRAITOR
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
|
||||
/datum/antagonist/traitor/auto
|
||||
id = MODE_AUTOTRAITOR
|
||||
allow_latejoin = 1
|
||||
|
||||
/datum/antagonist/traitor/New()
|
||||
..()
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, WEST)))
|
||||
|
||||
if(!M.client && M.mind)
|
||||
for(var/mob/dead/observer/ghost in player_list)
|
||||
for(var/mob/observer/dead/ghost in player_list)
|
||||
if(ghost.mind == M.mind)
|
||||
ghost << "<b><font color = #330033><font size = 3>Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned!</b> (Verbs -> Ghost -> Re-enter corpse)</font></font>"
|
||||
break
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/mob/proc/cultify()
|
||||
return
|
||||
|
||||
/mob/dead/cultify()
|
||||
/mob/observer/dead/cultify()
|
||||
if(icon_state != "ghost-narsie")
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "ghost-narsie"
|
||||
@@ -21,7 +21,7 @@
|
||||
C << "<span class='sinister'>The Geometer of Blood is overjoyed to be reunited with its followers, and accepts your body in sacrifice. As reward, you have been gifted with the shell of an Harvester.<br>Your tendrils can use and draw runes without need for a tome, your eyes can see beings through walls, and your mind can open any door. Use these assets to serve Nar-Sie and bring him any remaining living human in the world.<br>You can teleport yourself back to Nar-Sie along with any being under yourself at any time using your \"Harvest\" spell.</span>"
|
||||
dust()
|
||||
else if(client)
|
||||
var/mob/dead/G = (ghostize())
|
||||
var/mob/observer/dead/G = (ghostize())
|
||||
G.icon = 'icons/mob/mob.dmi'
|
||||
G.icon_state = "ghost-narsie"
|
||||
G.overlays = 0
|
||||
|
||||
@@ -298,7 +298,7 @@ var/global/list/narsie_list = list()
|
||||
acquire(pick(cultists))
|
||||
return
|
||||
//no living cultists, pick a living human instead.
|
||||
for(var/mob/dead/observer/ghost in player_list)
|
||||
for(var/mob/observer/dead/ghost in player_list)
|
||||
if(!ghost.client)
|
||||
continue
|
||||
var/turf/pos = get_turf(ghost)
|
||||
|
||||
@@ -343,8 +343,8 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [name] on [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
if(istype(M,/mob/dead))
|
||||
var/mob/dead/D = M
|
||||
if(istype(M,/mob/observer/dead))
|
||||
var/mob/observer/dead/D = M
|
||||
D.manifest(user)
|
||||
return
|
||||
if(!istype(M))
|
||||
|
||||
@@ -342,8 +342,8 @@ var/list/sacrificed = list()
|
||||
usr << "<span class='warning'>The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used.</span>"
|
||||
return fizzle()
|
||||
|
||||
var/mob/dead/observer/ghost
|
||||
for(var/mob/dead/observer/O in loc)
|
||||
var/mob/observer/dead/ghost
|
||||
for(var/mob/observer/dead/O in loc)
|
||||
if(!O.client) continue
|
||||
if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue
|
||||
ghost = O
|
||||
@@ -437,8 +437,8 @@ var/list/sacrificed = list()
|
||||
src = null
|
||||
if(usr.loc!=this_rune.loc)
|
||||
return this_rune.fizzle()
|
||||
var/mob/dead/observer/ghost
|
||||
for(var/mob/dead/observer/O in this_rune.loc)
|
||||
var/mob/observer/dead/ghost
|
||||
for(var/mob/observer/dead/O in this_rune.loc)
|
||||
if(!O.client) continue
|
||||
if(!O.MayRespawn()) continue
|
||||
if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue
|
||||
@@ -468,7 +468,8 @@ var/list/sacrificed = list()
|
||||
D.r_eyes = 200
|
||||
D.g_eyes = 200
|
||||
D.update_eyes()
|
||||
D.underwear = 0
|
||||
D.underwear_top = 0
|
||||
D.underwear_bottom = 0
|
||||
D.key = ghost.key
|
||||
cult.add_antagonist(D.mind)
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
|
||||
/turf/unsimulated/wall/supermatter/proc/Consume(var/mob/living/user)
|
||||
if(istype(user,/mob/dead/observer))
|
||||
if(istype(user,/mob/observer))
|
||||
return
|
||||
|
||||
qdel(user)
|
||||
|
||||
@@ -350,11 +350,6 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
|
||||
M << "<br>"
|
||||
M.add_ion_law("THE STATION IS [who2pref] [who2]")
|
||||
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in machines)
|
||||
if(prob(botEmagChance))
|
||||
bot.emag_act(1)
|
||||
|
||||
/*
|
||||
|
||||
var/apcnum = 0
|
||||
|
||||
@@ -254,13 +254,13 @@ var/global/list/additional_antag_types = list()
|
||||
"suspected criminal operatives",
|
||||
"malfunctioning von Neumann probe swarms",
|
||||
"shadowy interlopers",
|
||||
"a stranded Vox arkship",
|
||||
"a stranded alien arkship",
|
||||
"haywire IPC constructs",
|
||||
"rogue Unathi exiles",
|
||||
"artifacts of eldritch horror",
|
||||
"a brain slug infestation",
|
||||
"killer bugs that lay eggs in the husks of the living",
|
||||
"a deserted transport carrying xenomorph specimens",
|
||||
"a deserted transport carrying alien specimens",
|
||||
"an emissary for the gestalt requesting a security detail",
|
||||
"a Tajaran slave rebellion",
|
||||
"radical Skrellian transevolutionaries",
|
||||
@@ -537,7 +537,7 @@ proc/display_roundstart_logout_report()
|
||||
continue //Dead
|
||||
|
||||
continue //Happy connected client
|
||||
for(var/mob/dead/observer/D in mob_list)
|
||||
for(var/mob/observer/dead/D in mob_list)
|
||||
if(D.mind && (D.mind.original == L || D.mind.current == L))
|
||||
if(L.stat == DEAD)
|
||||
if(L.suiciding) //Suicider
|
||||
|
||||
@@ -387,8 +387,8 @@ var/global/datum/controller/gameticker/ticker
|
||||
else
|
||||
Player << "<font color='blue'><b>You missed the crew transfer after the events on [station_name()] as [Player.real_name].</b></font>"
|
||||
else
|
||||
if(istype(Player,/mob/dead/observer))
|
||||
var/mob/dead/observer/O = Player
|
||||
if(istype(Player,/mob/observer/dead))
|
||||
var/mob/observer/dead/O = Player
|
||||
if(!O.started_as_observer)
|
||||
Player << "<font color='red'><b>You did not survive the events on [station_name()]...</b></font>"
|
||||
else
|
||||
@@ -418,9 +418,9 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
if (!robo.connected_ai)
|
||||
if (robo.stat != 2)
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) survived as an AI-less borg! Its laws were:</b>"
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) survived as an AI-less synthetic! Its laws were:</b>"
|
||||
else
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>"
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a synthetic without an AI. Its laws were:</b>"
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
robo.laws.show_laws(world)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/datum/game_mode/bughunt
|
||||
name = "Bughunt"
|
||||
round_description = "A mercenary strike force is approaching the station to eradicate a xenomorph infestation!"
|
||||
extended_round_description = "Mercenaries and xenomorphs spawn in this game mode."
|
||||
config_tag = "bughunt"
|
||||
required_players = 15
|
||||
required_players_secret = 25
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_XENOMORPH, MODE_DEATHSQUAD)
|
||||
auto_recall_shuttle = 1
|
||||
ert_disabled = 1
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
@@ -1,12 +1,12 @@
|
||||
/datum/game_mode/infestation
|
||||
name = "infestation"
|
||||
round_description = "There's something in the walls!"
|
||||
extended_round_description = "Two alien antagonists (Xenomorphs, Cortical Borers or Changelings) may spawn during this round."
|
||||
extended_round_description = "Two alien antagonists (Cortical Borers or Changelings) spawn during this round."
|
||||
config_tag = "infestation"
|
||||
required_players = 15
|
||||
required_enemies = 5
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_BORER, MODE_XENOMORPH, MODE_CHANGELING)
|
||||
antag_tags = list(MODE_BORER, MODE_CHANGELING)
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/datum/game_mode/intrigue
|
||||
name = "Intrigue"
|
||||
round_description = "Crewmembers are contacted by external elements while another infiltrates the colony."
|
||||
extended_round_description = "Traitors and a ninja spawn during this round."
|
||||
config_tag = "intrigue"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 4
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_NINJA, MODE_AUTOTRAITOR)
|
||||
round_autoantag = 1
|
||||
require_all_templates = 1
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/lizard
|
||||
name = "lizard"
|
||||
round_description = "A space wizard and changelings have invaded the station!"
|
||||
extended_round_description = "Changelings and a wizard spawn during this round."
|
||||
config_tag = "lizard"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 4
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_WIZARD, MODE_CHANGELING)
|
||||
require_all_templates = 1
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/visitors
|
||||
name = "Visitors"
|
||||
round_description = "A space wizard and a ninja have invaded the station!"
|
||||
extended_round_description = "A ninja and wizard spawn during this round."
|
||||
config_tag = "visitors"
|
||||
required_players = 10
|
||||
required_players_secret = 10
|
||||
required_enemies = 2
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_WIZARD, MODE_NINJA)
|
||||
require_all_templates = 1
|
||||
@@ -34,6 +34,7 @@ var/list/nuke_disks = list()
|
||||
|
||||
/datum/game_mode/nuclear/declare_completion()
|
||||
if(config.objectives_disabled)
|
||||
..()
|
||||
return
|
||||
var/disk_rescued = 1
|
||||
for(var/obj/item/weapon/disk/nuclear/D in world)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
/datum/game_mode/traitor/auto
|
||||
name = "autotraitor"
|
||||
config_tag = "autotraitor"
|
||||
antag_tags = list(MODE_AUTOTRAITOR)
|
||||
round_autoantag = 1
|
||||
required_players_secret = 3
|
||||
antag_scaling_coeff = 5
|
||||
|
||||
@@ -28,7 +28,7 @@ var/list/whitelist = list()
|
||||
if (!text)
|
||||
log_misc("Failed to load config/alienwhitelist.txt")
|
||||
else
|
||||
alien_whitelist = text2list(text, "\n")
|
||||
alien_whitelist = splittext(text, "\n")
|
||||
|
||||
//todo: admin aliens
|
||||
/proc/is_alien_whitelisted(mob/M, var/species)
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/obj/machinery/meter/examine(mob/user)
|
||||
var/t = "A gas flow meter. "
|
||||
|
||||
if(get_dist(user, src) > 3 && !(istype(user, /mob/living/silicon/ai) || istype(user, /mob/dead)))
|
||||
if(get_dist(user, src) > 3 && !(istype(user, /mob/living/silicon/ai) || istype(user, /mob/observer/dead)))
|
||||
t += "<span class='warning'>You are too far away to read it.</span>"
|
||||
|
||||
else if(stat & (NOPOWER|BROKEN))
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
// AI (i.e. game AI, not the AI player) controlled bots
|
||||
|
||||
/obj/machinery/bot
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
layer = MOB_LAYER
|
||||
light_range = 3
|
||||
use_power = 0
|
||||
var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds"
|
||||
var/on = 1
|
||||
var/health = 0 //do not forget to set health for your bot!
|
||||
var/maxhealth = 0
|
||||
var/fire_dam_coeff = 1.0
|
||||
var/brute_dam_coeff = 1.0
|
||||
var/open = 0//Maint panel
|
||||
var/locked = 1
|
||||
//var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots
|
||||
|
||||
/obj/machinery/bot/proc/turn_on()
|
||||
if(stat) return 0
|
||||
on = 1
|
||||
set_light(initial(light_range))
|
||||
return 1
|
||||
|
||||
/obj/machinery/bot/proc/turn_off()
|
||||
on = 0
|
||||
set_light(0)
|
||||
|
||||
/obj/machinery/bot/proc/explode()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/bot/proc/healthcheck()
|
||||
if (src.health <= 0)
|
||||
src.explode()
|
||||
|
||||
/obj/machinery/bot/emag_act(var/remaining_charges, var/user)
|
||||
if(locked && !emagged)
|
||||
locked = 0
|
||||
emagged = 1
|
||||
user << "<span class='warning'>You short out [src]'s maintenance hatch lock.</span>"
|
||||
log_and_message_admins("emagged [src]'s maintenance hatch lock")
|
||||
return 1
|
||||
|
||||
if(!locked && open && emagged == 1)
|
||||
emagged = 2
|
||||
log_and_message_admins("emagged [src]'s inner circuits")
|
||||
return 1
|
||||
|
||||
/obj/machinery/bot/examine(mob/user)
|
||||
..(user)
|
||||
if (src.health < maxhealth)
|
||||
if (src.health > maxhealth/3)
|
||||
user << "<span class='warning'>[src]'s parts look loose.</span>"
|
||||
else
|
||||
user << "<span class='danger'>[src]'s parts look very loose!</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(!locked)
|
||||
open = !open
|
||||
user << "<span class='notice'>Maintenance panel is now [src.open ? "opened" : "closed"].</span>"
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
if(health < maxhealth)
|
||||
if(open)
|
||||
health = min(maxhealth, health+10)
|
||||
user.visible_message("<span class='warning'>[user] repairs [src]!</span>","<span class='notice'>You repair [src]!</span>")
|
||||
else
|
||||
user << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair.</span>"
|
||||
else
|
||||
if(hasvar(W,"force") && hasvar(W,"damtype"))
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
src.health -= W.force * fire_dam_coeff
|
||||
if("brute")
|
||||
src.health -= W.force * brute_dam_coeff
|
||||
..()
|
||||
healthcheck()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
return
|
||||
health -= Proj.damage
|
||||
..()
|
||||
healthcheck()
|
||||
|
||||
/obj/machinery/bot/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.explode()
|
||||
return
|
||||
if(2.0)
|
||||
src.health -= rand(5,10)*fire_dam_coeff
|
||||
src.health -= rand(10,20)*brute_dam_coeff
|
||||
healthcheck()
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
src.health -= rand(1,5)*fire_dam_coeff
|
||||
src.health -= rand(1,5)*brute_dam_coeff
|
||||
healthcheck()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/bot/emp_act(severity)
|
||||
var/was_on = on
|
||||
stat |= EMPED
|
||||
var/obj/effect/overlay/pulse2 = PoolOrNew(/obj/effect/overlay, src.loc )
|
||||
pulse2.icon = 'icons/effects/effects.dmi'
|
||||
pulse2.icon_state = "empdisable"
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = 1
|
||||
pulse2.set_dir(pick(cardinal))
|
||||
|
||||
spawn(10)
|
||||
qdel(pulse2)
|
||||
if (on)
|
||||
turn_off()
|
||||
spawn(severity*300)
|
||||
stat &= ~EMPED
|
||||
if (was_on)
|
||||
turn_on()
|
||||
|
||||
|
||||
/obj/machinery/bot/attack_ai(mob/user as mob)
|
||||
src.attack_hand(user)
|
||||
|
||||
/obj/machinery/bot/attack_hand(var/mob/living/carbon/human/user)
|
||||
|
||||
if(!istype(user))
|
||||
return ..()
|
||||
|
||||
if(user.species.can_shred(user))
|
||||
src.health -= rand(15,30)*brute_dam_coeff
|
||||
src.visible_message("<span class='danger'>[user] has slashed [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
if(prob(10))
|
||||
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
||||
healthcheck()
|
||||
|
||||
/******************************************************************/
|
||||
// Navigation procs
|
||||
// Used for A-star pathfinding
|
||||
|
||||
|
||||
// Returns the surrounding cardinal turfs with open links
|
||||
// Including through doors openable with the ID
|
||||
/turf/proc/CardinalTurfsWithAccess(var/obj/item/weapon/card/id/ID)
|
||||
var/L[] = new()
|
||||
|
||||
// for(var/turf/simulated/t in oview(src,1))
|
||||
|
||||
for(var/d in cardinal)
|
||||
var/turf/simulated/T = get_step(src, d)
|
||||
if(istype(T) && !T.density)
|
||||
if(!LinkBlockedWithAccess(src, T, ID))
|
||||
L.Add(T)
|
||||
return L
|
||||
|
||||
|
||||
// Returns true if a link between A and B is blocked
|
||||
// Movement through doors allowed if ID has access
|
||||
/proc/LinkBlockedWithAccess(turf/A, turf/B, obj/item/weapon/card/id/ID)
|
||||
|
||||
if(A == null || B == null) return 1
|
||||
var/adir = get_dir(A,B)
|
||||
var/rdir = get_dir(B,A)
|
||||
if((adir & (NORTH|SOUTH)) && (adir & (EAST|WEST))) // diagonal
|
||||
var/iStep = get_step(A,adir&(NORTH|SOUTH))
|
||||
if(!LinkBlockedWithAccess(A,iStep, ID) && !LinkBlockedWithAccess(iStep,B,ID))
|
||||
return 0
|
||||
|
||||
var/pStep = get_step(A,adir&(EAST|WEST))
|
||||
if(!LinkBlockedWithAccess(A,pStep,ID) && !LinkBlockedWithAccess(pStep,B,ID))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
if(DirBlockedWithAccess(A,adir, ID))
|
||||
return 1
|
||||
|
||||
if(DirBlockedWithAccess(B,rdir, ID))
|
||||
return 1
|
||||
|
||||
for(var/obj/O in B)
|
||||
if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
// Returns true if direction is blocked from loc
|
||||
// Checks doors against access with given ID
|
||||
/proc/DirBlockedWithAccess(turf/loc,var/dir,var/obj/item/weapon/card/id/ID)
|
||||
for(var/obj/structure/window/D in loc)
|
||||
if(!D.density) continue
|
||||
if(D.dir == SOUTHWEST) return 1
|
||||
if(D.dir == dir) return 1
|
||||
|
||||
for(var/obj/machinery/door/D in loc)
|
||||
if(!D.density) continue
|
||||
if(istype(D, /obj/machinery/door/window))
|
||||
if( dir & D.dir ) return !D.check_access(ID)
|
||||
|
||||
//if((dir & SOUTH) && (D.dir & (EAST|WEST))) return !D.check_access(ID)
|
||||
//if((dir & EAST ) && (D.dir & (NORTH|SOUTH))) return !D.check_access(ID)
|
||||
else return !D.check_access(ID) // it's a real, air blocking door
|
||||
return 0
|
||||
@@ -1,887 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
// Mulebot - carries crates around for Quartermaster
|
||||
// Navigates via floor navbeacons
|
||||
// Remote Controlled from QM's PDA
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot
|
||||
name = "Mulebot"
|
||||
desc = "A Multiple Utility Load Effector bot."
|
||||
icon_state = "mulebot0"
|
||||
layer = MOB_LAYER
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
health = 150 //yeah, it's tougher than ed209 because it is a big metal box with wheels --rastaf0
|
||||
maxhealth = 150
|
||||
fire_dam_coeff = 0.7
|
||||
brute_dam_coeff = 0.5
|
||||
var/atom/movable/load = null // the loaded crate (usually)
|
||||
var/beacon_freq = 1400
|
||||
var/control_freq = BOT_FREQ
|
||||
|
||||
suffix = ""
|
||||
|
||||
var/turf/target // this is turf to navigate to (location of beacon)
|
||||
var/loaddir = 0 // this the direction to unload onto/load from
|
||||
var/new_destination = "" // pending new destination (waiting for beacon response)
|
||||
var/destination = "" // destination description
|
||||
var/home_destination = "" // tag of home beacon
|
||||
req_access = list(access_cargo) // added robotics access so assembly line drop-off works properly -veyveyr //I don't think so, Tim. You need to add it to the MULE's hidden robot ID card. -NEO
|
||||
var/path[] = new()
|
||||
|
||||
var/mode = 0 //0 = idle/ready
|
||||
//1 = loading/unloading
|
||||
//2 = moving to deliver
|
||||
//3 = returning to home
|
||||
//4 = blocked
|
||||
//5 = computing navigation
|
||||
//6 = waiting for nav computation
|
||||
//7 = no destination beacon found (or no route)
|
||||
|
||||
var/blockcount = 0 //number of times retried a blocked path
|
||||
var/reached_target = 1 //true if already reached the target
|
||||
|
||||
var/refresh = 1 // true to refresh dialogue
|
||||
var/auto_return = 1 // true if auto return to home beacon after unload
|
||||
var/auto_pickup = 1 // true if auto-pickup at beacon
|
||||
|
||||
var/obj/item/weapon/cell/cell
|
||||
// the installed power cell
|
||||
|
||||
// constants for internal wiring bitflags
|
||||
var/datum/wires/mulebot/wires = null
|
||||
|
||||
var/bloodiness = 0 // count of bloodiness
|
||||
|
||||
/obj/machinery/bot/mulebot/New()
|
||||
..()
|
||||
wires = new(src)
|
||||
botcard = new(src)
|
||||
botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
|
||||
cell = new(src)
|
||||
cell.charge = 2000
|
||||
cell.maxcharge = 2000
|
||||
|
||||
spawn(5) // must wait for map loading to finish
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
|
||||
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
|
||||
var/count = 0
|
||||
for(var/obj/machinery/bot/mulebot/other in world)
|
||||
count++
|
||||
if(!suffix)
|
||||
suffix = "#[count]"
|
||||
name = "Mulebot ([suffix])"
|
||||
|
||||
/obj/machinery/bot/mulebot/Destroy()
|
||||
unload(0)
|
||||
qdel(wires)
|
||||
wires = null
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src,beacon_freq)
|
||||
radio_controller.remove_object(src,control_freq)
|
||||
return ..()
|
||||
|
||||
// attack by item
|
||||
// emag : lock/unlock,
|
||||
// screwdriver: open/close hatch
|
||||
// cell: insert it
|
||||
// other: chance to knock rider off bot
|
||||
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I,/obj/item/weapon/cell) && open && !cell)
|
||||
var/obj/item/weapon/cell/C = I
|
||||
user.drop_item()
|
||||
C.loc = src
|
||||
cell = C
|
||||
updateDialog()
|
||||
else if(istype(I,/obj/item/weapon/screwdriver))
|
||||
if(locked)
|
||||
user << "<span class='notice'>The maintenance hatch cannot be opened or closed while the controls are locked.</span>"
|
||||
return
|
||||
|
||||
open = !open
|
||||
if(open)
|
||||
src.visible_message("[user] opens the maintenance hatch of [src]", "<span class='notice'>You open [src]'s maintenance hatch.</span>")
|
||||
on = 0
|
||||
icon_state="mulebot-hatch"
|
||||
else
|
||||
src.visible_message("[user] closes the maintenance hatch of [src]", "<span class='notice'>You close [src]'s maintenance hatch.</span>")
|
||||
icon_state = "mulebot0"
|
||||
|
||||
updateDialog()
|
||||
else if (istype(I, /obj/item/weapon/wrench))
|
||||
if (src.health < maxhealth)
|
||||
src.health = min(maxhealth, src.health+25)
|
||||
user.visible_message(
|
||||
"<span class='notice'>\The [user] repairs \the [src]!</span>",
|
||||
"<span class='notice'>You repair \the [src]!</span>"
|
||||
)
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair!</span>"
|
||||
else if(load && ismob(load)) // chance to knock off rider
|
||||
if(prob(1+I.force * 2))
|
||||
unload(0)
|
||||
user.visible_message("<span class='warning'>[user] knocks [load] off [src] with \the [I]!</span>", "<span class='warning'>You knock [load] off [src] with \the [I]!</span>")
|
||||
else
|
||||
user << "You hit [src] with \the [I] but to no effect."
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/emag_act(var/remaining_charges, var/user)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
|
||||
flick("mulebot-emagged", src)
|
||||
playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0)
|
||||
return 1
|
||||
|
||||
/obj/machinery/bot/mulebot/ex_act(var/severity)
|
||||
unload(0)
|
||||
switch(severity)
|
||||
if(2)
|
||||
BITRESET(wires, rand(0,9))
|
||||
BITRESET(wires, rand(0,9))
|
||||
BITRESET(wires, rand(0,9))
|
||||
if(3)
|
||||
BITRESET(wires, rand(0,9))
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/bullet_act()
|
||||
if(prob(50) && !isnull(load))
|
||||
unload(0)
|
||||
if(prob(25))
|
||||
src.visible_message("<span class='warning'>Something shorts out inside [src]!</span>")
|
||||
var/index = 1<< (rand(0,9))
|
||||
if(wires & index)
|
||||
wires &= ~index
|
||||
else
|
||||
wires |= index
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/attack_ai(var/mob/user)
|
||||
user.set_machine(src)
|
||||
interact(user, 1)
|
||||
|
||||
/obj/machinery/bot/mulebot/attack_hand(var/mob/user)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
user.set_machine(src)
|
||||
interact(user, 0)
|
||||
|
||||
/obj/machinery/bot/mulebot/interact(var/mob/user, var/ai=0)
|
||||
var/dat
|
||||
dat += "<TT><B>Multiple Utility Load Effector Mk. III</B></TT><BR><BR>"
|
||||
dat += "ID: [suffix]<BR>"
|
||||
dat += "Power: [on ? "On" : "Off"]<BR>"
|
||||
|
||||
if(!open)
|
||||
|
||||
dat += "Status: "
|
||||
switch(mode)
|
||||
if(0)
|
||||
dat += "Ready"
|
||||
if(1)
|
||||
dat += "Loading/Unloading"
|
||||
if(2)
|
||||
dat += "Navigating to Delivery Location"
|
||||
if(3)
|
||||
dat += "Navigating to Home"
|
||||
if(4)
|
||||
dat += "Waiting for clear path"
|
||||
if(5,6)
|
||||
dat += "Calculating navigation path"
|
||||
if(7)
|
||||
dat += "Unable to locate destination"
|
||||
|
||||
|
||||
dat += "<BR>Current Load: [load ? load.name : "<i>none</i>"]<BR>"
|
||||
dat += "Destination: [!destination ? "<i>none</i>" : destination]<BR>"
|
||||
dat += "Power level: [cell ? cell.percent() : 0]%<BR>"
|
||||
|
||||
if(locked && !ai)
|
||||
dat += "<HR>Controls are locked <A href='byond://?src=\ref[src];op=unlock'><I>(unlock)</I></A>"
|
||||
else
|
||||
dat += "<HR>Controls are unlocked <A href='byond://?src=\ref[src];op=lock'><I>(lock)</I></A><BR><BR>"
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];op=power'>Toggle Power</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=stop'>Stop</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=go'>Proceed</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=home'>Return to Home</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=destination'>Set Destination</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=sethome'>Set Home</A><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
|
||||
|
||||
if(load)
|
||||
dat += "<A href='byond://?src=\ref[src];op=unload'>Unload Now</A><BR>"
|
||||
dat += "<HR>The maintenance hatch is closed.<BR>"
|
||||
|
||||
else
|
||||
if(!ai)
|
||||
dat += "The maintenance hatch is open.<BR><BR>"
|
||||
dat += "Power cell: "
|
||||
if(cell)
|
||||
dat += "<A href='byond://?src=\ref[src];op=cellremove'>Installed</A><BR>"
|
||||
else
|
||||
dat += "<A href='byond://?src=\ref[src];op=cellinsert'>Removed</A><BR>"
|
||||
|
||||
dat += wires.GetInteractWindow()
|
||||
else
|
||||
dat += "The bot is in maintenance mode and cannot be controlled.<BR>"
|
||||
|
||||
user << browse("<HEAD><TITLE>Mulebot [suffix ? "([suffix])" : ""]</TITLE></HEAD>[dat]", "window=mulebot;size=350x500")
|
||||
onclose(user, "mulebot")
|
||||
return
|
||||
|
||||
/obj/machinery/bot/mulebot/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if (usr.stat)
|
||||
return
|
||||
if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(href_list["op"])
|
||||
if("lock", "unlock")
|
||||
if(src.allowed(usr))
|
||||
locked = !locked
|
||||
updateDialog()
|
||||
else
|
||||
usr << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
if("power")
|
||||
if (src.on)
|
||||
turn_off()
|
||||
else if (cell && !open)
|
||||
if (!turn_on())
|
||||
usr << "<span class='warning'>You can't switch on [src].</span>"
|
||||
return
|
||||
else
|
||||
return
|
||||
visible_message("[usr] switches [on ? "on" : "off"] [src].")
|
||||
updateDialog()
|
||||
|
||||
|
||||
if("cellremove")
|
||||
if(open && cell && !usr.get_active_hand())
|
||||
cell.update_icon()
|
||||
usr.put_in_active_hand(cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell = null
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] removes the power cell from [src].</span>", "<span class='notice'>You remove the power cell from [src].</span>")
|
||||
updateDialog()
|
||||
|
||||
if("cellinsert")
|
||||
if(open && !cell)
|
||||
var/obj/item/weapon/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
usr.drop_item()
|
||||
cell = C
|
||||
C.loc = src
|
||||
C.add_fingerprint(usr)
|
||||
|
||||
usr.visible_message("<span class='notice'>[usr] inserts a power cell into [src].</span>", "<span class='notice'>You insert the power cell into [src].</span>")
|
||||
updateDialog()
|
||||
|
||||
|
||||
if("stop")
|
||||
if(mode >=2)
|
||||
mode = 0
|
||||
updateDialog()
|
||||
|
||||
if("go")
|
||||
if(mode == 0)
|
||||
start()
|
||||
updateDialog()
|
||||
|
||||
if("home")
|
||||
if(mode == 0 || mode == 2)
|
||||
start_home()
|
||||
updateDialog()
|
||||
|
||||
if("destination")
|
||||
refresh=0
|
||||
var/new_dest
|
||||
var/list/beaconlist = new()
|
||||
for(var/obj/machinery/navbeacon/N in navbeacons)
|
||||
beaconlist.Add(N.location)
|
||||
if(beaconlist.len)
|
||||
new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) in beaconlist
|
||||
else
|
||||
alert("No destination beacons available.")
|
||||
refresh=1
|
||||
if(new_dest)
|
||||
set_destination(new_dest)
|
||||
|
||||
|
||||
if("setid")
|
||||
refresh=0
|
||||
var/new_id = sanitize(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null, MAX_NAME_LEN)
|
||||
refresh=1
|
||||
if(new_id)
|
||||
suffix = new_id
|
||||
name = "Mulebot ([suffix])"
|
||||
updateDialog()
|
||||
|
||||
if("sethome")
|
||||
refresh=0
|
||||
var/new_home = input("Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) as text|null
|
||||
refresh=1
|
||||
if(new_home)
|
||||
home_destination = new_home
|
||||
updateDialog()
|
||||
|
||||
if("unload")
|
||||
if(load && mode !=1)
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
|
||||
if("autoret")
|
||||
auto_return = !auto_return
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = !auto_pickup
|
||||
|
||||
if("close")
|
||||
usr.unset_machine()
|
||||
usr << browse(null,"window=mulebot")
|
||||
|
||||
updateDialog()
|
||||
//src.updateUsrDialog()
|
||||
else
|
||||
usr << browse(null, "window=mulebot")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
|
||||
|
||||
// returns true if the bot has power
|
||||
/obj/machinery/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge>0 && wires.HasPower()
|
||||
|
||||
// mousedrop a crate to load the bot
|
||||
// can load anything if emagged
|
||||
|
||||
/obj/machinery/bot/mulebot/MouseDrop_T(var/atom/movable/C, mob/user)
|
||||
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
if (!on || !istype(C)|| C.anchored || get_dist(user, src) > 1 || get_dist(src,C) > 1 )
|
||||
return
|
||||
|
||||
if(load)
|
||||
return
|
||||
|
||||
load(C)
|
||||
|
||||
|
||||
// called to load a crate
|
||||
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
|
||||
if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate))
|
||||
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
return // if not emagged, only allow crates to be loaded
|
||||
|
||||
//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
|
||||
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
|
||||
if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
|
||||
return
|
||||
if(!isturf(C.loc)) //To prevent the loading from stuff from someone's inventory, which wouldn't get handled properly.
|
||||
return
|
||||
|
||||
if(get_dist(C, src) > 1 || load || !on)
|
||||
return
|
||||
for(var/obj/structure/plasticflaps/P in src.loc)//Takes flaps into account
|
||||
if(!CanPass(C,P))
|
||||
return
|
||||
mode = 1
|
||||
|
||||
// if a create, close before loading
|
||||
var/obj/structure/closet/crate/crate = C
|
||||
if(istype(crate))
|
||||
crate.close()
|
||||
|
||||
C.loc = src.loc
|
||||
sleep(2)
|
||||
if(C.loc != src.loc) //To prevent you from going onto more thano ne bot.
|
||||
return
|
||||
C.loc = src
|
||||
load = C
|
||||
|
||||
C.pixel_y += 9
|
||||
if(C.layer < layer)
|
||||
C.layer = layer + 0.1
|
||||
overlays += C
|
||||
|
||||
if(ismob(C))
|
||||
var/mob/M = C
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
|
||||
mode = 0
|
||||
send_status()
|
||||
|
||||
// called to unload the bot
|
||||
// argument is optional direction to unload
|
||||
// if zero, unload at bot's location
|
||||
/obj/machinery/bot/mulebot/proc/unload(var/dirn = 0)
|
||||
if(!load)
|
||||
return
|
||||
|
||||
mode = 1
|
||||
overlays.Cut()
|
||||
|
||||
load.loc = src.loc
|
||||
load.pixel_y -= 9
|
||||
load.layer = initial(load.layer)
|
||||
if(ismob(load))
|
||||
var/mob/M = load
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
|
||||
|
||||
if(dirn)
|
||||
var/turf/T = src.loc
|
||||
T = get_step(T,dirn)
|
||||
if(CanPass(load,T))//Can't get off onto anything that wouldn't let you pass normally
|
||||
step(load, dirn)
|
||||
else
|
||||
load.loc = src.loc//Drops you right there, so you shouldn't be able to get yourself stuck
|
||||
|
||||
load = null
|
||||
|
||||
// in case non-load items end up in contents, dump every else too
|
||||
// this seems to happen sometimes due to race conditions
|
||||
// with items dropping as mobs are loaded
|
||||
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM == cell || AM == botcard) continue
|
||||
|
||||
AM.loc = src.loc
|
||||
AM.layer = initial(AM.layer)
|
||||
AM.pixel_y = initial(AM.pixel_y)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
mode = 0
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/process()
|
||||
if(!has_power())
|
||||
on = 0
|
||||
return
|
||||
if(on)
|
||||
var/speed = (wires.Motor1() ? 1:0) + (wires.Motor2() ? 2:0)
|
||||
//world << "speed: [speed]"
|
||||
switch(speed)
|
||||
if(0)
|
||||
// do nothing
|
||||
if(1)
|
||||
process_bot()
|
||||
spawn(2)
|
||||
process_bot()
|
||||
sleep(2)
|
||||
process_bot()
|
||||
sleep(2)
|
||||
process_bot()
|
||||
sleep(2)
|
||||
process_bot()
|
||||
if(2)
|
||||
process_bot()
|
||||
spawn(4)
|
||||
process_bot()
|
||||
if(3)
|
||||
process_bot()
|
||||
|
||||
if(refresh) updateDialog()
|
||||
|
||||
/obj/machinery/bot/mulebot/proc/process_bot()
|
||||
//if(mode) world << "Mode: [mode]"
|
||||
switch(mode)
|
||||
if(0) // idle
|
||||
icon_state = "mulebot0"
|
||||
return
|
||||
if(1) // loading/unloading
|
||||
return
|
||||
if(2,3,4) // navigating to deliver,home, or blocked
|
||||
|
||||
if(loc == target) // reached target
|
||||
at_target()
|
||||
return
|
||||
|
||||
else if(path.len > 0 && target) // valid path
|
||||
|
||||
var/turf/next = path[1]
|
||||
reached_target = 0
|
||||
if(next == loc)
|
||||
path -= next
|
||||
return
|
||||
|
||||
|
||||
if(istype( next, /turf/simulated))
|
||||
//world << "at ([x],[y]) moving to ([next.x],[next.y])"
|
||||
|
||||
|
||||
if(bloodiness)
|
||||
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
|
||||
var/newdir = get_dir(next, loc)
|
||||
if(newdir == dir)
|
||||
B.set_dir(newdir)
|
||||
else
|
||||
newdir = newdir | dir
|
||||
if(newdir == 3)
|
||||
newdir = 1
|
||||
else if(newdir == 12)
|
||||
newdir = 4
|
||||
B.set_dir(newdir)
|
||||
bloodiness--
|
||||
|
||||
|
||||
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(cell) cell.use(1)
|
||||
if(moved) // successful move
|
||||
//world << "Successful move."
|
||||
blockcount = 0
|
||||
path -= loc
|
||||
|
||||
|
||||
if(mode==4)
|
||||
spawn(1)
|
||||
send_status()
|
||||
|
||||
if(destination == home_destination)
|
||||
mode = 3
|
||||
else
|
||||
mode = 2
|
||||
|
||||
else // failed to move
|
||||
|
||||
//world << "Unable to move."
|
||||
|
||||
|
||||
|
||||
blockcount++
|
||||
mode = 4
|
||||
if(blockcount == 3)
|
||||
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
|
||||
if(blockcount > 5) // attempt 5 times before recomputing
|
||||
// find new path excluding blocked turf
|
||||
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
|
||||
spawn(2)
|
||||
calc_path(next)
|
||||
if(path.len > 0)
|
||||
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
mode = 4
|
||||
mode =6
|
||||
return
|
||||
return
|
||||
else
|
||||
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
//world << "Bad turf."
|
||||
mode = 5
|
||||
return
|
||||
else
|
||||
//world << "No path."
|
||||
mode = 5
|
||||
return
|
||||
|
||||
if(5) // calculate new path
|
||||
//world << "Calc new path."
|
||||
mode = 6
|
||||
spawn(0)
|
||||
|
||||
calc_path()
|
||||
|
||||
if(path.len > 0)
|
||||
blockcount = 0
|
||||
mode = 4
|
||||
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
|
||||
else
|
||||
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
|
||||
mode = 7
|
||||
//if(6)
|
||||
//world << "Pending path calc."
|
||||
//if(7)
|
||||
//world << "No dest / no route."
|
||||
return
|
||||
|
||||
|
||||
// calculates a path to the current destination
|
||||
// given an optional turf to avoid
|
||||
/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
|
||||
src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid)
|
||||
if(!src.path)
|
||||
src.path = list()
|
||||
|
||||
|
||||
// sets the current destination
|
||||
// signals all beacons matching the delivery code
|
||||
// beacons will return a signal giving their locations
|
||||
/obj/machinery/bot/mulebot/proc/set_destination(var/new_dest)
|
||||
spawn(0)
|
||||
new_destination = new_dest
|
||||
post_signal(beacon_freq, "findbeacon", "delivery")
|
||||
updateDialog()
|
||||
|
||||
// starts bot moving to current destination
|
||||
/obj/machinery/bot/mulebot/proc/start()
|
||||
if(destination == home_destination)
|
||||
mode = 3
|
||||
else
|
||||
mode = 2
|
||||
icon_state = "mulebot[wires.MobAvoid()]"
|
||||
|
||||
// starts bot moving to home
|
||||
// sends a beacon query to find
|
||||
/obj/machinery/bot/mulebot/proc/start_home()
|
||||
spawn(0)
|
||||
set_destination(home_destination)
|
||||
mode = 4
|
||||
icon_state = "mulebot[wires.MobAvoid()]"
|
||||
|
||||
// called when bot reaches current target
|
||||
/obj/machinery/bot/mulebot/proc/at_target()
|
||||
if(!reached_target)
|
||||
src.visible_message("[src] makes a chiming sound!", "You hear a chime.")
|
||||
playsound(src.loc, 'sound/machines/chime.ogg', 50, 0)
|
||||
reached_target = 1
|
||||
|
||||
if(load) // if loaded, unload at target
|
||||
unload(loaddir)
|
||||
else
|
||||
// not loaded
|
||||
if(auto_pickup) // find a crate
|
||||
var/atom/movable/AM
|
||||
if(!wires.LoadCheck()) // if emagged, load first unanchored thing we find
|
||||
for(var/atom/movable/A in get_step(loc, loaddir))
|
||||
if(!A.anchored)
|
||||
AM = A
|
||||
break
|
||||
else // otherwise, look for crates only
|
||||
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
|
||||
if(AM)
|
||||
load(AM)
|
||||
// whatever happened, check to see if we return home
|
||||
|
||||
if(auto_return && destination != home_destination)
|
||||
// auto return set and not at home already
|
||||
start_home()
|
||||
mode = 4
|
||||
else
|
||||
mode = 0 // otherwise go idle
|
||||
|
||||
send_status() // report status to anyone listening
|
||||
|
||||
return
|
||||
|
||||
// called when bot bumps into anything
|
||||
/obj/machinery/bot/mulebot/Bump(var/atom/obs)
|
||||
if(!wires.MobAvoid()) //usually just bumps, but if avoidance disabled knock over mobs
|
||||
var/mob/M = obs
|
||||
if(ismob(M))
|
||||
if(istype(M,/mob/living/silicon/robot))
|
||||
src.visible_message("<span class='warning'>[src] bumps into [M]!</span>")
|
||||
else
|
||||
src.visible_message("<span class='warning'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
M.lying = 1
|
||||
..()
|
||||
|
||||
// called from mob/living/carbon/human/Crossed()
|
||||
// when mulebot is in the same loc
|
||||
/obj/machinery/bot/mulebot/proc/RunOver(var/mob/living/carbon/human/H)
|
||||
src.visible_message("<span class='warning'>[src] drives over [H]!</span>")
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/damage = rand(5,15)
|
||||
H.apply_damage(2*damage, BRUTE, BP_HEAD)
|
||||
H.apply_damage(2*damage, BRUTE, BP_TORSO)
|
||||
H.apply_damage(0.5*damage, BRUTE, BP_L_LEG)
|
||||
H.apply_damage(0.5*damage, BRUTE, BP_R_LEG)
|
||||
H.apply_damage(0.5*damage, BRUTE, BP_L_ARM)
|
||||
H.apply_damage(0.5*damage, BRUTE, BP_R_ARM)
|
||||
|
||||
blood_splatter(src,H,1)
|
||||
bloodiness += 4
|
||||
|
||||
// player on mulebot attempted to move
|
||||
/obj/machinery/bot/mulebot/relaymove(var/mob/user)
|
||||
if(user.stat)
|
||||
return
|
||||
if(load == user)
|
||||
unload(0)
|
||||
return
|
||||
|
||||
// receive a radio signal
|
||||
// used for control and beacon reception
|
||||
|
||||
/obj/machinery/bot/mulebot/receive_signal(datum/signal/signal)
|
||||
|
||||
if(!on)
|
||||
return
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
// process all-bot input
|
||||
if(recv=="bot_status" && wires.RemoteRX())
|
||||
send_status()
|
||||
|
||||
|
||||
recv = signal.data["command [suffix]"]
|
||||
if(wires.RemoteRX())
|
||||
// process control input
|
||||
switch(recv)
|
||||
if("stop")
|
||||
mode = 0
|
||||
return
|
||||
|
||||
if("go")
|
||||
start()
|
||||
return
|
||||
|
||||
if("target")
|
||||
set_destination(signal.data["destination"] )
|
||||
return
|
||||
|
||||
if("unload")
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
return
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
return
|
||||
|
||||
if("bot_status")
|
||||
send_status()
|
||||
return
|
||||
|
||||
if("autoret")
|
||||
auto_return = text2num(signal.data["value"])
|
||||
return
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = text2num(signal.data["value"])
|
||||
return
|
||||
|
||||
// receive response from beacon
|
||||
recv = signal.data["beacon"]
|
||||
if(wires.BeaconRX())
|
||||
if(recv == new_destination) // if the recvd beacon location matches the set destination
|
||||
// the we will navigate there
|
||||
destination = new_destination
|
||||
target = signal.source.loc
|
||||
var/direction = signal.data["dir"] // this will be the load/unload dir
|
||||
if(direction)
|
||||
loaddir = text2num(direction)
|
||||
else
|
||||
loaddir = 0
|
||||
icon_state = "mulebot[wires.MobAvoid()]"
|
||||
calc_path()
|
||||
updateDialog()
|
||||
|
||||
// send a radio signal with a single data key/value pair
|
||||
/obj/machinery/bot/mulebot/proc/post_signal(var/freq, var/key, var/value)
|
||||
post_signal_multiple(freq, list("[key]" = value) )
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/obj/machinery/bot/mulebot/proc/post_signal_multiple(var/freq, var/list/keyval)
|
||||
|
||||
if(freq == beacon_freq && !wires.BeaconRX())
|
||||
return
|
||||
if(freq == control_freq && !wires.RemoteTX())
|
||||
return
|
||||
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
|
||||
|
||||
if(!frequency) return
|
||||
|
||||
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
//for(var/key in keyval)
|
||||
// signal.data[key] = keyval[key]
|
||||
signal.data = keyval
|
||||
//world << "sent [key],[keyval[key]] on [freq]"
|
||||
if (signal.data["findbeacon"])
|
||||
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
|
||||
else if (signal.data["type"] == "mulebot")
|
||||
frequency.post_signal(src, signal, filter = RADIO_MULEBOT)
|
||||
else
|
||||
frequency.post_signal(src, signal)
|
||||
|
||||
// signals bot status etc. to controller
|
||||
/obj/machinery/bot/mulebot/proc/send_status()
|
||||
var/list/kv = list(
|
||||
"type" = "mulebot",
|
||||
"name" = suffix,
|
||||
"loca" = (loc ? loc.loc : "Unknown"), // somehow loc can be null and cause a runtime - Quarxink
|
||||
"mode" = mode,
|
||||
"powr" = (cell ? cell.percent() : 0),
|
||||
"dest" = destination,
|
||||
"home" = home_destination,
|
||||
"load" = load,
|
||||
"retn" = auto_return,
|
||||
"pick" = auto_pickup,
|
||||
)
|
||||
post_signal_multiple(control_freq, kv)
|
||||
|
||||
/obj/machinery/bot/mulebot/emp_act(severity)
|
||||
if (cell)
|
||||
cell.emp_act(severity)
|
||||
if(load)
|
||||
load.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/bot/mulebot/explode()
|
||||
src.visible_message("<span class='danger'>[src] blows apart!</span>", 1)
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
PoolOrNew(/obj/item/stack/rods, Tsec)
|
||||
PoolOrNew(/obj/item/stack/rods, Tsec)
|
||||
new /obj/item/stack/cable_coil/cut(Tsec)
|
||||
if (cell)
|
||||
cell.loc = Tsec
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
||||
unload(0)
|
||||
qdel(src)
|
||||
@@ -118,7 +118,7 @@
|
||||
add_hiddenprint(user)
|
||||
destroy()
|
||||
|
||||
/obj/machinery/camera/attackby(obj/W as obj, mob/living/user as mob)
|
||||
/obj/machinery/camera/attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
update_coverage()
|
||||
// DECONSTRUCTION
|
||||
if(isscrewdriver(W))
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
usr << "No input found please hang up and try your call again."
|
||||
return
|
||||
|
||||
var/list/tempnetwork = text2list(input, ",")
|
||||
var/list/tempnetwork = splittext(input, ",")
|
||||
if(tempnetwork.len < 1)
|
||||
usr << "No network found please hang up and try your call again."
|
||||
return
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
if(ckey(clonemind.key) != R.ckey)
|
||||
return 0
|
||||
else
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
for(var/mob/observer/dead/G in player_list)
|
||||
if(G.ckey == R.ckey)
|
||||
if(G.can_reenter_corpse)
|
||||
break
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
var/cam = C.nano_structure()
|
||||
cameras[++cameras.len] = cam
|
||||
|
||||
camera_cache=list2json(cameras)
|
||||
camera_cache=json_encode(cameras)
|
||||
|
||||
if(current)
|
||||
data["current"] = current.nano_structure()
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
|
||||
if(scan)
|
||||
usr << "You remove \the [scan] from \the [src]."
|
||||
scan.loc = get_turf(src)
|
||||
scan.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
|
||||
usr.put_in_hands(scan)
|
||||
scan = null
|
||||
else if(modify)
|
||||
usr << "You remove \the [modify] from \the [src]."
|
||||
modify.loc = get_turf(src)
|
||||
modify.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
|
||||
usr.put_in_hands(modify)
|
||||
modify = null
|
||||
@@ -60,10 +60,12 @@
|
||||
return ..()
|
||||
|
||||
if(!scan && (access_change_ids in id_card.access) && user.unEquip(id_card))
|
||||
id_card.loc = src
|
||||
user.drop_item()
|
||||
id_card.forceMove(src)
|
||||
scan = id_card
|
||||
else if(!modify)
|
||||
id_card.loc = src
|
||||
user.drop_item()
|
||||
id_card.forceMove(src)
|
||||
modify = id_card
|
||||
|
||||
nanomanager.update_uis(src)
|
||||
@@ -146,34 +148,34 @@
|
||||
data_core.manifest_modify(modify.registered_name, modify.assignment)
|
||||
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
|
||||
if(ishuman(usr))
|
||||
modify.loc = usr.loc
|
||||
modify.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(modify)
|
||||
modify = null
|
||||
else
|
||||
modify.loc = loc
|
||||
modify.forceMove(get_turf(src))
|
||||
modify = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
|
||||
I.loc = src
|
||||
I.forceMove(src)
|
||||
modify = I
|
||||
|
||||
if ("scan")
|
||||
if (scan)
|
||||
if(ishuman(usr))
|
||||
scan.loc = usr.loc
|
||||
scan.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(scan)
|
||||
scan = null
|
||||
else
|
||||
scan.loc = src.loc
|
||||
scan.forceMove(get_turf(src))
|
||||
scan = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
I.forceMove(src)
|
||||
scan = I
|
||||
|
||||
if("access")
|
||||
|
||||
@@ -78,34 +78,23 @@
|
||||
crew_announcement.announcer = ""
|
||||
|
||||
if("swipeidseclevel")
|
||||
var/mob/M = usr
|
||||
var/obj/item/weapon/card/id/I = M.get_active_hand()
|
||||
if (istype(I, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = I
|
||||
I = pda.id
|
||||
if (I && istype(I))
|
||||
if(access_captain in I.access || access_heads in I.access) //Let heads change the alert level.
|
||||
var/old_level = security_level
|
||||
if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
|
||||
if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
|
||||
if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
|
||||
set_security_level(tmp_alertlevel)
|
||||
if(security_level != old_level)
|
||||
//Only notify the admins if an actual change happened
|
||||
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
|
||||
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
|
||||
switch(security_level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
feedback_inc("alert_comms_green",1)
|
||||
if(SEC_LEVEL_BLUE)
|
||||
feedback_inc("alert_comms_blue",1)
|
||||
tmp_alertlevel = 0
|
||||
else:
|
||||
usr << "You are not authorized to do this."
|
||||
tmp_alertlevel = 0
|
||||
if(src.authenticated) //Let heads change the alert level.
|
||||
var/old_level = security_level
|
||||
if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
|
||||
if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
|
||||
if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
|
||||
set_security_level(tmp_alertlevel)
|
||||
if(security_level != old_level)
|
||||
//Only notify the admins if an actual change happened
|
||||
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
|
||||
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
|
||||
switch(security_level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
feedback_inc("alert_comms_green",1)
|
||||
if(SEC_LEVEL_BLUE)
|
||||
feedback_inc("alert_comms_blue",1)
|
||||
tmp_alertlevel = 0
|
||||
state = STATE_DEFAULT
|
||||
else
|
||||
usr << "You need to swipe your ID."
|
||||
|
||||
if("announce")
|
||||
if(src.authenticated==2)
|
||||
@@ -368,7 +357,7 @@
|
||||
if(STATE_CONFIRM_LEVEL)
|
||||
dat += "Current alert level: [get_security_level()]<BR>"
|
||||
dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]<BR>"
|
||||
dat += "<A HREF='?src=\ref[src];operation=swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
|
||||
dat += "<A HREF='?src=\ref[src];operation=swipeidseclevel'>OK</A> to confirm change.<BR>"
|
||||
|
||||
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
|
||||
user << browse(dat, "window=communications;size=400x500")
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
return
|
||||
|
||||
// Antagonistic cyborgs? Left here for downstream
|
||||
if(target.mind && target.mind.special_role && target.emagged)
|
||||
if(target.mind && (target.mind.special_role || target.emagged))
|
||||
target << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
|
||||
target.ResetSecurityCodes()
|
||||
else
|
||||
@@ -101,6 +101,7 @@
|
||||
else
|
||||
target.canmove = !target.canmove
|
||||
target.lockcharge = !target.canmove //when canmove is 1, lockcharge should be 0
|
||||
target.lockdown = !target.canmove
|
||||
if (target.lockcharge)
|
||||
target << "You have been locked down!"
|
||||
else
|
||||
@@ -115,8 +116,8 @@
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
// Antag AI checks
|
||||
if(!istype(user, /mob/living/silicon/ai) || !(user.mind.special_role && user.mind.original == user))
|
||||
// Antag synthetic checks
|
||||
if(!istype(user, /mob/living/silicon) || !(user.mind.special_role && user.mind.original == user))
|
||||
user << "Access Denied"
|
||||
return
|
||||
|
||||
@@ -131,7 +132,7 @@
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] emagged [target.name] using robotic console!</span>")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] emagged [target.name] using the robotic console!</span>")
|
||||
log_game("[key_name(usr)] emagged [target.name] using robotic console!")
|
||||
target.emagged = 1
|
||||
target << "<span class='notice'>Failsafe protocols overriden. New tools available.</span>"
|
||||
@@ -202,8 +203,12 @@
|
||||
robot["module"] = R.module ? R.module.name : "None"
|
||||
robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None"
|
||||
robot["hackable"] = 0
|
||||
//Antag synths should be able to hack themselves and see their hacked status.
|
||||
if(operator && isrobot(operator) && (operator.mind.special_role && operator.mind.original == operator) && (operator == R))
|
||||
robot["hacked"] = R.emagged ? 1 : 0
|
||||
robot["hackable"] = R.emagged? 0 : 1
|
||||
// Antag AIs know whether linked cyborgs are hacked or not.
|
||||
if(operator && istype(operator, /mob/living/silicon/ai) && (R.connected_ai == operator) && (operator.mind.special_role && operator.mind.original == operator))
|
||||
if(operator && isAI(operator) && (R.connected_ai == operator) && (operator.mind.special_role && operator.mind.original == operator))
|
||||
robot["hacked"] = R.emagged ? 1 : 0
|
||||
robot["hackable"] = R.emagged? 0 : 1
|
||||
robots.Add(list(robot))
|
||||
|
||||
@@ -286,7 +286,7 @@ What a mess.*/
|
||||
return
|
||||
Perp = new/list()
|
||||
t1 = lowertext(t1)
|
||||
var/list/components = text2list(t1, " ")
|
||||
var/list/components = splittext(t1, " ")
|
||||
if(components.len > 5)
|
||||
return //Lets not let them search too greedily.
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
|
||||
@@ -219,7 +219,7 @@ What a mess.*/
|
||||
return
|
||||
Perp = new/list()
|
||||
t1 = lowertext(t1)
|
||||
var/list/components = text2list(t1, " ")
|
||||
var/list/components = splittext(t1, " ")
|
||||
if(components.len > 5)
|
||||
return //Lets not let them search too greedily.
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
reqform.info += "RANK: [idrank]<br>"
|
||||
reqform.info += "REASON: [reason]<br>"
|
||||
reqform.info += "SUPPLY CRATE TYPE: [P.name]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [replacetext(get_access_desc(P.access))]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [get_access_desc(P.access)]<br>"
|
||||
reqform.info += "CONTENTS:<br>"
|
||||
reqform.info += P.manifest
|
||||
reqform.info += "<hr>"
|
||||
@@ -310,7 +310,7 @@
|
||||
reqform.info += "RANK: [idrank]<br>"
|
||||
reqform.info += "REASON: [reason]<br>"
|
||||
reqform.info += "SUPPLY CRATE TYPE: [P.name]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [replacetext(get_access_desc(P.access))]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [get_access_desc(P.access)]<br>"
|
||||
reqform.info += "CONTENTS:<br>"
|
||||
reqform.info += P.manifest
|
||||
reqform.info += "<hr>"
|
||||
|
||||
@@ -305,7 +305,7 @@ What a mess.*/
|
||||
return
|
||||
Perp = new/list()
|
||||
t1 = lowertext(t1)
|
||||
var/list/components = text2list(t1, " ")
|
||||
var/list/components = splittext(t1, " ")
|
||||
if(components.len > 5)
|
||||
return //Lets not let them search too greedily.
|
||||
for(var/datum/data/record/R in data_core.general)
|
||||
|
||||
@@ -103,13 +103,6 @@
|
||||
bumpopen(M)
|
||||
return
|
||||
|
||||
if(istype(AM, /obj/machinery/bot))
|
||||
var/obj/machinery/bot/bot = AM
|
||||
if(src.check_access(bot.botcard))
|
||||
if(density)
|
||||
open()
|
||||
return
|
||||
|
||||
if(istype(AM, /mob/living/bot))
|
||||
var/mob/living/bot/bot = AM
|
||||
if(src.check_access(bot.botcard))
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
//this is the master controller, that things will try to dock with.
|
||||
/obj/machinery/embedded_controller/radio/docking_port_multi
|
||||
name = "docking port controller"
|
||||
|
||||
|
||||
var/child_tags_txt
|
||||
var/child_names_txt
|
||||
var/list/child_names = list()
|
||||
|
||||
|
||||
var/datum/computer/file/embedded_program/docking/multi/docking_program
|
||||
|
||||
/obj/machinery/embedded_controller/radio/docking_port_multi/initialize()
|
||||
..()
|
||||
docking_program = new/datum/computer/file/embedded_program/docking/multi(src)
|
||||
program = docking_program
|
||||
|
||||
var/list/names = text2list(child_names_txt, ";")
|
||||
var/list/tags = text2list(child_tags_txt, ";")
|
||||
|
||||
|
||||
var/list/names = splittext(child_names_txt, ";")
|
||||
var/list/tags = splittext(child_tags_txt, ";")
|
||||
|
||||
if (names.len == tags.len)
|
||||
for (var/i = 1; i <= tags.len; i++)
|
||||
child_names[tags[i]] = names[i]
|
||||
@@ -84,10 +84,10 @@
|
||||
/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
|
||||
var/clean = 0
|
||||
switch(href_list["command"]) //anti-HTML-hacking checks
|
||||
if("cycle_ext")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
if (istype(M,/obj/machinery/embedded_controller/radio/docking_port_multi)) //if our parent controller is the right type, then we can auto-init stuff at construction
|
||||
var/obj/machinery/embedded_controller/radio/docking_port_multi/controller = M
|
||||
//parse child_tags_txt and create child tags
|
||||
children_tags = text2list(controller.child_tags_txt, ";")
|
||||
children_tags = splittext(controller.child_tags_txt, ";")
|
||||
|
||||
children_ready = list()
|
||||
children_override = list()
|
||||
|
||||
@@ -49,7 +49,7 @@ var/global/list/navbeacons // no I don't like putting this in, but it will do
|
||||
|
||||
codes = new()
|
||||
|
||||
var/list/entries = text2list(codes_txt, ";") // entries are separated by semicolons
|
||||
var/list/entries = splittext(codes_txt, ";") // entries are separated by semicolons
|
||||
|
||||
for(var/e in entries)
|
||||
var/index = findtext(e, "=") // format is "key=value"
|
||||
|
||||
@@ -502,7 +502,7 @@ var/list/turret_icons
|
||||
if(isanimal(L) || issmall(L)) // Animals are not so dangerous
|
||||
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
|
||||
|
||||
if(isxenomorph(L) || isalien(L)) // Xenos are dangerous
|
||||
if(isalien(L)) // Xenos are dangerous
|
||||
return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET
|
||||
|
||||
if(ishuman(L)) //if the target is a human, analyze threat level
|
||||
|
||||
@@ -298,7 +298,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
|
||||
continue
|
||||
|
||||
// Ghosts hearing all radio chat don't want to hear syndicate intercepts, they're duplicates
|
||||
if(data == 3 && istype(R, /mob/dead/observer) && R.client && R.client.prefs && (R.client.prefs.toggles & CHAT_GHOSTRADIO))
|
||||
if(data == 3 && istype(R, /mob/observer/dead) && R.client && R.client.prefs && (R.client.prefs.toggles & CHAT_GHOSTRADIO))
|
||||
continue
|
||||
|
||||
// --- Check for compression ---
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
if(..()) return
|
||||
|
||||
/* Ghosts can't use this one because it's a direct selection */
|
||||
if(istype(user, /mob/dead/observer)) return
|
||||
if(istype(user, /mob/observer/dead)) return
|
||||
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
wires = new(src)
|
||||
spawn(4)
|
||||
if(src.product_slogans)
|
||||
src.slogan_list += text2list(src.product_slogans, ";")
|
||||
src.slogan_list += splittext(src.product_slogans, ";")
|
||||
|
||||
// So not all machines speak at the exact same time.
|
||||
// The first time this machine says something will be at slogantime + this random value,
|
||||
@@ -104,7 +104,7 @@
|
||||
src.last_slogan = world.time + rand(0, slogan_delay)
|
||||
|
||||
if(src.product_ads)
|
||||
src.ads_list += text2list(src.product_ads, ";")
|
||||
src.ads_list += splittext(src.product_ads, ";")
|
||||
|
||||
src.build_inventory()
|
||||
power_change()
|
||||
@@ -255,31 +255,16 @@
|
||||
usr << "\icon[cashmoney] <span class='warning'>That is not enough money.</span>"
|
||||
return 0
|
||||
|
||||
if(istype(cashmoney, /obj/item/weapon/spacecash/bundle))
|
||||
// Bundles can just have money subtracted, and will work
|
||||
if(istype(cashmoney, /obj/item/weapon/spacecash))
|
||||
|
||||
visible_message("<span class='info'>\The [usr] inserts some cash into \the [src].</span>")
|
||||
var/obj/item/weapon/spacecash/bundle/cashmoney_bundle = cashmoney
|
||||
cashmoney_bundle.worth -= currently_vending.price
|
||||
cashmoney.worth -= currently_vending.price
|
||||
|
||||
if(cashmoney_bundle.worth <= 0)
|
||||
usr.drop_from_inventory(cashmoney_bundle)
|
||||
qdel(cashmoney_bundle)
|
||||
if(cashmoney.worth <= 0)
|
||||
usr.drop_from_inventory(cashmoney)
|
||||
qdel(cashmoney)
|
||||
else
|
||||
cashmoney_bundle.update_icon()
|
||||
else
|
||||
// Bills (banknotes) cannot really have worth different than face value,
|
||||
// so we have to eat the bill and spit out change in a bundle
|
||||
// This is really dirty, but there's no superclass for all bills, so we
|
||||
// just assume that all spacecash that's not something else is a bill
|
||||
|
||||
visible_message("<span class='info'>\The [usr] inserts a bill into \the [src].</span>")
|
||||
var/left = cashmoney.worth - currently_vending.price
|
||||
usr.drop_from_inventory(cashmoney)
|
||||
qdel(cashmoney)
|
||||
|
||||
if(left)
|
||||
spawn_money(left, src.loc, user)
|
||||
cashmoney.update_icon()
|
||||
|
||||
// Vending machines have no idea who paid with cash
|
||||
credit_purchase("(cash)")
|
||||
|
||||
@@ -218,6 +218,24 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc)
|
||||
AM.throw_at(target,missile_range, missile_speed, chassis)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare
|
||||
name = "\improper BNI Flare Launcher"
|
||||
icon_state = "mecha_flaregun"
|
||||
projectile = /obj/item/device/flashlight/flare
|
||||
fire_sound = 'sound/weapons/tablehit1.ogg'
|
||||
auto_rearm = 1
|
||||
fire_cooldown = 20
|
||||
projectiles_per_shot = 1
|
||||
projectile_energy_cost = 20
|
||||
missile_speed = 1
|
||||
missile_range = 15
|
||||
required_type = /obj/mecha //Why restrict it to just mining or combat mechs?
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc)
|
||||
var/obj/item/device/flashlight/flare/fired = AM
|
||||
fired.ignite()
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
|
||||
name = "\improper SRM-8 missile rack"
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new
|
||||
var/lights = 0
|
||||
var/lights_power = 6
|
||||
var/force = 0
|
||||
|
||||
//inner atmos
|
||||
var/use_internal_tank = 0
|
||||
|
||||
@@ -1,440 +0,0 @@
|
||||
/* Alien Effects!
|
||||
* Contains:
|
||||
* effect/alien
|
||||
* Resin
|
||||
* Weeds
|
||||
* Acid
|
||||
* Egg
|
||||
*/
|
||||
|
||||
/*
|
||||
* effect/alien
|
||||
*/
|
||||
/obj/effect/alien
|
||||
name = "alien thing"
|
||||
desc = "theres something alien about this"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/*
|
||||
* Resin
|
||||
*/
|
||||
/obj/effect/alien/resin
|
||||
name = "resin"
|
||||
desc = "Looks like some kind of slimy growth."
|
||||
icon_state = "resin"
|
||||
|
||||
density = 1
|
||||
opacity = 1
|
||||
anchored = 1
|
||||
var/health = 200
|
||||
//var/mob/living/affecting = null
|
||||
|
||||
/obj/effect/alien/resin/wall
|
||||
name = "resin wall"
|
||||
desc = "Purple slime solidified into a wall."
|
||||
icon_state = "resinwall" //same as resin, but consistency ho!
|
||||
|
||||
/obj/effect/alien/resin/membrane
|
||||
name = "resin membrane"
|
||||
desc = "Purple slime just thin enough to let light pass through."
|
||||
icon_state = "resinmembrane"
|
||||
opacity = 0
|
||||
health = 120
|
||||
|
||||
/obj/effect/alien/resin/New()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
|
||||
|
||||
/obj/effect/alien/resin/Destroy()
|
||||
var/turf/T = get_turf(src)
|
||||
T.thermal_conductivity = initial(T.thermal_conductivity)
|
||||
..()
|
||||
|
||||
/obj/effect/alien/resin/proc/healthcheck()
|
||||
if(health <=0)
|
||||
density = 0
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/bullet_act(var/obj/item/projectile/Proj)
|
||||
health -= Proj.damage
|
||||
..()
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
health-=50
|
||||
if(2.0)
|
||||
health-=50
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
health-=50
|
||||
else
|
||||
health-=25
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/hitby(AM as mob|obj)
|
||||
..()
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span class='danger'>[src] was hit by [AM].</span>", 1)
|
||||
var/tforce = 0
|
||||
if(ismob(AM))
|
||||
tforce = 10
|
||||
else
|
||||
tforce = AM:throwforce
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||
health = max(0, health - tforce)
|
||||
healthcheck()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/attack_hand()
|
||||
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if (HULK in usr.mutations)
|
||||
usr << "<span class='notice'>You easily destroy the [name].</span>"
|
||||
for(var/mob/O in oviewers(src))
|
||||
O.show_message("<span class='warning'>[usr] destroys the [name]!</span>", 1)
|
||||
health = 0
|
||||
else
|
||||
|
||||
// Aliens can get straight through these.
|
||||
if(istype(usr,/mob/living/carbon))
|
||||
var/mob/living/carbon/M = usr
|
||||
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
|
||||
for(var/mob/O in oviewers(src))
|
||||
O.show_message("<span class='warning'>[usr] strokes the [name] and it melts away!</span>", 1)
|
||||
health = 0
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
usr << "<span class='notice'>You claw at the [name].</span>"
|
||||
for(var/mob/O in oviewers(src))
|
||||
O.show_message("<span class='warning'>[usr] claws at the [name]!</span>", 1)
|
||||
health -= rand(5,10)
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
var/aforce = W.force
|
||||
health = max(0, health - aforce)
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||
healthcheck()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/effect/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group) return 0
|
||||
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||
return !opacity
|
||||
return !density
|
||||
|
||||
|
||||
/*
|
||||
* Weeds
|
||||
*/
|
||||
#define NODERANGE 3
|
||||
|
||||
/obj/effect/alien/weeds
|
||||
name = "weeds"
|
||||
desc = "Weird purple weeds."
|
||||
icon_state = "weeds"
|
||||
|
||||
anchored = 1
|
||||
density = 0
|
||||
layer = 2
|
||||
var/health = 15
|
||||
var/obj/effect/alien/weeds/node/linked_node = null
|
||||
|
||||
/obj/effect/alien/weeds/node
|
||||
icon_state = "weednode"
|
||||
name = "purple sac"
|
||||
desc = "Weird purple octopus-like thing."
|
||||
layer = 3
|
||||
light_range = NODERANGE
|
||||
var/node_range = NODERANGE
|
||||
|
||||
/obj/effect/alien/weeds/node/New()
|
||||
..(src.loc, src)
|
||||
|
||||
|
||||
/obj/effect/alien/weeds/New(pos, node)
|
||||
..()
|
||||
if(istype(loc, /turf/space))
|
||||
qdel(src)
|
||||
return
|
||||
linked_node = node
|
||||
if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
|
||||
spawn(rand(150, 200))
|
||||
if(src)
|
||||
Life()
|
||||
return
|
||||
|
||||
/obj/effect/alien/weeds/proc/Life()
|
||||
set background = 1
|
||||
var/turf/U = get_turf(src)
|
||||
/*
|
||||
if (locate(/obj/movable, U))
|
||||
U = locate(/obj/movable, U)
|
||||
if(U.density == 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
Alien plants should do something if theres a lot of poison
|
||||
if(U.poison> 200000)
|
||||
health -= round(U.poison/200000)
|
||||
update()
|
||||
return
|
||||
*/
|
||||
if (istype(U, /turf/space))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
|
||||
return
|
||||
|
||||
direction_loop:
|
||||
for(var/dirn in cardinal)
|
||||
var/turf/T = get_step(src, dirn)
|
||||
|
||||
if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
|
||||
continue
|
||||
|
||||
// if (locate(/obj/movable, T)) // don't propogate into movables
|
||||
// continue
|
||||
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
continue direction_loop
|
||||
|
||||
PoolOrNew(/obj/effect/alien/weeds, T, linked_node)
|
||||
|
||||
|
||||
/obj/effect/alien/weeds/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
if(3.0)
|
||||
if (prob(5))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(W.attack_verb.len)
|
||||
visible_message("<span class='danger'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
|
||||
var/damage = W.force / 4.0
|
||||
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
|
||||
if(WT.remove_fuel(0, user))
|
||||
damage = 15
|
||||
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
|
||||
health -= damage
|
||||
healthcheck()
|
||||
|
||||
/obj/effect/alien/weeds/proc/healthcheck()
|
||||
if(health <= 0)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300 + T0C)
|
||||
health -= 5
|
||||
healthcheck()
|
||||
|
||||
#undef NODERANGE
|
||||
|
||||
|
||||
/*
|
||||
* Acid
|
||||
*/
|
||||
/obj/effect/alien/acid
|
||||
name = "acid"
|
||||
desc = "Burbling corrossive stuff. I wouldn't want to touch it."
|
||||
icon_state = "acid"
|
||||
|
||||
density = 0
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
|
||||
var/atom/target
|
||||
var/ticks = 0
|
||||
var/target_strength = 0
|
||||
|
||||
/obj/effect/alien/acid/New(loc, target)
|
||||
..(loc)
|
||||
src.target = target
|
||||
|
||||
if(isturf(target)) // Turf take twice as long to take down.
|
||||
target_strength = 8
|
||||
else
|
||||
target_strength = 4
|
||||
tick()
|
||||
|
||||
/obj/effect/alien/acid/proc/tick()
|
||||
if(!target)
|
||||
qdel(src)
|
||||
|
||||
ticks += 1
|
||||
|
||||
if(ticks >= target_strength)
|
||||
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span class='alium'>[src.target] collapses under its own weight into a puddle of goop and undigested debris!</span>", 1)
|
||||
|
||||
if(istype(target, /turf/simulated/wall)) // I hate turf code.
|
||||
var/turf/simulated/wall/W = target
|
||||
W.dismantle_wall(1)
|
||||
else
|
||||
qdel(target)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
switch(target_strength - ticks)
|
||||
if(6)
|
||||
visible_message("<span class='alium'>[src.target] is holding up against the acid!</span>")
|
||||
if(4)
|
||||
visible_message("<span class='alium'>[src.target]\s structure is being melted by the acid!</span>")
|
||||
if(2)
|
||||
visible_message("<span class='alium'>[src.target] is struggling to withstand the acid!</span>")
|
||||
if(0 to 1)
|
||||
visible_message("<span class='alium'>[src.target] begins to crumble under the acid!</span>")
|
||||
spawn(rand(150, 200)) tick()
|
||||
|
||||
/*
|
||||
* Egg
|
||||
*/
|
||||
/var/const //for the status var
|
||||
BURST = 0
|
||||
BURSTING = 1
|
||||
GROWING = 2
|
||||
GROWN = 3
|
||||
|
||||
MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger
|
||||
MAX_GROWTH_TIME = 3000
|
||||
|
||||
/obj/effect/alien/egg
|
||||
desc = "It looks like a weird egg"
|
||||
name = "egg"
|
||||
icon_state = "egg_growing"
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
var/health = 100
|
||||
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
|
||||
flags = PROXMOVE
|
||||
|
||||
/obj/effect/alien/egg/New()
|
||||
if(config.aliens_allowed)
|
||||
..()
|
||||
spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
|
||||
Grow()
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/alien/egg/attack_hand(user as mob)
|
||||
|
||||
var/mob/living/carbon/M = user
|
||||
if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs))
|
||||
return attack_hand(user)
|
||||
|
||||
switch(status)
|
||||
if(BURST)
|
||||
user << "<span class='warning'>You clear the hatched egg.</span>"
|
||||
qdel(src)
|
||||
return
|
||||
if(GROWING)
|
||||
user << "<span class='warning'>The child is not developed yet.</span>"
|
||||
return
|
||||
if(GROWN)
|
||||
user << "<span class='warning'>You retrieve the child.</span>"
|
||||
Burst(0)
|
||||
return
|
||||
|
||||
/obj/effect/alien/egg/proc/GetFacehugger()
|
||||
return locate(/obj/item/clothing/mask/facehugger) in contents
|
||||
|
||||
/obj/effect/alien/egg/proc/Grow()
|
||||
icon_state = "egg"
|
||||
status = GROWN
|
||||
new /obj/item/clothing/mask/facehugger(src)
|
||||
return
|
||||
|
||||
/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
|
||||
if(status == GROWN || status == GROWING)
|
||||
var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
|
||||
icon_state = "egg_hatched"
|
||||
flick("egg_opening", src)
|
||||
status = BURSTING
|
||||
spawn(15)
|
||||
status = BURST
|
||||
child.loc = get_turf(src)
|
||||
|
||||
if(kill && istype(child))
|
||||
child.Die()
|
||||
else
|
||||
for(var/mob/M in range(1,src))
|
||||
if(CanHug(M))
|
||||
child.Attach(M)
|
||||
break
|
||||
|
||||
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
|
||||
health -= Proj.damage
|
||||
..()
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(health <= 0)
|
||||
return
|
||||
if(W.attack_verb.len)
|
||||
src.visible_message("<span class='danger'>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
else
|
||||
src.visible_message("<span class='danger'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
var/damage = W.force / 4.0
|
||||
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
|
||||
if(WT.remove_fuel(0, user))
|
||||
damage = 15
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
|
||||
src.health -= damage
|
||||
src.healthcheck()
|
||||
|
||||
|
||||
/obj/effect/alien/egg/proc/healthcheck()
|
||||
if(health <= 0)
|
||||
Burst()
|
||||
|
||||
/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 500 + T0C)
|
||||
health -= 5
|
||||
healthcheck()
|
||||
|
||||
/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(status == GROWN)
|
||||
if(!CanHug(AM))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = AM
|
||||
if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST)
|
||||
return
|
||||
|
||||
Burst(0)
|
||||
@@ -513,16 +513,3 @@ steam.start() -- spawns the effect
|
||||
round(min(light, BOMBCAP_LIGHT_RADIUS)),
|
||||
round(min(flash, BOMBCAP_FLASH_RADIUS))
|
||||
)
|
||||
|
||||
proc/holder_damage(var/atom/holder)
|
||||
if(holder)
|
||||
var/dmglevel = 4
|
||||
|
||||
if (round(amount/8) > 0)
|
||||
dmglevel = 1
|
||||
else if (round(amount/4) > 0)
|
||||
dmglevel = 2
|
||||
else if (round(amount/2) > 0)
|
||||
dmglevel = 3
|
||||
|
||||
if(dmglevel<4) holder.ex_act(dmglevel)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
..()
|
||||
if(!H)
|
||||
return
|
||||
if(istype(H, /mob/dead/observer) && !affect_ghosts)
|
||||
if(istype(H, /mob/observer) && !affect_ghosts)
|
||||
return
|
||||
Trigger(H)
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
pressure_resistance = 5
|
||||
// causeerrorheresoifixthis
|
||||
var/obj/item/master = null
|
||||
var/list/origin_tech = null //Used by R&D to determine what research bonuses it grants.
|
||||
var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
|
||||
var/force = 0
|
||||
|
||||
var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
|
||||
var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
|
||||
|
||||
@@ -235,7 +235,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
ownrank = ownjob
|
||||
name = newname + " (" + ownjob + ")"
|
||||
|
||||
|
||||
//AI verb and proc for sending PDA messages.
|
||||
/obj/item/device/pda/ai/verb/cmd_send_pdamesg()
|
||||
set category = "AI IM"
|
||||
@@ -252,7 +251,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
var/selected = plist[c]
|
||||
create_message(usr, selected, 0)
|
||||
|
||||
|
||||
/obj/item/device/pda/ai/verb/cmd_toggle_pda_receiver()
|
||||
set category = "AI IM"
|
||||
set name = "Toggle Sender/Receiver"
|
||||
@@ -263,7 +261,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
toff = !toff
|
||||
usr << "<span class='notice'>PDA sender/receiver toggled [(toff ? "Off" : "On")]!</span>"
|
||||
|
||||
|
||||
/obj/item/device/pda/ai/verb/cmd_toggle_pda_silent()
|
||||
set category = "AI IM"
|
||||
set name = "Toggle Ringer"
|
||||
@@ -420,8 +417,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
cartdata["radio"] = 1
|
||||
if(istype(cartridge.radio, /obj/item/radio/integrated/signal))
|
||||
cartdata["radio"] = 2
|
||||
if(istype(cartridge.radio, /obj/item/radio/integrated/mule))
|
||||
cartdata["radio"] = 3
|
||||
//if(istype(cartridge.radio, /obj/item/radio/integrated/mule))
|
||||
// cartdata["radio"] = 3
|
||||
|
||||
if(mode == 2)
|
||||
cartdata["charges"] = cartridge.charges ? cartridge.charges : 0
|
||||
|
||||
@@ -124,10 +124,6 @@
|
||||
icon_state = "cart-q"
|
||||
access_quartermaster = 1
|
||||
|
||||
/obj/item/weapon/cartridge/quartermaster/initialize()
|
||||
radio = new /obj/item/radio/integrated/mule(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/cartridge/head
|
||||
name = "\improper Easy-Record DELUXE"
|
||||
icon_state = "cart-h"
|
||||
@@ -141,9 +137,6 @@
|
||||
access_janitor = 1
|
||||
access_security = 1
|
||||
|
||||
/obj/item/weapon/cartridge/hop/initialize()
|
||||
radio = new /obj/item/radio/integrated/mule(src)
|
||||
|
||||
/obj/item/weapon/cartridge/hos
|
||||
name = "\improper R.O.B.U.S.T. DELUXE"
|
||||
icon_state = "cart-hos"
|
||||
@@ -351,40 +344,26 @@
|
||||
/* MULEBOT Control (Mode: 48) */
|
||||
|
||||
if(mode==48)
|
||||
var/muleData[0]
|
||||
var/mulebotsData[0]
|
||||
if(istype(radio,/obj/item/radio/integrated/mule))
|
||||
var/obj/item/radio/integrated/mule/QC = radio
|
||||
muleData["active"] = QC.active
|
||||
if(QC.active && !isnull(QC.botstatus))
|
||||
var/area/loca = QC.botstatus["loca"]
|
||||
var/loca_name = sanitize(loca.name)
|
||||
muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"]))
|
||||
var/count = 0
|
||||
|
||||
else
|
||||
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
|
||||
for(var/mob/living/bot/mulebot/M in living_mob_list)
|
||||
if(!M.on)
|
||||
continue
|
||||
++count
|
||||
var/muleData[0]
|
||||
muleData["name"] = M.suffix
|
||||
muleData["location"] = get_area(M)
|
||||
muleData["mode"] = M.mode
|
||||
muleData["home"] = M.homeName
|
||||
muleData["target"] = M.targetName
|
||||
muleData["ref"] = "\ref[M]"
|
||||
muleData["load"] = M.load ? M.load.name : "Nothing"
|
||||
|
||||
mulebotsData[++mulebotsData.len] = muleData.Copy()
|
||||
|
||||
|
||||
var/mulebotsCount=0
|
||||
for(var/obj/machinery/bot/B in QC.botlist)
|
||||
mulebotsCount++
|
||||
if(B.loc)
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]")
|
||||
|
||||
if(!mulebotsData.len)
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
|
||||
|
||||
muleData["bots"] = mulebotsData
|
||||
muleData["count"] = mulebotsCount
|
||||
|
||||
else
|
||||
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
|
||||
muleData["active"] = 0
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
|
||||
muleData["bots"] = mulebotsData
|
||||
muleData["count"] = 0
|
||||
|
||||
values["mulebot"] = muleData
|
||||
values["mulebotcount"] = count
|
||||
values["mulebots"] = mulebotsData
|
||||
|
||||
|
||||
|
||||
@@ -575,5 +554,9 @@
|
||||
loc:mode = 43
|
||||
mode = 43
|
||||
|
||||
if("MULEbot")
|
||||
var/mob/living/bot/mulebot/M = locate(href_list["ref"])
|
||||
if(istype(M))
|
||||
M.obeyCommand(href_list["command"])
|
||||
|
||||
return 1
|
||||
|
||||
@@ -105,107 +105,6 @@
|
||||
radio_controller.remove_object(src, control_freq)
|
||||
..()
|
||||
|
||||
/obj/item/radio/integrated/mule
|
||||
var/list/botlist = null // list of bots
|
||||
var/obj/machinery/bot/mulebot/active // the active bot; if null, show bot list
|
||||
var/list/botstatus // the status signal sent by the bot
|
||||
var/list/beacons
|
||||
|
||||
var/beacon_freq = 1400
|
||||
var/control_freq = BOT_FREQ
|
||||
|
||||
// create a new QM cartridge, and register to receive bot control & beacon message
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
|
||||
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
spawn(10)
|
||||
post_signal(beacon_freq, "findbeacon", "delivery", s_filter = RADIO_NAVBEACONS)
|
||||
|
||||
// receive radio signals
|
||||
// can detect bot status signals
|
||||
// and beacon locations
|
||||
// create/populate lists as they are recvd
|
||||
|
||||
receive_signal(datum/signal/signal)
|
||||
// var/obj/item/device/pda/P = src.loc
|
||||
|
||||
/*
|
||||
world << "recvd:[P] : [signal.source]"
|
||||
for(var/d in signal.data)
|
||||
world << "- [d] = [signal.data[d]]"
|
||||
*/
|
||||
if(signal.data["type"] == "mulebot")
|
||||
if(!botlist)
|
||||
botlist = new()
|
||||
|
||||
if(!(signal.source in botlist))
|
||||
botlist += signal.source
|
||||
|
||||
if(active == signal.source)
|
||||
var/list/b = signal.data
|
||||
botstatus = b.Copy()
|
||||
|
||||
else if(signal.data["beacon"])
|
||||
if(!beacons)
|
||||
beacons = new()
|
||||
|
||||
beacons[signal.data["beacon"] ] = signal.source
|
||||
|
||||
|
||||
// if(istype(P)) P.updateSelfDialog()
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
var/cmd = "command"
|
||||
if(active) cmd = "command [active.suffix]"
|
||||
|
||||
switch(href_list["op"])
|
||||
|
||||
if("control")
|
||||
active = locate(href_list["bot"])
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("scanbots") // find all bots
|
||||
botlist = null
|
||||
post_signal(control_freq, "command", "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("botlist")
|
||||
active = null
|
||||
|
||||
|
||||
if("unload")
|
||||
post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("setdest")
|
||||
if(beacons)
|
||||
var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in beacons
|
||||
if(dest)
|
||||
post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("retoff")
|
||||
post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("reton")
|
||||
post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("pickoff")
|
||||
post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("pickon")
|
||||
post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("stop", "go", "home")
|
||||
post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Radio Cartridge, essentially a signaler.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_BELT
|
||||
show_messages = 1
|
||||
show_messages = 0
|
||||
|
||||
var/flush = null
|
||||
origin_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
|
||||
@@ -100,31 +100,31 @@
|
||||
user << "<span class='danger'>Transfer failed:</span> Existing AI found on remote terminal. Remove existing AI to install a new one."
|
||||
return 0
|
||||
|
||||
if(ai.is_malf())
|
||||
user << "<span class='danger'>ERROR:</span> Remote transfer interface disabled."
|
||||
return 0
|
||||
user.visible_message("\The [user] starts downloading \the [ai] into \the [src]...", "You start downloading \the [ai] into \the [src]...")
|
||||
ai << "<span class='danger'>\The [user] is downloading you into \the [src]!</span>"
|
||||
|
||||
if(istype(ai.loc, /turf/))
|
||||
new /obj/structure/AIcore/deactivated(get_turf(ai))
|
||||
if(do_after(user, 100))
|
||||
if(istype(ai.loc, /turf/))
|
||||
new /obj/structure/AIcore/deactivated(get_turf(ai))
|
||||
|
||||
ai.carded = 1
|
||||
admin_attack_log(user, ai, "Carded with [src.name]", "Was carded with [src.name]", "used the [src.name] to card")
|
||||
src.name = "[initial(name)] - [ai.name]"
|
||||
ai.carded = 1
|
||||
admin_attack_log(user, ai, "Carded with [src.name]", "Was carded with [src.name]", "used the [src.name] to card")
|
||||
src.name = "[initial(name)] - [ai.name]"
|
||||
|
||||
ai.loc = src
|
||||
ai.destroy_eyeobj(src)
|
||||
ai.cancel_camera()
|
||||
ai.control_disabled = 1
|
||||
ai.aiRestorePowerRoutine = 0
|
||||
carded_ai = ai
|
||||
ai.loc = src
|
||||
ai.destroy_eyeobj(src)
|
||||
ai.cancel_camera()
|
||||
ai.control_disabled = 1
|
||||
ai.aiRestorePowerRoutine = 0
|
||||
carded_ai = ai
|
||||
|
||||
if(ai.client)
|
||||
ai << "You have been downloaded to a mobile storage device. Remote access lost."
|
||||
if(user.client)
|
||||
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
if(ai.client)
|
||||
ai << "You have been downloaded to a mobile storage device. Remote access lost."
|
||||
if(user.client)
|
||||
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
|
||||
ai.canmove = 1
|
||||
update_icon()
|
||||
ai.canmove = 1
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/device/aicard/proc/clear()
|
||||
|
||||
@@ -109,7 +109,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
if(!comm || !comm.exonet || !comm.exonet.address || comm.exonet.address == src.exonet.address) //Don't add addressless devices, and don't add ourselves.
|
||||
continue
|
||||
src.known_devices |= comm
|
||||
for(var/mob/dead/observer/O in dead_mob_list)
|
||||
for(var/mob/observer/dead/O in dead_mob_list)
|
||||
if(!O.client || O.client.prefs.communicator_visibility == 0)
|
||||
continue
|
||||
src.known_devices |= O
|
||||
@@ -157,13 +157,13 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
populate_known_devices() //Update the devices so ghosts can see the list on NanoUI.
|
||||
..()
|
||||
|
||||
/mob/dead/observer
|
||||
/mob/observer/dead
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
|
||||
// Proc: New()
|
||||
// Parameters: None
|
||||
// Description: Gives ghosts an exonet address based on their key and ghost name.
|
||||
/mob/dead/observer/New()
|
||||
/mob/observer/dead/New()
|
||||
. = ..()
|
||||
spawn(20)
|
||||
exonet = new(src)
|
||||
@@ -175,7 +175,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// Proc: Destroy()
|
||||
// Parameters: None
|
||||
// Description: Removes the ghost's address and nulls the exonet datum, to allow qdel()ing.
|
||||
/mob/dead/observer/Destroy()
|
||||
/mob/observer/dead/Destroy()
|
||||
. = ..()
|
||||
if(exonet)
|
||||
exonet.remove_address()
|
||||
@@ -200,7 +200,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
|
||||
|
||||
//Now for ghosts who we pretend have communicators.
|
||||
for(var/mob/dead/observer/O in known_devices)
|
||||
for(var/mob/observer/dead/O in known_devices)
|
||||
if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet)
|
||||
communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address)
|
||||
|
||||
@@ -210,7 +210,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
|
||||
|
||||
//Ghosts we invited.
|
||||
for(var/mob/dead/observer/O in voice_invites)
|
||||
for(var/mob/observer/dead/O in voice_invites)
|
||||
if(O.exonet && O.client)
|
||||
invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address)
|
||||
|
||||
@@ -220,7 +220,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
|
||||
|
||||
//Ghosts that want to talk to us.
|
||||
for(var/mob/dead/observer/O in voice_requests)
|
||||
for(var/mob/observer/dead/O in voice_requests)
|
||||
if(O.exonet && O.client)
|
||||
requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address)
|
||||
|
||||
@@ -342,7 +342,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
|
||||
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
|
||||
/mob/dead/observer/receive_exonet_message(origin_atom, origin_address, message)
|
||||
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message)
|
||||
if(message == "voice")
|
||||
if(istype(origin_atom, /obj/item/device/communicator))
|
||||
var/obj/item/device/communicator/comm = origin_atom
|
||||
@@ -600,7 +600,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// Verb: join_as_voice()
|
||||
// Parameters: None
|
||||
// Description: Allows ghosts to call communicators, if they meet all the requirements.
|
||||
/mob/dead/verb/join_as_voice()
|
||||
/mob/observer/dead/verb/join_as_voice()
|
||||
set category = "Ghost"
|
||||
set name = "Call Communicator"
|
||||
set desc = "If there is a communicator available, send a request to speak through it. This will reset your respawn timer, if someone picks up."
|
||||
@@ -643,7 +643,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
var/choice = input(src,"Send a voice request to whom?") as null|anything in choices
|
||||
if(choice)
|
||||
var/obj/item/device/communicator/chosen_communicator = choice
|
||||
var/mob/dead/observer/O = src
|
||||
var/mob/observer/dead/O = src
|
||||
if(O.exonet)
|
||||
O.exonet.send_message(chosen_communicator.exonet.address, "voice")
|
||||
|
||||
|
||||
@@ -199,6 +199,14 @@
|
||||
src.force = on_damage
|
||||
src.damtype = "fire"
|
||||
processing_objects += src
|
||||
|
||||
/obj/item/device/flashlight/flare/proc/ignite() //Used for flare launchers.
|
||||
on = !on
|
||||
update_icon()
|
||||
force = on_damage
|
||||
damtype = "fire"
|
||||
processing_objects += src
|
||||
return 1
|
||||
|
||||
/obj/item/device/flashlight/slime
|
||||
gender = PLURAL
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = list(TECH_DATA = 2)
|
||||
show_messages = 1
|
||||
show_messages = 0
|
||||
|
||||
var/obj/item/device/radio/radio
|
||||
var/looking_for_personality = 0
|
||||
|
||||
@@ -156,7 +156,7 @@ var/global/list/default_medbay_channels = list(
|
||||
var/obj/item/weapon/card/id/I = GetIdCard()
|
||||
return has_access(list(), req_one_accesses, I ? I.GetAccess() : list())
|
||||
|
||||
/mob/dead/observer/has_internal_radio_channel_access(var/list/req_one_accesses)
|
||||
/mob/observer/dead/has_internal_radio_channel_access(var/list/req_one_accesses)
|
||||
return can_admin_interact()
|
||||
|
||||
/obj/item/device/radio/proc/text_wires()
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
/datum/uplink_category/stealth_items
|
||||
name = "Stealth and Camouflage Items"
|
||||
|
||||
/datum/uplink_category/armor
|
||||
name = "Armor"
|
||||
|
||||
/datum/uplink_category/tools
|
||||
name = "Devices and Tools"
|
||||
|
||||
|
||||
@@ -305,6 +305,22 @@ datum/uplink_item/dd_SortValue()
|
||||
item_cost = 6
|
||||
path = /obj/item/weapon/disk/file/cameras/syndicate
|
||||
|
||||
/********
|
||||
* Armor *
|
||||
********/
|
||||
/datum/uplink_item/item/armor
|
||||
category = /datum/uplink_category/armor
|
||||
|
||||
/datum/uplink_item/item/armor/combat
|
||||
name = "Combat Armor Set"
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/combat_armor
|
||||
|
||||
/datum/uplink_item/item/armor/heavy_vest
|
||||
name = "Heavy Armor Vest"
|
||||
item_cost = 4
|
||||
path = /obj/item/clothing/suit/storage/vest/heavy/merc
|
||||
|
||||
/********************
|
||||
* Devices and Tools *
|
||||
********************/
|
||||
@@ -351,11 +367,6 @@ datum/uplink_item/dd_SortValue()
|
||||
item_cost = 3
|
||||
path = /obj/item/clothing/glasses/thermal/syndi
|
||||
|
||||
/datum/uplink_item/item/tools/heavy_vest
|
||||
name = "Heavy Armor Vest"
|
||||
item_cost = 4
|
||||
path = /obj/item/clothing/suit/storage/vest/heavy/merc
|
||||
|
||||
/datum/uplink_item/item/tools/powersink
|
||||
name = "Powersink (DANGER!)"
|
||||
item_cost = 5
|
||||
@@ -385,7 +396,7 @@ datum/uplink_item/dd_SortValue()
|
||||
item_cost = 3
|
||||
path = /obj/item/weapon/storage/secure/briefcase/money
|
||||
desc = "A briefcase with 10,000 untraceable thalers for funding your sneaky activities."
|
||||
|
||||
|
||||
/datum/uplink_item/item/tools/crystal
|
||||
name = "Tradable Crystal"
|
||||
item_cost = 1
|
||||
|
||||
@@ -61,6 +61,9 @@ var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_ra
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/camera_floppy, 10, 0)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
|
||||
@@ -69,7 +72,6 @@ var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_ra
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/heavy_vest)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user