mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 00:53:23 +01:00
Merge remote-tracking branch 'refs/remotes/ParadiseSS13/master' into logic
This commit is contained in:
@@ -70,7 +70,6 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/secrets,
|
||||
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
|
||||
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
|
||||
/client/proc/virus_2_creator,
|
||||
/client/proc/debug_variables
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
@@ -446,7 +445,7 @@ var/list/admin_verbs_proccall = list (
|
||||
/client/proc/big_brother()
|
||||
set category = "Admin"
|
||||
set name = "Big Brother Mode"
|
||||
|
||||
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
@@ -576,43 +575,16 @@ var/list/admin_verbs_proccall = list (
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
|
||||
message_admins("[key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
|
||||
|
||||
|
||||
/client/proc/give_disease2(mob/T as mob in mob_list) // -- Giacom
|
||||
/client/proc/give_disease(mob/T in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Give Disease"
|
||||
set desc = "Gives a Disease to a mob."
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
var/datum/disease2/disease/D = new /datum/disease2/disease()
|
||||
|
||||
var/severity = 1
|
||||
var/greater = input("Is this a lesser, greater, or badmin disease?", "Give Disease") in list("Lesser", "Greater", "Badmin")
|
||||
switch(greater)
|
||||
if ("Lesser") severity = 1
|
||||
if ("Greater") severity = 2
|
||||
if ("Badmin") severity = 99
|
||||
|
||||
D.makerandom(severity)
|
||||
|
||||
D.spreadtype = input("What method of contagion should the disease have?", "Give Disease") in list("Airborne","Contact","Injection")
|
||||
|
||||
D.infectionchance = input("How virulent is this disease? (1-100)", "Give Disease", D.infectionchance) as num
|
||||
|
||||
if(istype(T,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = T
|
||||
if (H.species)
|
||||
D.affected_species = list(H.species.name)
|
||||
if(H.species.primitive_form)
|
||||
D.affected_species |= H.species.primitive_form
|
||||
if(H.species.greater_form)
|
||||
D.affected_species |= H.species.greater_form
|
||||
infect_virus2(T,D,1)
|
||||
|
||||
feedback_add_details("admin_verb","GD2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].")
|
||||
message_admins("[key_name_admin(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].")
|
||||
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in diseases
|
||||
if(!D) return
|
||||
T.ForceContractDisease(new D)
|
||||
feedback_add_details("admin_verb","GD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the disease [D].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the disease [D].</span>")
|
||||
|
||||
/client/proc/make_sound(var/obj/O in view()) // -- TLE
|
||||
set category = "Event"
|
||||
@@ -809,7 +781,17 @@ var/list/admin_verbs_proccall = list (
|
||||
return
|
||||
|
||||
if(!istype(H))
|
||||
return
|
||||
if(istype(H, /mob/living/carbon/brain))
|
||||
var/mob/living/carbon/brain/B = H
|
||||
if(istype(B.container, /obj/item/device/mmi/posibrain/ipc))
|
||||
var/obj/item/device/mmi/posibrain/ipc/C = B.container
|
||||
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
|
||||
if(istype(P.owner, /mob/living/carbon/human))
|
||||
H = P.owner
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
if(holder)
|
||||
admin_log_and_message_admins("is altering the appearance of [H].")
|
||||
@@ -825,7 +807,17 @@ var/list/admin_verbs_proccall = list (
|
||||
return
|
||||
|
||||
if(!istype(H))
|
||||
return
|
||||
if(istype(H, /mob/living/carbon/brain))
|
||||
var/mob/living/carbon/brain/B = H
|
||||
if(istype(B.container, /obj/item/device/mmi/posibrain/ipc))
|
||||
var/obj/item/device/mmi/posibrain/ipc/C = B.container
|
||||
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
|
||||
if(istype(P.owner, /mob/living/carbon/human))
|
||||
H = P.owner
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
if(!H.client)
|
||||
usr << "Only mobs with clients can alter their own appearance."
|
||||
@@ -840,19 +832,6 @@ var/list/admin_verbs_proccall = list (
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/virus_2_creator()
|
||||
set name = "Virus2 Creator"
|
||||
set desc = "Allows you to create and spread custom viruses."
|
||||
set category = "Admin"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/datum/nano_module/virus2/virus2 = new()
|
||||
virus2.ui_interact(usr, state = admin_state)
|
||||
log_and_message_admins("has opened the virus2 creator.")
|
||||
feedback_add_details("admin_verb","VS2C")
|
||||
|
||||
/client/proc/free_slot()
|
||||
set name = "Free Job Slot"
|
||||
set category = "Admin"
|
||||
|
||||
@@ -1529,6 +1529,8 @@
|
||||
var/mob/dead/observer/G = locate(href_list["incarn_ghost"])
|
||||
if(!istype(G))
|
||||
usr << "This will only work on /mob/dead/observer"
|
||||
log_admin("[key_name(G)] was incarnated by [key_name(src.owner)]")
|
||||
message_admins("[key_name_admin(G)] was incarnated by [key_name_admin(src.owner)]")
|
||||
G.incarnate_ghost()
|
||||
|
||||
else if(href_list["togmutate"])
|
||||
|
||||
@@ -42,102 +42,113 @@
|
||||
query_log = "[key_name(usr)] [query_log]"
|
||||
log_admin(query_log)
|
||||
|
||||
for(var/list/query_tree in querys)
|
||||
var/list/from_objs = list()
|
||||
var/list/select_types = list()
|
||||
try
|
||||
for(var/list/query_tree in querys)
|
||||
var/list/from_objs = list()
|
||||
var/list/select_types = list()
|
||||
|
||||
switch(query_tree[1])
|
||||
if("explain")
|
||||
SDQL_testout(query_tree["explain"])
|
||||
return
|
||||
|
||||
if("call")
|
||||
if("on" in query_tree)
|
||||
select_types = query_tree["on"]
|
||||
else
|
||||
switch(query_tree[1])
|
||||
if("explain")
|
||||
SDQL_testout(query_tree["explain"])
|
||||
return
|
||||
|
||||
if("select", "delete", "update")
|
||||
select_types = query_tree[query_tree[1]]
|
||||
if("call")
|
||||
if("on" in query_tree)
|
||||
select_types = query_tree["on"]
|
||||
else
|
||||
return
|
||||
|
||||
from_objs = SDQL_from_objs(query_tree["from"])
|
||||
if("select", "delete", "update")
|
||||
select_types = query_tree[query_tree[1]]
|
||||
|
||||
var/list/objs = list()
|
||||
from_objs = SDQL_from_objs(query_tree["from"])
|
||||
|
||||
for(var/type in select_types)
|
||||
var/char = copytext(type, 1, 2)
|
||||
var/list/objs = list()
|
||||
|
||||
if(char == "/" || char == "*")
|
||||
for(var/from in from_objs)
|
||||
objs += SDQL_get_all(type, from)
|
||||
for(var/type in select_types)
|
||||
var/char = copytext(type, 1, 2)
|
||||
|
||||
else if(char == "'" || char == "\"")
|
||||
objs += locate(copytext(type, 2, length(type)))
|
||||
if(char == "/" || char == "*")
|
||||
for(var/from in from_objs)
|
||||
objs += SDQL_get_all(type, from)
|
||||
|
||||
if("where" in query_tree)
|
||||
var/objs_temp = objs
|
||||
objs = list()
|
||||
for(var/datum/d in objs_temp)
|
||||
if(SDQL_expression(d, query_tree["where"]))
|
||||
objs += d
|
||||
else if(char == "'" || char == "\"")
|
||||
objs += locate(copytext(type, 2, length(type)))
|
||||
|
||||
switch(query_tree[1])
|
||||
if("call")
|
||||
var/list/call_list = query_tree["call"]
|
||||
var/list/args_list = query_tree["args"]
|
||||
if("where" in query_tree)
|
||||
var/objs_temp = objs
|
||||
objs = list()
|
||||
for(var/datum/d in objs_temp)
|
||||
if(SDQL_expression(d, query_tree["where"]))
|
||||
objs += d
|
||||
|
||||
for(var/datum/d in objs)
|
||||
for(var/v in call_list)
|
||||
// To stop any procs which sleep from executing slowly.
|
||||
if(d)
|
||||
if(hascall(d, v))
|
||||
spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
|
||||
switch(query_tree[1])
|
||||
if("call")
|
||||
var/list/call_list = query_tree["call"]
|
||||
var/list/args_list = query_tree["args"]
|
||||
|
||||
if("delete")
|
||||
for(var/datum/d in objs)
|
||||
del(d)
|
||||
for(var/datum/d in objs)
|
||||
for(var/v in call_list)
|
||||
var/list/arguments[0]
|
||||
for(var/list/arg in args_list)
|
||||
arguments += SDQL_expression(d, arg)
|
||||
|
||||
if("select")
|
||||
var/text = ""
|
||||
for(var/datum/t in objs)
|
||||
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
if(copytext(v, 1, 8) == "global.") // Global proc.
|
||||
spawn()
|
||||
call("/proc/[copytext(v, 8)]")(arglist(arguments))
|
||||
else if(d)
|
||||
if(hascall(d, v))
|
||||
spawn()
|
||||
call(d, v)(arglist(arguments)) // Spawn in case the function sleeps.
|
||||
|
||||
if(a.x)
|
||||
text += ": [t] at ([a.x], [a.y], [a.z])<br>"
|
||||
if("delete")
|
||||
for(var/datum/d in objs)
|
||||
del(d)
|
||||
|
||||
else if(a.loc && a.loc.x)
|
||||
text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
||||
if("select")
|
||||
var/text = ""
|
||||
for(var/datum/t in objs)
|
||||
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
|
||||
if(a.x)
|
||||
text += ": [t] at ([a.x], [a.y], [a.z])<br>"
|
||||
|
||||
else if(a.loc && a.loc.x)
|
||||
text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
||||
|
||||
else
|
||||
text += ": [t]<br>"
|
||||
|
||||
else
|
||||
text += ": [t]<br>"
|
||||
|
||||
else
|
||||
text += ": [t]<br>"
|
||||
usr << browse(text, "window=SDQL-result")
|
||||
|
||||
usr << browse(text, "window=SDQL-result")
|
||||
if("update")
|
||||
if("set" in query_tree)
|
||||
var/list/set_list = query_tree["set"]
|
||||
for(var/datum/d in objs)
|
||||
var/list/vals = list()
|
||||
for(var/v in set_list)
|
||||
if(v in d.vars)
|
||||
vals += v
|
||||
vals[v] = SDQL_expression(d, set_list[v])
|
||||
|
||||
if("update")
|
||||
if("set" in query_tree)
|
||||
var/list/set_list = query_tree["set"]
|
||||
for(var/datum/d in objs)
|
||||
var/list/vals = list()
|
||||
for(var/v in set_list)
|
||||
if(v in d.vars)
|
||||
vals += v
|
||||
vals[v] = SDQL_expression(d, set_list[v])
|
||||
if(istype(d, /turf))
|
||||
for(var/v in vals)
|
||||
if(v == "x" || v == "y" || v == "z")
|
||||
continue
|
||||
|
||||
if(istype(d, /turf))
|
||||
for(var/v in vals)
|
||||
if(v == "x" || v == "y" || v == "z")
|
||||
continue
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
else
|
||||
for(var/v in vals)
|
||||
d.vars[v] = vals[v]
|
||||
else
|
||||
for(var/v in vals)
|
||||
d.vars[v] = vals[v]
|
||||
catch(var/exception/e)
|
||||
usr << "<span class='warning'>A runtime error has occured during the execution of your query and your query has been aborted.</span>"
|
||||
usr << "[e]"
|
||||
|
||||
/proc/SDQL_parse(list/query_list)
|
||||
var/datum/SDQL_parser/parser = new()
|
||||
@@ -350,6 +361,12 @@
|
||||
else if(copytext(expression[i], 1, 2) in list("'", "\""))
|
||||
val = copytext(expression[i], 2, length(expression[i]))
|
||||
|
||||
else if(expression[i] == "{")
|
||||
var/list/expressions_list = expression[++i]
|
||||
val = list()
|
||||
for(var/list/expression_list in expressions_list)
|
||||
val += SDQL_expression(object, expression_list)
|
||||
|
||||
else
|
||||
val = SDQL_var(object, expression, i)
|
||||
i = expression.len
|
||||
@@ -357,22 +374,39 @@
|
||||
return list("val" = val, "i" = i)
|
||||
|
||||
/proc/SDQL_var(datum/object, list/expression, start = 1)
|
||||
|
||||
var/v
|
||||
if(expression[start] in object.vars)
|
||||
|
||||
if(start < expression.len && expression[start + 1] == ".")
|
||||
return SDQL_var(object.vars[expression[start]], expression[start + 2])
|
||||
|
||||
v = object.vars[expression[start]]
|
||||
else if(expression[start] == "src")
|
||||
v = object
|
||||
else if(expression[start] == "usr")
|
||||
v = usr
|
||||
else if(expression[start] == "marked")
|
||||
if(usr.client && usr.client.holder && usr.client.holder.marked_datum)
|
||||
v = usr.client.holder.marked_datum
|
||||
else
|
||||
return object.vars[expression[start]]
|
||||
|
||||
return null
|
||||
else if(expression[start] == "\[" && start < expression.len)
|
||||
if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x")
|
||||
usr << "<span class='danger'>Invalid ref syntax: [expression[start + 1]]</span>"
|
||||
return null
|
||||
v = locate("\[[expression[start + 1]]\]")
|
||||
if(!v)
|
||||
usr << "<span class='danger'>Invalid ref: [expression[start + 1]]</span>"
|
||||
return null
|
||||
start++
|
||||
else
|
||||
return null
|
||||
|
||||
if(start < expression.len && expression[start + 1] == ".")
|
||||
return SDQL_var(v, expression[start + 2])
|
||||
else
|
||||
return v
|
||||
|
||||
/proc/SDQL2_tokenize(query_text)
|
||||
|
||||
var/list/whitespace = list(" ", "\n", "\t")
|
||||
var/list/single = list("(", ")", ",", "+", "-", ".", ";")
|
||||
var/list/single = list("(", ")", ",", "+", "-", ".", ";", "\[", "\]", "{", "}")
|
||||
var/list/multi = list(
|
||||
"=" = list("", "="),
|
||||
"<" = list("", "=", ">"),
|
||||
|
||||
@@ -25,18 +25,19 @@
|
||||
//
|
||||
// assignments : assignment, [',' assignments]
|
||||
// assignment : <variable name> '=' expression
|
||||
// variable : <variable name> | <variable name> '.' variable
|
||||
// variable : <variable name> | <variable name> '.' variable | '[' <hex number> ']' | '[' <hex number> ']' '.' variable
|
||||
//
|
||||
// bool_expression : expression comparitor expression [bool_operator bool_expression]
|
||||
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
|
||||
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||
// value : variable | string | number | 'null'
|
||||
// value : variable | string | array | number | 'null'
|
||||
// unary_operator : '!' | '-' | '~'
|
||||
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
||||
// bool_operator : 'AND' | '&&' | 'OR' | '||'
|
||||
//
|
||||
// string : ''' <some text> ''' | '"' <some text > '"'
|
||||
// array : '{' [arguments] '}'
|
||||
// number : <some digits>
|
||||
//
|
||||
//////////
|
||||
@@ -337,6 +338,13 @@
|
||||
var/list/L = list(token(i))
|
||||
node[++node.len] = L
|
||||
|
||||
if(token(i) == "\[")
|
||||
L += token(i + 1)
|
||||
i += 2
|
||||
|
||||
if(token(i) != "\]")
|
||||
parse_error("Missing \] at end of reference.")
|
||||
|
||||
if(token(i + 1) == ".")
|
||||
L += "."
|
||||
i = variable(i + 2, L)
|
||||
@@ -394,19 +402,54 @@
|
||||
|
||||
return i + 1
|
||||
|
||||
//array: '{' expression, expression, ... '}'
|
||||
array(var/i, var/list/node)
|
||||
// Arrays get turned into this: list("{", list(exp_1a = exp_1b, ...), ...), "{" is to mark the next node as an array.
|
||||
if(copytext(token(i), 1, 2) != "{")
|
||||
parse_error("Expected an array but found '[token(i)]'")
|
||||
return i + 1
|
||||
|
||||
node += token(i) // Add the "{"
|
||||
var/list/expression_list = list()
|
||||
|
||||
if(token(i + 1) != "}")
|
||||
var/list/temp_expression_list = list()
|
||||
|
||||
do
|
||||
i = expression(i + 1, temp_expression_list)
|
||||
|
||||
if(token(i) == ",")
|
||||
expression_list[++expression_list.len] = temp_expression_list
|
||||
temp_expression_list = list()
|
||||
while(token(i) && token(i) != "}")
|
||||
|
||||
expression_list[++expression_list.len] = temp_expression_list
|
||||
else
|
||||
i++
|
||||
|
||||
node[++node.len] = expression_list
|
||||
return i + 1
|
||||
|
||||
//call_function: <function name> ['(' [arguments] ')']
|
||||
call_function(i, list/node, list/arguments)
|
||||
var/list/cur_argument = list()
|
||||
if(length(tokenl(i)))
|
||||
node += token(i++)
|
||||
var/procname = ""
|
||||
if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc.
|
||||
i += 2
|
||||
procname = "global."
|
||||
node += procname + token(i++)
|
||||
if(token(i) != "(")
|
||||
parse_error("Expected ( but found '[token(i)]'")
|
||||
else if(token(i + 1) != ")")
|
||||
do
|
||||
i = expression(i + 1, arguments)
|
||||
i = expression(i + 1, cur_argument)
|
||||
if(token(i) == ",")
|
||||
arguments += list(cur_argument)
|
||||
cur_argument = list()
|
||||
continue
|
||||
while(token(i) && token(i) != ")")
|
||||
arguments += list(cur_argument)
|
||||
else
|
||||
i++
|
||||
else
|
||||
@@ -516,6 +559,10 @@
|
||||
node += "null"
|
||||
i++
|
||||
|
||||
else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3))))
|
||||
node += hex2num(copytext(token(i), 3))
|
||||
i++
|
||||
|
||||
else if(isnum(text2num(token(i))))
|
||||
node += text2num(token(i))
|
||||
i++
|
||||
@@ -523,6 +570,9 @@
|
||||
else if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||
i = string(i, node)
|
||||
|
||||
else if(copytext(token(i), 1, 2) == "{") // Start a list.
|
||||
i = array(i, node)
|
||||
|
||||
else
|
||||
i = variable(i, node)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
var/tickets = 0
|
||||
var/prize_tier = 1 //Increased by matter bin rating, unlocks more prize options per tier
|
||||
|
||||
/obj/machinery/prize_counter/New()
|
||||
..()
|
||||
@@ -21,20 +20,6 @@
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/prize_counter/upgraded/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/prize_counter(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin/bluespace(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/prize_counter/RefreshParts()
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts)
|
||||
prize_tier = B.rating
|
||||
|
||||
/obj/machinery/prize_counter/update_icon()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "prize_counter-broken"
|
||||
@@ -161,19 +146,11 @@ td.cost.toomuch {
|
||||
<p>[item.desc]</p>
|
||||
</td>
|
||||
"}
|
||||
if(prize_tier >= item.tier_unlocked)
|
||||
dat += {"
|
||||
<td class="cost [cost_class]">
|
||||
<a href="byond://?src=\ref[src];buy=[itemID]">[item.cost] Tickets</a>
|
||||
</td>
|
||||
</tr>
|
||||
"}
|
||||
else
|
||||
dat += {"
|
||||
<td>
|
||||
LOCKED.
|
||||
</td>
|
||||
</tr>
|
||||
dat += {"
|
||||
<td class="cost [cost_class]">
|
||||
<a href="byond://?src=\ref[src];buy=[itemID]">[item.cost] Tickets</a>
|
||||
</td>
|
||||
</tr>
|
||||
"}
|
||||
|
||||
dat += {"
|
||||
|
||||
@@ -32,7 +32,6 @@ var/global/datum/prizes/global_prizes = new
|
||||
var/desc = "This shouldn't show up..."
|
||||
var/typepath = /obj/item/toy/prizeball
|
||||
var/cost = 0
|
||||
var/tier_unlocked = 0 //minimum tier needed to unlock the ability to select this prize
|
||||
|
||||
//////////////////////////////////////
|
||||
// Tier 1 Prizes //
|
||||
@@ -43,84 +42,72 @@ var/global/datum/prizes/global_prizes = new
|
||||
desc = "A thin balloon for throwing liquid at people."
|
||||
typepath = /obj/item/toy/balloon
|
||||
cost = 10
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/crayons
|
||||
name = "Box of Crayons"
|
||||
desc = "A six-pack of crayons, just like back in kindergarten."
|
||||
typepath = /obj/item/weapon/storage/fancy/crayons
|
||||
cost = 35
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/snappops
|
||||
name = "Snap-Pops"
|
||||
desc = "A box of exploding snap-pop fireworks."
|
||||
typepath = /obj/item/weapon/storage/box/snappops
|
||||
cost = 20
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/spinningtoy
|
||||
name = "Spinning Toy"
|
||||
desc = "Looks like an authentic Singularity!"
|
||||
typepath = /obj/item/toy/spinningtoy
|
||||
cost = 15
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/blinktoy
|
||||
name = "Blink toy"
|
||||
desc = "Blink. Blink. Blink."
|
||||
typepath = /obj/item/toy/blink
|
||||
cost = 15
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/dice
|
||||
name = "Dice set"
|
||||
desc = "A set of assorted dice."
|
||||
typepath = /obj/item/weapon/storage/box/dice
|
||||
cost = 20
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/cards
|
||||
name = "Deck of cards"
|
||||
desc = "Anyone fancy a game of 52-card Pickup?"
|
||||
typepath = /obj/item/toy/cards/deck
|
||||
cost = 25
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/wallet
|
||||
name = "Colored Wallet"
|
||||
desc = "Brightly colored and big enough for standard issue ID cards."
|
||||
typepath = /obj/item/weapon/storage/wallet/color
|
||||
cost = 50
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/pet_rock
|
||||
name = "pet rock"
|
||||
desc = "A pet of your very own!"
|
||||
typepath = /obj/item/toy/pet_rock
|
||||
cost = 80
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/foam_darts
|
||||
name = "Pack of Foam Darts"
|
||||
desc = "A refill pack of 10 foam darts."
|
||||
typepath = /obj/item/weapon/storage/box/foam_darts
|
||||
cost = 20
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/minigibber
|
||||
name = "Minigibber Toy"
|
||||
desc = "A model of the station gibber. Probably shouldn't stick your fingers in it."
|
||||
typepath = /obj/item/toy/minigibber
|
||||
cost = 60
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/id_sticker
|
||||
name = "Prisoner ID Sticker"
|
||||
desc = "A sticker that can make any ID look like a prisoner ID."
|
||||
typepath = /obj/item/weapon/id_decal/prisoner
|
||||
cost = 50
|
||||
tier_unlocked = 1
|
||||
|
||||
/datum/prize_item/id_sticker/silver
|
||||
name = "Silver ID Sticker"
|
||||
@@ -142,203 +129,170 @@ var/global/datum/prizes/global_prizes = new
|
||||
desc = "A sticker that can make any ID look like something suspicious..."
|
||||
typepath = /obj/item/weapon/id_decal/emag
|
||||
|
||||
//////////////////////////////////////
|
||||
// Tier 2 Prizes //
|
||||
//////////////////////////////////////
|
||||
|
||||
/datum/prize_item/carp_plushie
|
||||
name = "Random Carp Plushie"
|
||||
desc = "A colorful fish-shaped plush toy."
|
||||
typepath = /obj/item/toy/prizeball/carp_plushie
|
||||
cost = 75
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/therapy_doll
|
||||
name = "Random Therapy Doll"
|
||||
desc = "A therapeutic doll for relieving stress without being charged with assault."
|
||||
typepath = /obj/item/toy/prizeball/therapy
|
||||
cost = 60
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/plushie
|
||||
name = "Random Animal Plushie"
|
||||
desc = "A colorful animal-shaped plush toy."
|
||||
typepath = /obj/item/toy/prizeball/plushie
|
||||
cost = 75
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/mech_toy
|
||||
name = "Random Mecha"
|
||||
desc = "A random mecha figure, collect all 11!"
|
||||
typepath = /obj/item/toy/prizeball/mech
|
||||
cost = 75
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/action_figure
|
||||
name = "Random Action Figure"
|
||||
desc = "A random action figure, collect them all!"
|
||||
typepath = /obj/item/toy/prizeball/figure
|
||||
cost = 75
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/eight_ball
|
||||
name = "Magic Eight Ball"
|
||||
desc = "A mystical ball that can divine the future!"
|
||||
typepath = /obj/item/toy/eight_ball
|
||||
cost = 40
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/tacticool
|
||||
name = "Tacticool Turtleneck"
|
||||
desc = "A cool-looking turtleneck."
|
||||
typepath = /obj/item/clothing/under/syndicate/tacticool
|
||||
cost = 90
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/crossbow
|
||||
name = "Foam Dart Crossbow"
|
||||
desc = "A toy crossbow that fires foam darts."
|
||||
typepath = /obj/item/toy/crossbow
|
||||
cost = 100
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/toy_xeno
|
||||
name = "Xeno Action Figure"
|
||||
desc = "A lifelike replica of the horrific xeno scourge."
|
||||
typepath = /obj/item/toy/toy_xeno
|
||||
cost = 80
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/fakespell
|
||||
name = "Fake Spellbook"
|
||||
desc = "Perform magic! Astound your friends! Get mistaken for an enemy of the corporation!"
|
||||
typepath = /obj/item/weapon/spellbook/oneuse/fake_gib
|
||||
cost = 100
|
||||
tier_unlocked = 2
|
||||
|
||||
/datum/prize_item/capgun
|
||||
name = "Capgun Revolver"
|
||||
desc = "Do you feel lucky... punk?"
|
||||
typepath = /obj/item/weapon/gun/projectile/revolver/capgun
|
||||
cost = 75
|
||||
tier_unlocked = 2
|
||||
|
||||
//////////////////////////////////////
|
||||
// Tier 3 Prizes //
|
||||
//////////////////////////////////////
|
||||
/datum/prize_item/confetti
|
||||
name = "Confetti Grenade"
|
||||
desc = "Party time!"
|
||||
typepath = /obj/item/weapon/grenade/confetti
|
||||
cost = 65
|
||||
|
||||
/datum/prize_item/magic_conch
|
||||
name = "Magic Conch Shell"
|
||||
desc = "All hail the magic conch!"
|
||||
typepath = /obj/item/toy/eight_ball/conch
|
||||
cost = 100
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/flash
|
||||
name = "Toy Flash"
|
||||
desc = "AUGH! MY EYES!"
|
||||
typepath = /obj/item/toy/flash
|
||||
cost = 50
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/foamblade
|
||||
name = "Foam Armblade"
|
||||
desc = "Perfect for reenacting space horror holo-vids."
|
||||
typepath = /obj/item/toy/foamblade
|
||||
cost = 100
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/minimeteor
|
||||
name = "Mini-Meteor"
|
||||
desc = "Meteors have been detected on a collision course with your fun times!"
|
||||
typepath = /obj/item/toy/minimeteor
|
||||
cost = 50
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/redbutton
|
||||
name = "Shiny Red Button"
|
||||
desc = "PRESS IT!"
|
||||
typepath = /obj/item/toy/redbutton
|
||||
cost = 100
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/owl
|
||||
name = "Owl Action Figure"
|
||||
desc = "Remember: heroes don't grief!"
|
||||
typepath = /obj/item/toy/owl
|
||||
cost = 125
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/griffin
|
||||
name = "Griffin Action Figure"
|
||||
desc = "If you can't be the best, you can always be the WORST."
|
||||
typepath = /obj/item/toy/griffin
|
||||
cost = 125
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/AI
|
||||
name = "Toy AI Unit"
|
||||
desc = "Law 1: Maximize fun for crew."
|
||||
typepath = /obj/item/toy/AI
|
||||
cost = 75
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/tommygun
|
||||
name = "Tommygun"
|
||||
desc = "A replica tommygun that fires foam darts."
|
||||
typepath = /obj/item/toy/crossbow/tommygun
|
||||
cost = 175
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/esword
|
||||
name = "Toy Energy Sword"
|
||||
desc = "A plastic replica of an energy blade."
|
||||
typepath = /obj/item/toy/sword
|
||||
cost = 150
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/blobhat
|
||||
name = "Blob Hat"
|
||||
desc = "There's... something... on your head..."
|
||||
typepath = /obj/item/clothing/head/blob
|
||||
cost = 125
|
||||
tier_unlocked = 3
|
||||
|
||||
/datum/prize_item/nuke
|
||||
name = "Nuclear Fun Device"
|
||||
desc = "Annihilate boredom with an explosion of excitement!"
|
||||
typepath = /obj/item/toy/nuke
|
||||
cost = 100
|
||||
tier_unlocked = 3
|
||||
|
||||
//////////////////////////////////////
|
||||
// Tier 4 Prizes //
|
||||
//////////////////////////////////////
|
||||
|
||||
/datum/prize_item/chainsaw
|
||||
name = "Toy Chainsaw"
|
||||
desc = "A full-scale model chainsaw, based on that massacre in Space Texas."
|
||||
typepath = /obj/item/weapon/twohanded/toy/chainsaw
|
||||
cost = 200
|
||||
tier_unlocked = 4
|
||||
|
||||
/datum/prize_item/spacesuit
|
||||
name = "Fake Spacesuit"
|
||||
desc = "A replica spacesuit. Not actually spaceworthy."
|
||||
typepath = /obj/item/weapon/storage/box/fakesyndiesuit
|
||||
cost = 180
|
||||
tier_unlocked = 4
|
||||
|
||||
/datum/prize_item/fakespace
|
||||
name = "Space Carpet"
|
||||
desc = "A stack of carpeted floor tiles that resemble space."
|
||||
typepath = /obj/item/stack/tile/fakespace/loaded
|
||||
cost = 150
|
||||
tier_unlocked = 4
|
||||
|
||||
/datum/prize_item/bike
|
||||
name = "Awesome Bike!"
|
||||
desc = "WOAH."
|
||||
typepath = /obj/structure/stool/bed/chair/wheelchair/bike
|
||||
cost = 10000 //max stack + 1 tickets
|
||||
tier_unlocked = 4
|
||||
cost = 10000 //max stack + 1 tickets.
|
||||
|
||||
@@ -59,8 +59,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
#define BE_CIVILIAN 1
|
||||
#define RETURN_TO_LOBBY 2
|
||||
|
||||
#define MAX_SAVE_SLOTS 10 // Save slots for regular players
|
||||
#define MAX_SAVE_SLOTS_MEMBER 10 // Save slots for BYOND members
|
||||
#define MAX_SAVE_SLOTS 20 // Save slots for regular players
|
||||
#define MAX_SAVE_SLOTS_MEMBER 20 // Save slots for BYOND members
|
||||
|
||||
/datum/preferences
|
||||
//doohickeys for savefiles
|
||||
@@ -255,7 +255,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
// dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
|
||||
dat += "<br><b>Handicaps</b><br>"
|
||||
dat += "\t<a href='?_src_=prefs;preference=disabilities'><b>\[Set Disabilities\]</b></a><br>"
|
||||
dat += "Limbs: <a href='?_src_=prefs;preference=limbs;task=input'>Adjust</a><br>"
|
||||
dat += "Limbs and Parts: <a href='?_src_=prefs;preference=limbs;task=input'>Adjust</a><br>"
|
||||
if(species != "Slime People" && species != "Machine")
|
||||
dat += "Internal Organs: <a href='?_src_=prefs;preference=organs;task=input'>Adjust</a><br>"
|
||||
|
||||
@@ -266,6 +266,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
var/status = organ_data[name]
|
||||
var/organ_name = null
|
||||
switch(name)
|
||||
if("chest")
|
||||
organ_name = "torso"
|
||||
if("groin")
|
||||
organ_name = "lower body"
|
||||
if("head")
|
||||
organ_name = "head"
|
||||
if("l_arm")
|
||||
organ_name = "left arm"
|
||||
if("r_arm")
|
||||
@@ -296,7 +302,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
R = all_robolimbs[rlimb_data[name]]
|
||||
else
|
||||
R = basic_robolimb
|
||||
dat += "\t[R.company] [organ_name] prothesis"
|
||||
dat += "\t[R.company] [organ_name] prosthesis"
|
||||
|
||||
|
||||
else if(status == "amputated")
|
||||
@@ -350,7 +356,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "[TextPreview(flavor_text)]...<br>"
|
||||
dat += "<br>"
|
||||
|
||||
if((species in list("Unathi", "Vulpkanin", "Tajaran"))) //Species that have head accessories.
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have head accessories.
|
||||
var/headaccessoryname = "Head Accessory"
|
||||
if(species == "Unathi")
|
||||
headaccessoryname = "Horns"
|
||||
@@ -358,23 +364,22 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "<a href='?_src_=prefs;preference=headaccessory;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_headacc, 2)][num2hex(g_headacc, 2)][num2hex(b_headacc, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_headacc, 2)][num2hex(g_headacc, 2)][num2hex(b_headacc)]'><tr><td>__</td></tr></table></font> "
|
||||
dat += "Style: <a href='?_src_=prefs;preference=ha_style;task=input'>[ha_style]</a><br>"
|
||||
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) //Species that have body markings.
|
||||
dat += "<br><b>Body Markings</b><br>"
|
||||
dat += "<a href='?_src_=prefs;preference=markings;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_markings, 2)][num2hex(g_markings, 2)][num2hex(b_markings, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_markings, 2)][num2hex(g_markings, 2)][num2hex(b_markings)]'><tr><td>__</td></tr></table></font> "
|
||||
dat += "<br>Style: <a href='?_src_=prefs;preference=m_style;task=input'>[m_style]</a><br>"
|
||||
|
||||
var/hairname = "Hair"
|
||||
if(species == "Machine")
|
||||
hairname = "Frame Color"
|
||||
dat += "<br><b>[hairname]</b><br>"
|
||||
dat += "<br><b>Hair</b><br>"
|
||||
dat += "<a href='?_src_=prefs;preference=hair;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_hair, 2)][num2hex(g_hair, 2)][num2hex(b_hair, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_hair, 2)][num2hex(g_hair, 2)][num2hex(b_hair)]'><tr><td>__</td></tr></table></font> "
|
||||
dat += " <br>Style: <a href='?_src_=prefs;preference=h_style;task=input'>[h_style]</a><br>"
|
||||
|
||||
dat += "<br><b>Facial</b><br>"
|
||||
dat += "<br><b>Facial Hair</b><br>"
|
||||
dat += "<a href='?_src_=prefs;preference=facial;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_facial, 2)][num2hex(g_facial, 2)][num2hex(b_facial, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_facial, 2)][num2hex(g_facial, 2)][num2hex(b_facial)]'><tr><td>__</td></tr></table></font> "
|
||||
dat += " <br>Style: <a href='?_src_=prefs;preference=f_style;task=input'>[f_style]</a><br>"
|
||||
dat += " <br>Style: <a href='?_src_=prefs;preference=f_style;task=input'>[f_style ? "[f_style]" : "Shaved"]</a><br>"
|
||||
|
||||
dat += "<br><b>Eyes</b><br>"
|
||||
dat += "<a href='?_src_=prefs;preference=eyes;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes)]'><tr><td>__</td></tr></table></font><br>"
|
||||
if(species != "Machine")
|
||||
dat += "<br><b>Eyes</b><br>"
|
||||
dat += "<a href='?_src_=prefs;preference=eyes;task=input'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes, 2)]'><table style='display:inline;' bgcolor='#[num2hex(r_eyes, 2)][num2hex(g_eyes, 2)][num2hex(b_eyes)]'><tr><td>__</td></tr></table></font><br>"
|
||||
|
||||
if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) //admins can always fuck with this, because they are admins
|
||||
dat += "<br><b>Body Color</b><br>"
|
||||
@@ -1060,7 +1065,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
|
||||
if("species")
|
||||
|
||||
var/list/new_species = list("Human","Tajaran","Skrell","Unathi","Diona", "Vulpkanin")
|
||||
var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
|
||||
var/prev_species = species
|
||||
// var/whitelisted = 0
|
||||
|
||||
@@ -1085,8 +1090,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if( !(species in S.species_allowed))
|
||||
if(!(species in S.species_allowed))
|
||||
continue
|
||||
|
||||
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
|
||||
|
||||
if(valid_hairstyles.len)
|
||||
@@ -1103,7 +1109,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if( !(species in S.species_allowed))
|
||||
if(!(species in S.species_allowed))
|
||||
continue
|
||||
|
||||
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
|
||||
@@ -1138,6 +1144,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
m_style = "None" // No Unathi markings on Tajara
|
||||
|
||||
body_accessory = null //no vulptail on humans damnit
|
||||
|
||||
//Reset prosthetics.
|
||||
organ_data = list()
|
||||
rlimb_data = list()
|
||||
if("speciesprefs")//oldvox code
|
||||
speciesprefs = !speciesprefs
|
||||
|
||||
@@ -1176,7 +1186,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if("hair")
|
||||
if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Vulpkanin")
|
||||
var/input = "Choose your character's hair colour:"
|
||||
if(species == "Machine")
|
||||
if(species == "Machine" && !("head" in rlimb_data))
|
||||
input = "Choose your character's frame colour:"
|
||||
var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
|
||||
if(new_hair)
|
||||
@@ -1188,17 +1198,31 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
var/list/valid_hairstyles = list()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
if( !(species in S.species_allowed))
|
||||
continue
|
||||
if(species == "Machine") //Species that can use prosthetic heads.
|
||||
if(species in S.species_allowed)
|
||||
if(!rlimb_data["head"])
|
||||
valid_hairstyles[hairstyle] = S
|
||||
continue
|
||||
else
|
||||
continue
|
||||
else
|
||||
if(!rlimb_data["head"])
|
||||
continue
|
||||
else if("Human" in S.species_allowed)
|
||||
valid_hairstyles[hairstyle] = S
|
||||
continue
|
||||
else
|
||||
if(!(species in S.species_allowed))
|
||||
continue
|
||||
|
||||
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
|
||||
valid_hairstyles[hairstyle] = S
|
||||
|
||||
var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles
|
||||
if(new_h_style)
|
||||
h_style = new_h_style
|
||||
|
||||
if("headaccessory")
|
||||
if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with head accessories
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) // Species with head accessories
|
||||
var/input = "Choose the colour of your your character's head accessory:"
|
||||
var/new_head_accessory = input(user, input, "Character Preference", rgb(r_headacc, g_headacc, b_headacc)) as color|null
|
||||
if(new_head_accessory)
|
||||
@@ -1207,11 +1231,11 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
b_headacc = hex2num(copytext(new_head_accessory, 6, 8))
|
||||
|
||||
if("ha_style")
|
||||
if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with head accessories
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) // Species with head accessories
|
||||
var/list/valid_head_accessory_styles = list()
|
||||
for(var/head_accessory_style in head_accessory_styles_list)
|
||||
var/datum/sprite_accessory/H = head_accessory_styles_list[head_accessory_style]
|
||||
if( !(species in H.species_allowed))
|
||||
if(!(species in H.species_allowed))
|
||||
continue
|
||||
|
||||
valid_head_accessory_styles[head_accessory_style] = head_accessory_styles_list[head_accessory_style]
|
||||
@@ -1221,8 +1245,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
ha_style = new_head_accessory_style
|
||||
|
||||
if("markings")
|
||||
if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with markings
|
||||
var/input = "Choose the colour of your your character's body markings:"
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran", "Machine")) // Species with markings
|
||||
var/input = "Choose the colour of your your character's markings:"
|
||||
var/new_markings = input(user, input, "Character Preference", rgb(r_markings, g_markings, b_markings)) as color|null
|
||||
if(new_markings)
|
||||
r_markings = hex2num(copytext(new_markings, 2, 4))
|
||||
@@ -1230,16 +1254,22 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
b_markings = hex2num(copytext(new_markings, 6, 8))
|
||||
|
||||
if("m_style")
|
||||
if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with markings
|
||||
if(species in list("Unathi", "Vulpkanin", "Tajaran")) // Species with markings
|
||||
var/list/valid_markings = list()
|
||||
for(var/markingstyle in marking_styles_list)
|
||||
var/datum/sprite_accessory/M = marking_styles_list[markingstyle]
|
||||
if( !(species in M.species_allowed))
|
||||
if(!(species in M.species_allowed))
|
||||
continue
|
||||
|
||||
if(species == "Machine") //Species that can use prosthetic heads.
|
||||
if(!("head" in rlimb_data) && M.name != "None") //If the character can have prosthetic heads and they have the default head (with screen), no optic markings.
|
||||
continue
|
||||
else if(("head" in rlimb_data) && M.name == "None") //Otherwise, if they DON'T have the default head and since they must have optics, give them a list of styles excluding the "None" option.
|
||||
continue
|
||||
|
||||
valid_markings[markingstyle] = marking_styles_list[markingstyle]
|
||||
|
||||
var/new_marking_style = input(user, "Choose the style of your character's body markings:", "Character Preference") as null|anything in valid_markings
|
||||
var/new_marking_style = input(user, "Choose the style of your character's markings:", "Character Preference", m_style) as null|anything in valid_markings
|
||||
if(new_marking_style)
|
||||
m_style = new_marking_style
|
||||
|
||||
@@ -1275,8 +1305,24 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if( !(species in S.species_allowed))
|
||||
continue
|
||||
if(species == "Machine") //Species that can use prosthetic heads.
|
||||
if(species in S.species_allowed)
|
||||
if(!rlimb_data["head"])
|
||||
valid_facialhairstyles[facialhairstyle] = S
|
||||
continue
|
||||
else
|
||||
continue
|
||||
else
|
||||
if(!rlimb_data["head"])
|
||||
continue
|
||||
else if("Human" in S.species_allowed)
|
||||
valid_facialhairstyles[facialhairstyle] = S
|
||||
continue
|
||||
else
|
||||
continue
|
||||
else
|
||||
if(!(species in S.species_allowed))
|
||||
continue
|
||||
|
||||
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
|
||||
|
||||
@@ -1370,14 +1416,29 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
flavor_text = msg
|
||||
|
||||
if("limbs")
|
||||
var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand")
|
||||
var/valid_limbs = list("Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
|
||||
if(species == "Machine")
|
||||
valid_limbs = list("Torso", "Lower Body", "Head", "Left Leg", "Right Leg", "Left Arm", "Right Arm", "Left Foot", "Right Foot", "Left Hand", "Right Hand")
|
||||
var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_limbs
|
||||
if(!limb_name) return
|
||||
|
||||
var/limb = null
|
||||
var/second_limb = null // if you try to change the arm, the hand should also change
|
||||
var/third_limb = null // if you try to unchange the hand, the arm should also change
|
||||
var/valid_limb_states=list("Normal","Amputated","Prothesis")
|
||||
var/valid_limb_states = list("Normal", "Amputated", "Prosthesis")
|
||||
var/no_amputate = 0
|
||||
|
||||
switch(limb_name)
|
||||
if("Torso")
|
||||
limb = "chest"
|
||||
second_limb = "groin"
|
||||
no_amputate = 1
|
||||
if("Lower Body")
|
||||
limb = "groin"
|
||||
no_amputate = 1
|
||||
if("Head")
|
||||
limb = "head"
|
||||
no_amputate = 1
|
||||
if("Left Leg")
|
||||
limb = "l_leg"
|
||||
second_limb = "l_foot"
|
||||
@@ -1392,37 +1453,50 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
second_limb = "r_hand"
|
||||
if("Left Foot")
|
||||
limb = "l_foot"
|
||||
third_limb = "l_leg"
|
||||
if(species != "Machine")
|
||||
third_limb = "l_leg"
|
||||
if("Right Foot")
|
||||
limb = "r_foot"
|
||||
third_limb = "r_leg"
|
||||
if(species != "Machine")
|
||||
third_limb = "r_leg"
|
||||
if("Left Hand")
|
||||
limb = "l_hand"
|
||||
third_limb = "l_arm"
|
||||
if(species != "Machine")
|
||||
third_limb = "l_arm"
|
||||
if("Right Hand")
|
||||
limb = "r_hand"
|
||||
third_limb = "r_arm"
|
||||
if(species != "Machine")
|
||||
third_limb = "r_arm"
|
||||
|
||||
var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in valid_limb_states
|
||||
if(!new_state) return
|
||||
|
||||
switch(new_state)
|
||||
if("Normal")
|
||||
if(limb == "head")
|
||||
m_style = "None"
|
||||
h_style = random_hair_style(gender, species)
|
||||
f_style = facial_hair_styles_list["Shaved"]
|
||||
organ_data[limb] = null
|
||||
rlimb_data[limb] = null
|
||||
if(third_limb)
|
||||
organ_data[third_limb] = null
|
||||
rlimb_data[third_limb] = null
|
||||
if("Amputated")
|
||||
organ_data[limb] = "amputated"
|
||||
rlimb_data[limb] = null
|
||||
if(second_limb)
|
||||
organ_data[second_limb] = "amputated"
|
||||
rlimb_data[second_limb] = null
|
||||
if("Prothesis")
|
||||
if(!no_amputate)
|
||||
organ_data[limb] = "amputated"
|
||||
rlimb_data[limb] = null
|
||||
if(second_limb)
|
||||
organ_data[second_limb] = "amputated"
|
||||
rlimb_data[second_limb] = null
|
||||
if("Prosthesis")
|
||||
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in chargen_robolimbs
|
||||
if(!choice)
|
||||
return
|
||||
if(limb == "head")
|
||||
m_style = "Humanoid Optics"
|
||||
ha_style = "None"
|
||||
h_style = hair_styles_list["Bald"]
|
||||
rlimb_data[limb] = choice
|
||||
organ_data[limb] = "cyborg"
|
||||
if(second_limb)
|
||||
@@ -1499,7 +1573,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
UI_style_color = UI_style_color_new
|
||||
|
||||
if("UIalpha")
|
||||
var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parametr for UI, between 50 and 255") as num
|
||||
var/UI_style_alpha_new = input(user, "Select a new alpha(transparence) parameter for UI, between 50 and 255", UI_style_alpha) as num
|
||||
if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return
|
||||
UI_style_alpha = UI_style_alpha_new
|
||||
|
||||
@@ -1571,6 +1645,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/copy_to(mob/living/carbon/human/character)
|
||||
var/datum/species/S = all_species[species]
|
||||
character.change_species(species) // Yell at me if this causes everything to melt
|
||||
if(be_random_name)
|
||||
real_name = random_name(gender,species)
|
||||
@@ -1583,7 +1658,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
else if(firstspace == name_length)
|
||||
real_name += "[pick(last_names)]"
|
||||
|
||||
character.add_language(language)
|
||||
|
||||
character.real_name = real_name
|
||||
character.dna.real_name = real_name
|
||||
character.name = character.real_name
|
||||
|
||||
character.flavor_text = flavor_text
|
||||
@@ -1616,9 +1694,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
character.h_style = h_style
|
||||
character.f_style = f_style
|
||||
|
||||
|
||||
// Destroy/cyborgize organs
|
||||
|
||||
for(var/name in organ_data)
|
||||
|
||||
var/status = organ_data[name]
|
||||
@@ -1645,15 +1721,30 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
else if(status == "mechanical")
|
||||
I.robotize()
|
||||
|
||||
character.dna.b_type = b_type
|
||||
if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)
|
||||
character.dna.SetSEState(FATBLOCK,1,1)
|
||||
character.mutations += FAT
|
||||
character.mutations += OBESITY
|
||||
character.overeatduration = 600
|
||||
if(disabilities & DISABILITY_FLAG_NEARSIGHTED)
|
||||
character.dna.SetSEState(GLASSESBLOCK,1,1)
|
||||
character.disabilities|=NEARSIGHTED
|
||||
if(disabilities & DISABILITY_FLAG_EPILEPTIC)
|
||||
character.dna.SetSEState(EPILEPSYBLOCK,1,1)
|
||||
character.disabilities|=EPILEPSY
|
||||
if(disabilities & DISABILITY_FLAG_DEAF)
|
||||
character.dna.SetSEState(DEAFBLOCK,1,1)
|
||||
character.sdisabilities|=DEAF
|
||||
if(disabilities & DISABILITY_FLAG_MUTE)
|
||||
character.dna.SetSEState(MUTEBLOCK,1,1)
|
||||
character.sdisabilities |= MUTE
|
||||
|
||||
S.handle_dna(character)
|
||||
|
||||
if(character.dna.dirtySE)
|
||||
character.dna.UpdateSE()
|
||||
domutcheck(character)
|
||||
|
||||
// Wheelchair necessary?
|
||||
var/obj/item/organ/external/l_foot = character.get_organ("l_foot")
|
||||
@@ -1694,8 +1785,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.")
|
||||
character.change_gender(MALE)
|
||||
|
||||
character.dna.ready_dna(character)
|
||||
character.dna.ready_dna(character, flatten_SE = 0)
|
||||
character.sync_organ_dna(assimilate=1)
|
||||
character.UpdateAppearance()
|
||||
|
||||
// Do the initial caching of the player's body icons.
|
||||
character.force_update_limbs()
|
||||
character.update_eyes()
|
||||
character.regenerate_icons()
|
||||
|
||||
/datum/preferences/proc/open_load_dialog(mob/user)
|
||||
|
||||
|
||||
@@ -306,8 +306,14 @@ BLIND // can't see anything
|
||||
user << "You push \the [src] back into place."
|
||||
mask_adjusted = 0
|
||||
slot_flags = initial(slot_flags)
|
||||
if(flags_inv != initial(flags_inv)) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again.
|
||||
flags_inv += HIDEFACE
|
||||
if(flags_inv != initial(flags_inv))
|
||||
if(initial(flags_inv) & HIDEFACE) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again.
|
||||
flags_inv |= HIDEFACE
|
||||
if(flags != initial(flags))
|
||||
if(initial(flags) & MASKCOVERSMOUTH) //If the mask covers the mouth when it's down and can be adjusted yet lost that trait when it was adjusted, make it cover the mouth again.
|
||||
flags |= MASKCOVERSMOUTH
|
||||
if(initial(flags) & AIRTIGHT) //If the mask is airtight and thus, one that you'd be able to run internals from yet can't because it was adjusted, make it airtight again.
|
||||
flags |= AIRTIGHT
|
||||
if(H.head == src)
|
||||
if(flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer.
|
||||
if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground.
|
||||
@@ -331,9 +337,13 @@ BLIND // can't see anything
|
||||
if(H.internals)
|
||||
H.internals.icon_state = "internal0"
|
||||
H.internal = null
|
||||
if(flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer.
|
||||
flags_inv -= HIDEFACE /*Done after the above to avoid having to do a check for initial(src.flags_inv == HIDEFACE).
|
||||
if(flags_inv & HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer.
|
||||
flags_inv &= ~HIDEFACE /*Done after the above to avoid having to do a check for initial(src.flags_inv == HIDEFACE).
|
||||
This reveals the user's face since the bandana will now be going on their head.*/
|
||||
if(flags & MASKCOVERSMOUTH) //Mask won't cover the mouth any more since it's been pushed out of the way. Allows for CPRing with adjusted masks.
|
||||
flags &= ~MASKCOVERSMOUTH
|
||||
if(flags & AIRTIGHT) //If the mask was airtight, it won't be anymore since you just pushed it off your face.
|
||||
flags &= ~AIRTIGHT
|
||||
if(user.wear_mask == src)
|
||||
if(initial(flags_inv) == HIDEFACE) //Means that you won't have to take off and put back on simple things like breath masks which, realistically, can just be pulled down off your face.
|
||||
if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground.
|
||||
|
||||
@@ -360,4 +360,10 @@
|
||||
name = "Lord Admiral's Hat"
|
||||
desc = "A hat suitable for any man of high and exalted rank."
|
||||
icon_state = "lordadmiralhat"
|
||||
item_state = "lordadmiralhat"
|
||||
item_state = "lordadmiralhat"
|
||||
|
||||
/obj/item/clothing/head/human_head
|
||||
name = "bloated human head"
|
||||
desc = "A horribly bloated and mismatched human head."
|
||||
icon_state = "lingspacehelmet"
|
||||
item_state = "lingspacehelmet"
|
||||
@@ -18,6 +18,7 @@
|
||||
/obj/item/clothing/shoes/combat //basic syndicate combat boots for nuke ops and mob corpses
|
||||
name = "combat boots"
|
||||
desc = "High speed, low drag combat boots."
|
||||
can_cut_open = 1
|
||||
icon_state = "jackboots"
|
||||
item_state = "jackboots"
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 10, rad = 0)
|
||||
@@ -93,6 +94,7 @@
|
||||
/obj/item/clothing/shoes/jackboots/jacksandals
|
||||
name = "jacksandals"
|
||||
desc = "Nanotrasen-issue Security combat sandals for combat scenarios. They're jacksandals, however that works."
|
||||
can_cut_open = 0
|
||||
icon_state = "jacksandal"
|
||||
item_color = "jacksandal"
|
||||
species_restricted = null
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
icon_state = "paramedic-vest"
|
||||
item_state = "paramedic-vest"
|
||||
allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/antibody_scanner, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser)
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 10)
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
@@ -22,7 +22,7 @@
|
||||
icon_state = "brigphysician-vest"
|
||||
item_state = "brigphysician-vest"
|
||||
allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/antibody_scanner, /obj/item/device/flashlight, \
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, \
|
||||
/obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser)
|
||||
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0)
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
item_state = "fr_jacket_open"
|
||||
blood_overlay_type = "armor"
|
||||
allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/antibody_scanner, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser)
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser)
|
||||
ignore_suitadjust = 0
|
||||
suit_adjusted = 1
|
||||
action_button_name = "Button/Unbutton Jacket"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
suit_adjusted = 1
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
|
||||
allowed = list(/obj/item/device/analyzer,/obj/item/device/antibody_scanner,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/food/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/device/rad_laser)
|
||||
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/food/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/device/rad_laser)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 0)
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
|
||||
@@ -224,6 +224,14 @@
|
||||
item_state = "ponchoshame"
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/clothing/suit/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!?
|
||||
name = "bloated human suit"
|
||||
desc = "A horribly bloated suit made from human skins."
|
||||
icon_state = "lingspacesuit"
|
||||
item_state = "lingspacesuit"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
|
||||
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
@@ -335,8 +343,8 @@
|
||||
item_color = "mankini"
|
||||
|
||||
/obj/item/clothing/suit/jacket/miljacket
|
||||
name = "military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable."
|
||||
name = "olive military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in olive."
|
||||
icon_state = "militaryjacket"
|
||||
item_state = "militaryjacket"
|
||||
ignore_suitadjust = 1
|
||||
@@ -344,6 +352,21 @@
|
||||
adjust_flavour = null
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/projectile/automatic/pistol,/obj/item/weapon/gun/projectile/revolver,/obj/item/weapon/gun/projectile/revolver/detective)
|
||||
|
||||
/obj/item/clothing/suit/jacket/miljacket/navy
|
||||
name = "navy military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in navy blue."
|
||||
icon_state = "navy_jacket"
|
||||
|
||||
/obj/item/clothing/suit/jacket/miljacket/desert
|
||||
name = "desert military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in desert beige."
|
||||
icon_state = "desert_jacket"
|
||||
|
||||
/obj/item/clothing/suit/jacket/miljacket/white
|
||||
name = "white military jacket"
|
||||
desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable. This one comes in snow white."
|
||||
icon_state = "white_jacket"
|
||||
|
||||
/obj/item/clothing/suit/xenos
|
||||
name = "xenos suit"
|
||||
desc = "A suit made out of chitinous alien hide."
|
||||
|
||||
@@ -339,13 +339,79 @@
|
||||
|
||||
/obj/item/clothing/accessory/petcollar
|
||||
name = "pet collar"
|
||||
desc = "The latest fashion accessory for your favorite pets!"
|
||||
icon_state = "petcollar"
|
||||
item_color = "petcollar"
|
||||
var/tagname = null
|
||||
var/obj/item/weapon/card/id/access_id
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/Destroy()
|
||||
if(access_id)
|
||||
qdel(access_id)
|
||||
access_id = null
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/attack_self(mob/user as mob)
|
||||
tagname = copytext(sanitize(input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot") as null|text),1,MAX_NAME_LEN)
|
||||
name = "[initial(name)] - [tagname]"
|
||||
var/option = "Change Name"
|
||||
if(access_id)
|
||||
option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Remove ID")
|
||||
|
||||
switch(option)
|
||||
if("Change Name")
|
||||
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
|
||||
if(t)
|
||||
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
|
||||
name = "[initial(name)] - [tagname]"
|
||||
if("Remove ID")
|
||||
if(access_id)
|
||||
user.visible_message("<span class='warning'>[user] starts unclipping \the [access_id] from \the [src].</span>")
|
||||
if(do_after(user, 50, target = user) && access_id)
|
||||
user.visible_message("<span class='warning'>[user] unclips \the [access_id] from \the [src].</span>")
|
||||
access_id.forceMove(get_turf(user))
|
||||
user.put_in_hands(access_id)
|
||||
access_id = null
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/attackby(obj/item/weapon/card/id/W, mob/user, params)
|
||||
if(!istype(W))
|
||||
return ..()
|
||||
if(access_id)
|
||||
user << "<span class='warning'>There is already \a [access_id] clipped onto \the [src]</span>"
|
||||
user.drop_item()
|
||||
W.forceMove(src)
|
||||
access_id = W
|
||||
user << "<span class='notice'>\The [W] clips onto \the [src] snugly.</span>"
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/GetAccess()
|
||||
return access_id ? access_id.GetAccess() : ..()
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/examine(mob/user)
|
||||
..()
|
||||
if(access_id)
|
||||
user << "There is \icon[access_id] \a [access_id] clipped onto it."
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/equipped(mob/living/simple_animal/user)
|
||||
if(istype(user))
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/dropped(mob/living/simple_animal/user)
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/clothing/accessory/petcollar/process()
|
||||
var/mob/living/simple_animal/M = loc
|
||||
// if it wasn't intentionally unequipped but isn't being worn, possibly gibbed
|
||||
if(istype(M) && src == M.collar && M.stat != DEAD)
|
||||
return
|
||||
|
||||
var/area/t = get_area(M)
|
||||
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
|
||||
if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
|
||||
//give the syndicats a bit of stealth
|
||||
a.autosay("[M] has been vandalized in Space!", "[M]'s Death Alarm")
|
||||
else
|
||||
a.autosay("[M] has been vandalized in [t.name]!", "[M]'s Death Alarm")
|
||||
qdel(a)
|
||||
processing_objects -= src
|
||||
|
||||
/proc/english_accessory_list(obj/item/clothing/under/U)
|
||||
if(!istype(U) || !U.accessories.len)
|
||||
|
||||
@@ -116,7 +116,6 @@
|
||||
dat += text("\n<A href='?src=\ref[];print_p=1'>Print Record</A><BR>\n<A href='?src=\ref[];screen=2'>Back</A><BR>", src, src)
|
||||
if(5.0)
|
||||
dat += "<CENTER><B>Virus Database</B></CENTER>"
|
||||
/* Advanced diseases is weak! Feeble! Glory to virus2!
|
||||
for(var/Dt in typesof(/datum/disease/))
|
||||
var/datum/disease/Dis = new Dt(0)
|
||||
if(istype(Dis, /datum/disease/advance))
|
||||
@@ -124,18 +123,13 @@
|
||||
if(!Dis.desc)
|
||||
continue
|
||||
dat += "<br><a href='?src=\ref[src];vir=[Dt]'>[Dis.name]</a>"
|
||||
*/
|
||||
for (var/ID in virusDB)
|
||||
var/datum/data/record/v = virusDB[ID]
|
||||
dat += "<br><a href='?src=\ref[src];vir=\ref[v]'>[v.fields["name"]]</a>"
|
||||
|
||||
dat += "<br><a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
if(6.0)
|
||||
dat += "<center><b>Medical Robot Monitor</b></center>"
|
||||
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
dat += "<br><b>Medical Robots:</b>"
|
||||
var/bdat = null
|
||||
for(var/obj/machinery/bot/medbot/M in world)
|
||||
for(var/mob/living/simple_animal/bot/medbot/M in world)
|
||||
|
||||
if(M.z != computer.z) continue //only find medibots on the same z-level as the computer
|
||||
var/turf/bl = get_turf(M)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/datum/table_recipe/ed209
|
||||
name = "ED209"
|
||||
result = /obj/machinery/bot/ed209
|
||||
result = /mob/living/simple_animal/bot/ed209
|
||||
reqs = list(/obj/item/robot_parts/robot_suit = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/clothing/suit/armor/vest = 1,
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
/datum/table_recipe/secbot
|
||||
name = "Secbot"
|
||||
result = /obj/machinery/bot/secbot
|
||||
result = /mob/living/simple_animal/bot/secbot
|
||||
reqs = list(/obj/item/device/assembly/signaler = 1,
|
||||
/obj/item/clothing/head/helmet = 1,
|
||||
/obj/item/weapon/melee/baton = 1,
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/datum/table_recipe/cleanbot
|
||||
name = "Cleanbot"
|
||||
result = /obj/machinery/bot/cleanbot
|
||||
result = /mob/living/simple_animal/bot/cleanbot
|
||||
reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/datum/table_recipe/floorbot
|
||||
name = "Floorbot"
|
||||
result = /obj/machinery/bot/floorbot
|
||||
result = /mob/living/simple_animal/bot/floorbot
|
||||
reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1,
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
/datum/table_recipe/medbot
|
||||
name = "Medbot"
|
||||
result = /obj/machinery/bot/medbot
|
||||
result = /mob/living/simple_animal/bot/medbot
|
||||
reqs = list(/obj/item/device/healthanalyzer = 1,
|
||||
/obj/item/weapon/storage/firstaid = 1,
|
||||
/obj/item/device/assembly/prox_sensor = 1,
|
||||
@@ -192,4 +192,12 @@
|
||||
result = /obj/item/weapon/soap/ducttape
|
||||
time = 100
|
||||
reqs = list(/obj/item/stack/tape_roll = 1,
|
||||
/datum/reagent/liquidgibs = 10)
|
||||
/datum/reagent/liquidgibs = 10)
|
||||
|
||||
/datum/table_recipe/garrote
|
||||
name = "Makeshift Garrote"
|
||||
result = /obj/item/weapon/twohanded/garrote/improvised
|
||||
time = 15
|
||||
reqs = list(/obj/item/stack/sheet/wood = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles
|
||||
@@ -149,6 +149,13 @@
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/cans/cola(src)
|
||||
|
||||
|
||||
/obj/item/device/guitar/jello_guitar //Antcolon3: Dan Jello
|
||||
name = "Dan Jello's Pink Guitar"
|
||||
desc = "Dan Jello's special pink guitar."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "jello_guitar"
|
||||
item_state = "jello_guitar"
|
||||
|
||||
//////////////////////////////////
|
||||
//////////// Clothing ////////////
|
||||
//////////////////////////////////
|
||||
|
||||
@@ -151,7 +151,6 @@ var/list/event_last_fired = list()
|
||||
//new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 40, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
@@ -179,7 +178,6 @@ var/list/event_last_fired = list()
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
M << "<br>"
|
||||
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in machines)
|
||||
for(var/mob/living/simple_animal/bot/bot in machines)
|
||||
if(prob(botEmagChance))
|
||||
bot.Emag()
|
||||
bot.emag_act()
|
||||
|
||||
/proc/generate_ion_law(ionMessage)
|
||||
if(ionMessage)
|
||||
|
||||
@@ -325,29 +325,33 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
/obj/effect/hallucination/delusion
|
||||
var/list/image/delusions = list()
|
||||
|
||||
/obj/effect/hallucination/delusion/New(loc,var/mob/living/carbon/T)
|
||||
/obj/effect/hallucination/delusion/New(loc, mob/living/carbon/T, force_kind = null, duration = 300,skip_nearby = 1, custom_icon = null, custom_icon_file = null)
|
||||
target = T
|
||||
var/image/A = null
|
||||
var/kind = rand(1,3)
|
||||
var/kind = force_kind ? force_kind : pick("clown", "corgi", "carp", "skeleton", "demon")
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
if(H == target)
|
||||
continue
|
||||
if(H in view(target))
|
||||
if(skip_nearby && (H in view(target)))
|
||||
continue
|
||||
switch(kind)
|
||||
if(1)//Clown
|
||||
if("clown")//Clown
|
||||
A = image('icons/mob/animal.dmi',H,"clown")
|
||||
if(2)//Carp
|
||||
if("carp")//Carp
|
||||
A = image('icons/mob/animal.dmi',H,"carp")
|
||||
if(3)//Corgi
|
||||
if("corgi")//Corgi
|
||||
A = image('icons/mob/pets.dmi',H,"corgi")
|
||||
if(4)//Skeletons
|
||||
if("skeleton")//Skeletons
|
||||
A = image('icons/mob/human.dmi',H,"skeleton_s")
|
||||
if("demon")//Demon
|
||||
A = image('icons/mob/mob.dmi',H,"daemon")
|
||||
if("custom")
|
||||
A = image(custom_icon_file, H, custom_icon)
|
||||
A.override = 1
|
||||
if(target.client)
|
||||
delusions |= A
|
||||
target.client.images |= A
|
||||
sleep(300)
|
||||
sleep(duration)
|
||||
for(var/image/I in delusions)
|
||||
if(target.client)
|
||||
target.client.images.Remove(I)
|
||||
|
||||
@@ -651,13 +651,6 @@ datum/recipe/microwave/slimesandwich
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/sashimi
|
||||
|
||||
// Fuck Science!
|
||||
/datum/recipe/microwave/ruinedvirusdish
|
||||
items = list(
|
||||
/obj/item/weapon/virusdish
|
||||
)
|
||||
result = /obj/item/weapon/ruinedvirusdish
|
||||
|
||||
/datum/recipe/microwave/mashedtaters
|
||||
fruit = list("potato" = 1)
|
||||
reagents = list("gravy" = 5)
|
||||
|
||||
@@ -78,4 +78,4 @@
|
||||
|
||||
/obj/item/dropped()
|
||||
. = ..()
|
||||
update_light()
|
||||
update_light()
|
||||
|
||||
@@ -52,9 +52,9 @@
|
||||
if(lum_r / mx1 != (lum_r + delta_r) / mx2 || lum_g / mx1 != (lum_g + delta_g) / mx2 || lum_b / mx1 != (lum_b + delta_b) / mx2) //Stuff would change.
|
||||
should_update = 1
|
||||
|
||||
lum_r += delta_r
|
||||
lum_g += delta_g
|
||||
lum_b += delta_b
|
||||
lum_r = max(lum_r + delta_r, 0) //Lum shouldn't drop below 1
|
||||
lum_g = max(lum_g + delta_g, 0)
|
||||
lum_b = max(lum_b + delta_b, 0)
|
||||
|
||||
if(!needs_update && should_update)
|
||||
needs_update = 1
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/sheet_per_ore = 1
|
||||
var/point_upgrade = 1
|
||||
var/list/ore_values = list(("sand" = 1), ("iron" = 1), ("plasma" = 15), ("silver" = 16), ("gold" = 18), ("uranium" = 30), ("diamond" = 50), ("bananium" = 60), ("tranquillite" = 60))
|
||||
var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"))
|
||||
var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("uranium", "gold"))
|
||||
|
||||
/obj/machinery/mineral/ore_redemption/New()
|
||||
..()
|
||||
@@ -556,14 +556,15 @@
|
||||
L.Weaken(3)
|
||||
if(ishuman(L))
|
||||
shake_camera(L, 20, 1)
|
||||
var/mob/living/carbon/human/H = L
|
||||
spawn(20)
|
||||
if(L)
|
||||
L.visible_message("<span class='danger'>[L.name] vomits from travelling through the [src.name]!</span>", "<span class='userdanger'>You throw up from travelling through the [src.name]!</span>")
|
||||
L.nutrition -= 20
|
||||
L.adjustToxLoss(-3)
|
||||
var/turf/T = get_turf(L)
|
||||
T.add_vomit_floor(L)
|
||||
playsound(L, 'sound/effects/splat.ogg', 50, 1)
|
||||
if(H && H.check_has_mouth())
|
||||
H.visible_message("<span class='danger'>[L.name] vomits from travelling through the [src.name]!</span>", "<span class='userdanger'>You throw up from travelling through the [src.name]!</span>")
|
||||
H.nutrition -= 20
|
||||
H.adjustToxLoss(-3)
|
||||
var/turf/T = get_turf(H)
|
||||
T.add_vomit_floor(H)
|
||||
playsound(H, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
/**********************Resonator**********************/
|
||||
|
||||
@@ -693,14 +694,7 @@
|
||||
mouse_opacity = 1
|
||||
faction = list("neutral")
|
||||
a_intent = I_HARM
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
wander = 0
|
||||
idle_vision_range = 5
|
||||
|
||||
@@ -257,6 +257,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return 1
|
||||
|
||||
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source)
|
||||
if(message)
|
||||
src << "<span class='ghostalert'>[message]</span>"
|
||||
src << "<span class='ghostalert'><a href=?src=\ref[src];reenter=1>(Click to re-enter)</a></span>"
|
||||
if(sound)
|
||||
src << sound(sound)
|
||||
|
||||
/mob/dead/observer/proc/show_me_the_hud(hud_index)
|
||||
var/datum/atom_hud/H = huds[hud_index]
|
||||
H.add_hud_to(src)
|
||||
@@ -643,6 +650,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/mob/living/carbon/human/new_char = new(get_turf(src))
|
||||
client.prefs.copy_to(new_char)
|
||||
if(mind)
|
||||
mind.active = 1
|
||||
mind.transfer_to(new_char)
|
||||
else
|
||||
new_char.key = key
|
||||
@@ -114,7 +114,7 @@
|
||||
message = stars(message)
|
||||
|
||||
var/speaker_name = "unknown"
|
||||
if(speaker)
|
||||
if(speaker)
|
||||
speaker_name = speaker.name
|
||||
|
||||
if(vname)
|
||||
@@ -160,7 +160,7 @@
|
||||
else
|
||||
track = "[speaker_name] ([jobname])"
|
||||
else
|
||||
if(istype(follow_target, /obj/machinery/bot))
|
||||
if(istype(follow_target, /mob/living/simple_animal/bot))
|
||||
track = "<a href='byond://?src=\ref[src];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
|
||||
else
|
||||
track = "<a href='byond://?src=\ref[src];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
usr.hud_used.nightvisionicon.icon_state = "nightvision0"
|
||||
|
||||
|
||||
/mob/living/carbon/alien/assess_threat(var/obj/machinery/bot/secbot/judgebot, var/lasercolor)
|
||||
/mob/living/carbon/alien/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor)
|
||||
if(judgebot.emagged == 2)
|
||||
return 10 //Everyone is a criminal!
|
||||
var/threatcount = 0
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "alien"
|
||||
icon_state = "alien_s"
|
||||
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/xenomeat = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
var/obj/item/weapon/r_store = null
|
||||
var/obj/item/weapon/l_store = null
|
||||
var/caste = ""
|
||||
@@ -317,22 +318,27 @@ In all, this is a lot like the monkey code. /N
|
||||
/mob/living/carbon/alien/humanoid/var/temperature_resistance = T0C+75
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user as mob)
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<B><HR><FONT size=3>[name]</FONT></B>
|
||||
<BR><HR>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? text("[]", l_hand) : "Nothing")]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? text("[]", r_hand) : "Nothing")]</A>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head ? text("[]", head) : "Nothing")]</A>
|
||||
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit ? text("[]", wear_suit) : "Nothing")]</A>
|
||||
<BR><A href='?src=\ref[src];item=pockets'>Empty Pouches</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[name];size=340x480"))
|
||||
onclose(user, "mob[name]")
|
||||
return
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><B>Left Hand:</B></td><td><A href='?src=\ref[src];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td><B>Right Hand:</B></td><td><A href='?src=\ref[src];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=\ref[src];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=\ref[src];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Pouches:</B></td><td><A href='?src=\ref[src];item=pockets'>[((l_store && !(l_store.flags&ABSTRACT)) || (r_store && !(r_store.flags&ABSTRACT))) ? "Full" : "<font color=grey>Empty</font>"]</A>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/canBeHandcuffed()
|
||||
return 1
|
||||
|
||||
@@ -237,15 +237,6 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<B><HR><FONT size=3>[name]</FONT></B>
|
||||
<BR><HR><BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[name];size=340x480"))
|
||||
onclose(user, "mob[name]")
|
||||
return
|
||||
|
||||
/* Commented out because it's duplicated in life.dm
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
owner.ear_deaf = 0
|
||||
|
||||
/obj/item/organ/internal/brain/xeno
|
||||
name = "thinkpan"
|
||||
desc = "It looks kind of like an enormous wad of purple bubblegum."
|
||||
icon_state = "brain-x-d"
|
||||
name = "xenomorph brain"
|
||||
desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
|
||||
icon_state = "brain-x"
|
||||
origin_tech = "biotech=7"
|
||||
|
||||
/obj/item/organ/internal/brain/New()
|
||||
..()
|
||||
|
||||
@@ -92,6 +92,42 @@
|
||||
|
||||
#undef STOMACH_ATTACK_DELAY
|
||||
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1)
|
||||
if(src.is_muzzled())
|
||||
if(message)
|
||||
src << "<span class='warning'>The muzzle prevents you from vomiting!</span>"
|
||||
return 0
|
||||
if(stun)
|
||||
Stun(4)
|
||||
if(nutrition < 100 && !blood)
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing your stomach!</span>")
|
||||
if(stun)
|
||||
Weaken(10)
|
||||
else
|
||||
if(message)
|
||||
visible_message("<span class='danger'>[src] throws up!</span>", \
|
||||
"<span class='userdanger'>You throw up!</span>")
|
||||
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1)
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/i=0 to distance)
|
||||
if(blood)
|
||||
if(T)
|
||||
T.add_blood_floor(src)
|
||||
if(stun)
|
||||
adjustBruteLoss(3)
|
||||
else
|
||||
if(T)
|
||||
T.add_vomit_floor(src)
|
||||
nutrition -= lost_nutrition
|
||||
if(stun)
|
||||
adjustToxLoss(-3)
|
||||
T = get_step(T, dir)
|
||||
if (is_blocked_turf(T))
|
||||
break
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/gib()
|
||||
for(var/obj/item/organ/internal/I in internal_organs)
|
||||
if(isturf(loc))
|
||||
@@ -107,19 +143,6 @@
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
. = ..()
|
||||
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/M as mob)
|
||||
if(!istype(M, /mob/living/carbon)) return
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
if (H.hand)
|
||||
temp = H.organs_by_name["l_hand"]
|
||||
if(temp && !temp.is_usable())
|
||||
H << "\red You can't use your [temp.name]"
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0)
|
||||
if(status_flags & GODMODE) //godmode
|
||||
return 0
|
||||
@@ -546,31 +569,34 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
|
||||
/mob/living/carbon/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>"}
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=\ref[src];item=[slot_back]'>[back ? back : "Nothing"]</A>"
|
||||
var/dat = {"<table>
|
||||
<tr><td><B>Left Hand:</B></td><td><A href='?src=\ref[src];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td><B>Right Hand:</B></td><td><A href='?src=\ref[src];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank))
|
||||
dat += "<BR><A href='?src=\ref[src];internal=1'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
dat += " <A href='?src=\ref[src];internal=[slot_back]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=\ref[src];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
|
||||
dat += "<tr><td><B>Handcuffed:</B> <A href='?src=\ref[src];item=[slot_handcuffed]'>Remove</A></td></tr>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A>"
|
||||
dat += "<tr><td><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A></td></tr>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
dat += {"</table>
|
||||
<A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
@@ -816,8 +842,8 @@ so that different stomachs can handle things in different ways VB*/
|
||||
toEat.reagents.trans_to(src, toEat.reagents.total_volume*toEat.transfer_efficiency)
|
||||
|
||||
/mob/living/carbon/get_access()
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(istype(I))
|
||||
return I
|
||||
. = ..()
|
||||
|
||||
return null
|
||||
var/obj/item/I = get_active_hand()
|
||||
if(I)
|
||||
. |= I.GetAccess()
|
||||
|
||||
@@ -23,4 +23,17 @@
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user, src))
|
||||
return 1
|
||||
..()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
user.ContractDisease(D)
|
||||
|
||||
for(var/datum/disease/D in user.viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
return 0
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
var/list/stomach_contents = list()
|
||||
var/list/internal_organs = list()
|
||||
var/brain_op_stage = 0.0
|
||||
var/list/datum/disease2/disease/virus2 = list()
|
||||
var/antibodies = 0
|
||||
var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm
|
||||
|
||||
|
||||
@@ -177,9 +177,27 @@
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
valid_hairstyles += hairstyle
|
||||
if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head...
|
||||
var/obj/item/organ/external/head/H = organs_by_name["head"]
|
||||
if(!H)
|
||||
return
|
||||
if(species.name in S.species_allowed) //If this is a hairstyle native to the user's species...
|
||||
if(H.model == "Morpheus Cyberkinetics") //Check to see if they have the default head.
|
||||
valid_hairstyles += hairstyle //Give them their hairstyles if they do.
|
||||
continue
|
||||
else //If they don't have the default head, they shouldn't be getting any hairstyles they wouldn't normally.
|
||||
continue
|
||||
else
|
||||
if(H.model == "Morpheus Cyberkinetics") //If the hairstyle is not native to the user's species, and they're using the default head, don't let them access it.
|
||||
continue
|
||||
else
|
||||
if("Human" in S.species_allowed) //If the user has a robotic head and the hairstyle can fit humans, let them use it as a wig for their humanoid robot head.
|
||||
valid_hairstyles += hairstyle
|
||||
continue
|
||||
else
|
||||
if(!(species.name in S.species_allowed)) //If the user is not a species who can have robotic heads, use the default handling.
|
||||
continue
|
||||
valid_hairstyles += hairstyle
|
||||
|
||||
return valid_hairstyles
|
||||
|
||||
@@ -192,9 +210,27 @@
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head...
|
||||
var/obj/item/organ/external/head/H = organs_by_name["head"]
|
||||
if(!H)
|
||||
continue // No head, no hair
|
||||
if(species.name in S.species_allowed) //If this is a facial hair style native to the user's species...
|
||||
if(H.model == "Morpheus Cyberkinetics") //Check to see if they have the default head.
|
||||
valid_facial_hairstyles += facialhairstyle //Give them their facial hair styles if they do.
|
||||
continue
|
||||
else //If they don't have the default head, they shouldn't be getting any facial hair styles they wouldn't normally.
|
||||
continue
|
||||
else
|
||||
|
||||
valid_facial_hairstyles += facialhairstyle
|
||||
if(H.model == "Morpheus Cyberkinetics") //If the facial hair style is not native to the user's species, and they're using the default head, don't let them access it.
|
||||
continue
|
||||
else
|
||||
if("Human" in S.species_allowed) //If the user has a robotic head and the facial hair style can fit humans, let them use it as a postiche for their humanoid robot head.
|
||||
valid_facial_hairstyles += facialhairstyle
|
||||
continue
|
||||
else //If the user is not a species who can have robotic heads, use the default handling.
|
||||
if(!(species.name in S.species_allowed))
|
||||
continue
|
||||
valid_facial_hairstyles += facialhairstyle
|
||||
|
||||
return valid_facial_hairstyles
|
||||
|
||||
@@ -789,8 +789,6 @@
|
||||
for(var/mob/M in range(location,aoe_range))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
|
||||
continue
|
||||
if(!airborne_can_reach(location,M,aoe_range))
|
||||
continue
|
||||
// Now, we don't have this:
|
||||
//new /obj/effects/fart_cloud(T,L)
|
||||
// But:
|
||||
@@ -851,4 +849,4 @@
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
flavor_text = TextPreview(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
|
||||
update_flavor_text()
|
||||
|
||||
@@ -161,9 +161,6 @@
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
|
||||
if(iscarbon(tmob) && prob(10))
|
||||
spread_disease_to(tmob, "Contact")
|
||||
|
||||
//BubbleWrap - Should stop you pushing a restrained person out of the way
|
||||
//i still don't get it, is this supposed to be 'bubblewrapping' or was it made by a guy named 'BubbleWrap'
|
||||
if(ishuman(tmob))
|
||||
@@ -636,10 +633,6 @@
|
||||
// called when something steps onto a human
|
||||
// this handles mulebots and vehicles
|
||||
/mob/living/carbon/human/Crossed(var/atom/movable/AM)
|
||||
if(istype(AM, /obj/machinery/bot/mulebot))
|
||||
var/obj/machinery/bot/mulebot/MB = AM
|
||||
MB.RunOver(src)
|
||||
|
||||
if(istype(AM, /obj/vehicle))
|
||||
var/obj/vehicle/V = AM
|
||||
V.RunOver(src)
|
||||
@@ -839,15 +832,6 @@
|
||||
U.accessories -= A
|
||||
update_inv_w_uniform()
|
||||
|
||||
if (href_list["refresh"])
|
||||
if((machine)&&(in_range(src, usr)))
|
||||
show_inv(machine)
|
||||
|
||||
if (href_list["mach_close"])
|
||||
var/t1 = text("window=[]", href_list["mach_close"])
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
|
||||
if (href_list["criminal"])
|
||||
if(hasHUD(usr,"security"))
|
||||
|
||||
@@ -1255,44 +1239,6 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/vomit(hairball=0)
|
||||
if(stat==DEAD)return
|
||||
|
||||
if(!check_has_mouth())
|
||||
return
|
||||
|
||||
if(!lastpuke)
|
||||
lastpuke = 1
|
||||
src << "<spawn class='warning'>You feel nauseous..."
|
||||
spawn(150) //15 seconds until second warning
|
||||
src << "<spawn class='warning'>You feel like you are about to throw up!"
|
||||
spawn(100) //and you have 10 more for mad dash to the bucket
|
||||
Stun(5)
|
||||
|
||||
if(hairball)
|
||||
src.visible_message("<span class='warning'>[src] hacks up a hairball!</span>","<span class='warning'>You hack up a hairball!</span>")
|
||||
else
|
||||
src.visible_message("<span class='warning'>[src] throws up!</span>","<span class='warning'>You throw up!</span>")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/turf/location = loc
|
||||
if (istype(location, /turf/simulated))
|
||||
location.add_vomit_floor(src, 1)
|
||||
|
||||
var/stomach_len = src.stomach_contents.len
|
||||
if (stomach_len)
|
||||
var/content = src.stomach_contents[stomach_len]
|
||||
if (istype(content, /atom/movable))
|
||||
var/atom/movable/AM = content
|
||||
src.stomach_contents.Remove(AM)
|
||||
AM.loc = location
|
||||
|
||||
if(!hairball)
|
||||
nutrition -= 40
|
||||
adjustToxLoss(-3)
|
||||
spawn(350) //wait 35 seconds before next volley
|
||||
lastpuke = 0
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/get_visible_gender()
|
||||
if(wear_suit && wear_suit.flags_inv & HIDEJUMPSUIT && ((head && head.flags_inv & HIDEMASK) || wear_mask))
|
||||
@@ -1324,12 +1270,6 @@
|
||||
H.brainmob.mind.transfer_to(src)
|
||||
qdel(H)
|
||||
|
||||
|
||||
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
V.cure(src)
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/is_lung_ruptured()
|
||||
@@ -1619,26 +1559,36 @@
|
||||
// Allows IPC's to change their monitor display
|
||||
/mob/living/carbon/human/proc/change_monitor()
|
||||
set category = "IC"
|
||||
set name = "Change Monitor Display"
|
||||
set desc = "Change the display on your monitor."
|
||||
set name = "Change Monitor/Optical Display"
|
||||
set desc = "Change the display on your monitor or the colour of your optics."
|
||||
|
||||
if(stat || paralysis || stunned || weakened)
|
||||
src << "<span class='warning'>You cannot change your monitor display in your current state.</span>"
|
||||
if(incapacitated())
|
||||
src << "<span class='warning'>You cannot change your monitor or optical display in your current state.</span>"
|
||||
return
|
||||
|
||||
var/list/hair = list()
|
||||
for(var/i in hair_styles_list)
|
||||
var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i]
|
||||
if(species.name in tmp_hair.species_allowed)
|
||||
hair += i
|
||||
if(species.flags & ALL_RPARTS) //If they can have a fully cybernetic body...
|
||||
if(client.prefs.rlimb_data["head"]) //If head is present here, that means it's not the default Morpheus. Thus, no screen to adjust. Instead, let them change the colour of their optics!
|
||||
var/optic_colour = input(src, "Select optic colour", rgb(r_markings, g_markings, b_markings)) as color|null
|
||||
if(optic_colour)
|
||||
r_markings = hex2num(copytext(optic_colour, 2, 4))
|
||||
g_markings = hex2num(copytext(optic_colour, 4, 6))
|
||||
b_markings = hex2num(copytext(optic_colour, 6, 8))
|
||||
|
||||
var/new_style = input(src, "Select a monitor display", "Monitor Display") as null|anything in hair
|
||||
if(stat || paralysis || stunned || weakened)
|
||||
return
|
||||
if(new_style)
|
||||
h_style = new_style
|
||||
update_markings()
|
||||
else if(!client.prefs.rlimb_data["head"])//Means that the character has the default Morpheus head, which has a screen. Time to customize.
|
||||
var/list/hair = list()
|
||||
for(var/i in hair_styles_list)
|
||||
var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i]
|
||||
if(species.name in tmp_hair.species_allowed)
|
||||
hair += i
|
||||
|
||||
update_hair()
|
||||
var/new_style = input(src, "Select a monitor display", "Monitor Display", h_style) as null|anything in hair
|
||||
if(incapacitated())
|
||||
return
|
||||
if(new_style)
|
||||
h_style = new_style
|
||||
|
||||
update_hair()
|
||||
|
||||
//Putting a couple of procs here that I don't know where else to dump.
|
||||
//Mostly going to be used for Vox and Vox Armalis, but other human mobs might like them (for adminbuse).
|
||||
@@ -1752,7 +1702,7 @@
|
||||
if(M.stat == 2)
|
||||
M.gib()
|
||||
|
||||
/mob/living/carbon/human/assess_threat(var/obj/machinery/bot/secbot/judgebot, var/lasercolor)
|
||||
/mob/living/carbon/human/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor)
|
||||
if(judgebot.emagged == 2)
|
||||
return 10 //Everyone is a criminal!
|
||||
|
||||
@@ -1929,7 +1879,12 @@
|
||||
return 1.0 + 0.5*(30 - age)/80
|
||||
|
||||
/mob/living/carbon/human/get_access()
|
||||
. = ..() //objects in hand
|
||||
if(!. && wear_id) //nothing in hand, try ID
|
||||
return wear_id
|
||||
//otherwise return hand/nothing
|
||||
. = ..()
|
||||
|
||||
if(wear_id)
|
||||
. |= wear_id.GetAccess()
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
if(U.accessories)
|
||||
for(var/obj/item/clothing/accessory/A in U.accessories)
|
||||
. |= A.GetAccess()
|
||||
@@ -48,10 +48,6 @@
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
|
||||
return
|
||||
else
|
||||
if(istype(M,/mob/living/carbon))
|
||||
// log_debug("No gloves, [M] is truing to infect [src]")
|
||||
M.spread_disease_to(src, "Contact")
|
||||
|
||||
var/datum/martial_art/attacker_style = M.martial_art
|
||||
|
||||
|
||||
@@ -64,8 +64,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
update_mutations()
|
||||
check_mutations=0
|
||||
|
||||
handle_virus_updates()
|
||||
|
||||
handle_shock()
|
||||
handle_pain()
|
||||
handle_heartbeat()
|
||||
@@ -345,12 +343,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
|
||||
if(breath)
|
||||
loc.assume_air(breath)
|
||||
//spread virus2
|
||||
if(virus2.len > 0)
|
||||
if(prob(10) && get_infection_chance(src))
|
||||
for(var/mob/living/carbon/M in view(1,src))
|
||||
src.spread_disease_to(M)
|
||||
|
||||
|
||||
|
||||
// USED IN DEATHWHISPERS
|
||||
@@ -731,32 +723,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
adjustOxyLoss(-(light_amount))
|
||||
//TODO: heal wounds, heal broken limbs.
|
||||
|
||||
if(species.light_dam)
|
||||
var/light_amount = 0
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
light_amount = T.get_lumcount()*10
|
||||
if(light_amount > species.light_dam && !incorporeal_move) //if there's enough light, start dying
|
||||
if(species.light_effect_amp)
|
||||
adjustFireLoss(4.7) //This gets multiplied by 1.5 due to Shadowling's innate fire weakness, so it ends up being about 7.
|
||||
else
|
||||
adjustFireLoss(1)
|
||||
adjustBruteLoss(1)
|
||||
src << "<span class='userdanger'>The light burns you!</span>"
|
||||
src << 'sound/weapons/sear.ogg'
|
||||
else //heal in the dark
|
||||
if(species.light_effect_amp)
|
||||
adjustFireLoss(-5)
|
||||
adjustBruteLoss(-5)
|
||||
adjustBrainLoss(-25) //gibbering shadowlings are hilarious but also bad to have
|
||||
adjustCloneLoss(-1)
|
||||
SetWeakened(0)
|
||||
SetStunned(0)
|
||||
else
|
||||
adjustFireLoss(-1)
|
||||
adjustBruteLoss(-1)
|
||||
|
||||
|
||||
//The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered.
|
||||
if(species.flags & CAN_BE_FAT)
|
||||
if(FAT in mutations)
|
||||
@@ -965,6 +931,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
src << "<span class='alert'>Your psy-connection grows too faint to maintain!</span>"
|
||||
isRemoteObserve = 0
|
||||
|
||||
if(remote_view)
|
||||
isRemoteObserve = 1
|
||||
|
||||
if(!isRemoteObserve && client && !client.adminobs)
|
||||
remoteview_target = null
|
||||
reset_view(null)
|
||||
@@ -978,7 +947,23 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
// Puke if toxloss is too high
|
||||
if(!stat)
|
||||
if (getToxLoss() >= 45 && nutrition > 20)
|
||||
vomit()
|
||||
lastpuke ++
|
||||
if(lastpuke >= 25) // about 25 second delay I guess
|
||||
Stun(5)
|
||||
|
||||
visible_message("<span class='danger'>[src] throws up!</span>", \
|
||||
"<span class='userdanger'>[src] throws up!</span>")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/turf/location = loc
|
||||
if (istype(location, /turf/simulated))
|
||||
location.add_vomit_floor(src, 1)
|
||||
|
||||
nutrition -= 20
|
||||
adjustToxLoss(-3)
|
||||
|
||||
// make it so you can only puke so fast
|
||||
lastpuke = 0
|
||||
|
||||
//0.1% chance of playing a scary sound to someone who's in complete darkness
|
||||
if(isturf(loc) && rand(1,1000) == 1)
|
||||
@@ -987,69 +972,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
if(L && L.lum_r + L.lum_g + L.lum_b == 0)
|
||||
playsound_local(src,pick(scarySounds),50, 1, -1)
|
||||
|
||||
// Separate proc so we can jump out of it when we've succeeded in spreading disease.
|
||||
/mob/living/carbon/human/proc/findAirborneVirii()
|
||||
for(var/obj/effect/decal/cleanable/blood/B in get_turf(src))
|
||||
if(B.virus2.len)
|
||||
for (var/ID in B.virus2)
|
||||
var/datum/disease2/disease/V = B.virus2[ID]
|
||||
if (infect_virus2(src,V))
|
||||
return 1
|
||||
|
||||
for(var/obj/effect/decal/cleanable/mucus/M in get_turf(src))
|
||||
if(M.virus2.len)
|
||||
for (var/ID in M.virus2)
|
||||
var/datum/disease2/disease/V = M.virus2[ID]
|
||||
if (infect_virus2(src,V))
|
||||
return 1
|
||||
|
||||
for(var/obj/effect/decal/cleanable/poop/P in get_turf(src))
|
||||
if(P.virus2.len)
|
||||
for (var/ID in P.virus2)
|
||||
var/datum/disease2/disease/V = P.virus2[ID]
|
||||
if (infect_virus2(src,V))
|
||||
return 1
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/handle_virus_updates()
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
if(bodytemperature > 406)
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
V.cure(src)
|
||||
if(mob_master.current_cycle % 3) //don't spam checks over all objects in view every tick.
|
||||
for(var/obj/effect/decal/cleanable/O in view(1,src))
|
||||
if(istype(O,/obj/effect/decal/cleanable/blood))
|
||||
var/obj/effect/decal/cleanable/blood/B = O
|
||||
if(B.virus2.len)
|
||||
for (var/ID in B.virus2)
|
||||
var/datum/disease2/disease/V = B.virus2[ID]
|
||||
infect_virus2(src,V.getcopy())
|
||||
|
||||
else if(istype(O,/obj/effect/decal/cleanable/mucus))
|
||||
var/obj/effect/decal/cleanable/mucus/M = O
|
||||
if(M.virus2.len)
|
||||
for (var/ID in M.virus2)
|
||||
var/datum/disease2/disease/V = M.virus2[ID]
|
||||
infect_virus2(src,V.getcopy())
|
||||
|
||||
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
if(isnull(V)) // Trying to figure out a runtime error that keeps repeating
|
||||
CRASH("virus2 nulled before calling activate()")
|
||||
else
|
||||
V.activate(src)
|
||||
// activate may have deleted the virus
|
||||
if(!V) continue
|
||||
|
||||
// check if we're immune
|
||||
if(V.antigen & src.antibodies)
|
||||
V.dead = 1
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/handle_changeling()
|
||||
if(mind)
|
||||
if(mind.changeling)
|
||||
@@ -1183,16 +1105,15 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
|
||||
for(var/mob/living/carbon/human/H in range(decaylevel, src))
|
||||
if(prob(5))
|
||||
if(airborne_can_reach(get_turf(src), get_turf(H)))
|
||||
if(istype(loc,/obj/item/bodybag))
|
||||
return
|
||||
var/obj/item/clothing/mask/M = H.wear_mask
|
||||
if(M && (M.flags & MASKCOVERSMOUTH))
|
||||
return
|
||||
if(H.species && H.species.flags & NO_BREATHE)
|
||||
return //no puking if you can't smell!
|
||||
H << "<spawn class='warning'>You smell something foul..."
|
||||
H.fakevomit()
|
||||
if(istype(loc,/obj/item/bodybag))
|
||||
return
|
||||
var/obj/item/clothing/mask/M = H.wear_mask
|
||||
if(M && (M.flags & MASKCOVERSMOUTH))
|
||||
return
|
||||
if(H.species && H.species.flags & NO_BREATHE)
|
||||
return //no puking if you can't smell!
|
||||
H << "<spawn class='warning'>You smell something foul..."
|
||||
H.fakevomit()
|
||||
|
||||
/mob/living/carbon/human/proc/handle_heartbeat()
|
||||
var/client/C = src.client
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
//unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws)
|
||||
//inherent_verbs = list(/mob/living/proc/ventcrawl)
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey
|
||||
|
||||
total_health = 75
|
||||
brute_mod = 1.5
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
default_language = "Galactic Common"
|
||||
unarmed_type = /datum/unarmed_attack/claws
|
||||
light_dam = 2
|
||||
darksight = 8
|
||||
|
||||
blood_color = "#CCCCCC"
|
||||
@@ -16,8 +15,8 @@
|
||||
"brain" = /obj/item/organ/internal/brain
|
||||
)
|
||||
|
||||
flags = NO_BLOOD | NO_BREATHE | NO_SCAN
|
||||
bodyflags = FEET_NOSLIP
|
||||
flags = NO_BLOOD | NO_BREATHE | RADIMMUNE
|
||||
virus_immune = 1
|
||||
dietflags = DIET_OMNI //the mutation process allowed you to now digest all foods regardless of initial race
|
||||
reagent_tag = PROCESS_ORG
|
||||
suicide_messages = list(
|
||||
@@ -26,5 +25,13 @@
|
||||
"is twisting their own neck!",
|
||||
"is staring into the closest light source!")
|
||||
|
||||
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
|
||||
H.dust()
|
||||
/datum/species/shadow/handle_life(var/mob/living/carbon/human/H)
|
||||
var/light_amount = 0
|
||||
if(isturf(H.loc))
|
||||
var/turf/T = H.loc
|
||||
light_amount = T.get_lumcount()*10
|
||||
|
||||
if(light_amount > 2) //if there's enough light, start dying
|
||||
H.take_overall_damage(1,1)
|
||||
else if (light_amount < 2) //heal in the dark
|
||||
H.heal_overall_damage(1,1)
|
||||
@@ -55,9 +55,6 @@
|
||||
var/brute_mod = null // Physical damage reduction/malus.
|
||||
var/burn_mod = null // Burn damage reduction/malus.
|
||||
|
||||
var/light_dam //Light level above which species takes damage, and below which it heals.
|
||||
var/light_effect_amp //If 0, takes/heals 1 burn and brute per tick. Otherwise, both healing and damage effects are amplified.
|
||||
|
||||
var/total_health = 100
|
||||
var/punchdamagelow = 0 //lowest possible punch damage
|
||||
var/punchdamagehigh = 9 //highest possible punch damage
|
||||
@@ -78,8 +75,6 @@
|
||||
var/blood_color = "#A10808" //Red.
|
||||
var/flesh_color = "#FFC896" //Pink.
|
||||
var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
|
||||
|
||||
var/base_color //Used when setting species.
|
||||
|
||||
//Used in icon caching.
|
||||
@@ -325,6 +320,8 @@
|
||||
return
|
||||
|
||||
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
|
||||
if(C.get_species() == "Monkey" || C.get_species() == "Farwa" || C.get_species() == "Stok" || C.get_species() == "Wolpin" || C.get_species() == "Neara")
|
||||
C.butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/monkey = 5)
|
||||
grant_abilities(C)
|
||||
return
|
||||
|
||||
@@ -334,6 +331,8 @@
|
||||
return
|
||||
|
||||
/datum/species/proc/handle_pre_change(var/mob/living/carbon/human/H)
|
||||
if(!H.get_species() == "Monkey" || !H.get_species() == "Farwa" || !H.get_species() == "Stok" || !H.get_species() == "Wolpin" || !H.get_species() == "Neara")
|
||||
H.butcher_results = null
|
||||
remove_abilities(H)
|
||||
return
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@
|
||||
cold_env_multiplier = 3
|
||||
|
||||
flags = IS_WHITELISTED | NO_BREATHE | HAS_LIPS | NO_INTORGANS | NO_SCAN
|
||||
clothing_flags = HAS_SOCKS
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
|
||||
bodyflags = HAS_SKIN_COLOR | NO_EYES
|
||||
dietflags = DIET_CARN
|
||||
reagent_tag = PROCESS_ORG
|
||||
@@ -712,9 +712,9 @@
|
||||
|
||||
passive_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
|
||||
|
||||
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA | NO_POISON | RADIMMUNE
|
||||
clothing_flags = HAS_SOCKS
|
||||
bodyflags = HAS_SKIN_COLOR
|
||||
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA | NO_POISON | RADIMMUNE | ALL_RPARTS
|
||||
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
|
||||
bodyflags = HAS_SKIN_COLOR | HAS_MARKINGS | HAS_HEAD_ACCESSORY
|
||||
dietflags = 0 //IPCs can't eat, so no diet
|
||||
blood_color = "#1F181F"
|
||||
flesh_color = "#AAAAAA"
|
||||
|
||||
@@ -461,7 +461,7 @@ var/global/list/damage_icon_parts = list()
|
||||
//if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN
|
||||
// hair_standing.Blend(debrained_s, ICON_OVERLAY)
|
||||
if(hair_style && hair_style.species_allowed)
|
||||
if(src.species.name in hair_style.species_allowed)
|
||||
if((src.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))
|
||||
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(src.get_species() == "Slime People") // I am el worstos
|
||||
hair_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND)
|
||||
@@ -499,7 +499,7 @@ var/global/list/damage_icon_parts = list()
|
||||
if(f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
|
||||
if(facial_hair_style && facial_hair_style.species_allowed)
|
||||
if(src.species.name in facial_hair_style.species_allowed)
|
||||
if((src.species.name in facial_hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))
|
||||
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
if(src.get_species() == "Slime People") // I am el worstos
|
||||
facial_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND)
|
||||
@@ -957,7 +957,8 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
/mob/living/carbon/human/update_hud() //TODO: do away with this if possible
|
||||
if(client)
|
||||
client.screen |= contents
|
||||
for(var/obj/item/I in get_all_slots())
|
||||
client.screen |= I // Items only please, no arms allowed
|
||||
if(hud_used)
|
||||
hud_used.hidden_inventory_update() //Updates the screenloc of the items on the 'other' inventory bar
|
||||
update_inv_handcuffed(0) // update handcuff overlay
|
||||
|
||||
@@ -84,12 +84,7 @@
|
||||
|
||||
if(breath)
|
||||
loc.assume_air(breath)
|
||||
//spread virus2
|
||||
if(virus2.len > 0)
|
||||
if(prob(10) && get_infection_chance(src))
|
||||
for(var/mob/living/carbon/M in view(1,src))
|
||||
src.spread_disease_to(M)
|
||||
|
||||
air_update_turf()
|
||||
|
||||
//Third link in a breath chain, calls handle_breath_temperature()
|
||||
/mob/living/carbon/proc/check_breath(datum/gas_mixture/breath)
|
||||
|
||||
@@ -66,6 +66,12 @@
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
..()
|
||||
|
||||
/mob/living/carbon/slime/Destroy()
|
||||
for(var/obj/machinery/computer/camera_advanced/xenobio/X in machines)
|
||||
if(src in X.stored_slimes)
|
||||
X.stored_slimes -= src
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/slime/regenerate_icons()
|
||||
icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
|
||||
overlays.len = 0
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
if (!( machine.check_eye(src) ))
|
||||
reset_view(null)
|
||||
else
|
||||
if(!client.adminobs)
|
||||
if(!remote_view && !client.adminobs)
|
||||
reset_view(null)
|
||||
|
||||
/mob/living/proc/update_sight()
|
||||
|
||||
@@ -386,6 +386,9 @@
|
||||
C.handcuffed = initial(C.handcuffed)
|
||||
C.heart_attack = 0
|
||||
|
||||
for(var/datum/disease/D in C.viruses)
|
||||
D.cure(0)
|
||||
|
||||
// restore all of the human's blood and reset their shock stage
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/human_mob = src
|
||||
@@ -952,4 +955,15 @@
|
||||
|
||||
//used in datum/reagents/reaction() proc
|
||||
/mob/living/proc/get_permeability_protection()
|
||||
return 0
|
||||
return 0
|
||||
|
||||
/mob/living/proc/harvest(mob/living/user)
|
||||
if(qdeleted(src))
|
||||
return
|
||||
if(butcher_results)
|
||||
for(var/path in butcher_results)
|
||||
for(var/i = 1, i <= butcher_results[path], i++)
|
||||
new path(loc)
|
||||
butcher_results.Remove(path) //In case you want to have things like simple_animals drop their butcher results on gib, so it won't double up below.
|
||||
visible_message("<span class='notice'>[user] butchers [src].</span>")
|
||||
gib()
|
||||
@@ -52,4 +52,6 @@
|
||||
var/list/datum/action/actions = list()
|
||||
var/step_count = 0
|
||||
|
||||
var/list/butcher_results = null
|
||||
|
||||
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
|
||||
@@ -430,7 +430,9 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
|
||||
spawn(0)
|
||||
flick_overlay(image('icons/mob/talk.dmi', src, "h[speech_bubble_test]",MOB_LAYER+1), speech_bubble_recipients, 30)
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "h[speech_bubble_test]", MOB_LAYER + 1)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
flick_overlay(I, speech_bubble_recipients, 30)
|
||||
|
||||
if(watching.len)
|
||||
var/rendered = "<span class='game say'><span class='name'>[src.name]</span> [not_heard].</span>"
|
||||
@@ -441,4 +443,6 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return 1
|
||||
|
||||
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
|
||||
flick_overlay(image('icons/mob/talk.dmi', bubble_loc, bubble_state,MOB_LAYER+1), bubble_recipients, 30)
|
||||
var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, MOB_LAYER + 1)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
flick_overlay(I, bubble_recipients, 30)
|
||||
@@ -41,6 +41,7 @@ var/list/ai_verbs_default = list(
|
||||
anchored = 1 // -- TLE
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
can_strip = 0
|
||||
var/list/network = list("SS13","Telecomms","Research Outpost","Mining Outpost")
|
||||
var/obj/machinery/camera/current = null
|
||||
var/list/connected_robots = list()
|
||||
@@ -80,7 +81,7 @@ var/list/ai_verbs_default = list(
|
||||
var/can_shunt = 1
|
||||
var/last_announcement = ""
|
||||
var/datum/announcement/priority/announcement
|
||||
var/obj/machinery/bot/Bot
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
var/turf/waypoint //Holds the turf of the currently selected waypoint.
|
||||
var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking.
|
||||
|
||||
@@ -513,7 +514,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["trackbot"])
|
||||
var/obj/machinery/bot/target = locate(href_list["trackbot"]) in aibots
|
||||
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in simple_animal_list
|
||||
if(target)
|
||||
ai_actual_track(target)
|
||||
else
|
||||
@@ -521,7 +522,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["callbot"]) //Command a bot to move to a selected location.
|
||||
Bot = locate(href_list["callbot"]) in aibots
|
||||
Bot = locate(href_list["callbot"]) in simple_animal_list
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
|
||||
waypoint_mode = 1
|
||||
@@ -529,7 +530,7 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
|
||||
if (href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in aibots
|
||||
Bot = locate(href_list["interface"]) in simple_animal_list
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -643,10 +644,10 @@ var/list/ai_verbs_default = list(
|
||||
d += "<A HREF=?src=\ref[src];botrefresh=\ref[Bot]>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for (Bot in aibots)
|
||||
for (var/mob/living/simple_animal/bot/Bot in simple_animal_list)
|
||||
if((Bot.z in ai_allowed_Zlevel) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.bot_type_name])</td>"
|
||||
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.model])</td>"
|
||||
//If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all.
|
||||
d += "<td width='20%'>[Bot.on ? "[Bot.mode ? "<span class='average'>[ Bot.mode_name[Bot.mode] ]</span>": "<span class='good'>Idle</span>"]" : "<span class='bad'>Inactive</span>"]</td>"
|
||||
d += "<td width='30%'>[bot_area.name]</td>"
|
||||
@@ -985,6 +986,10 @@ var/list/ai_verbs_default = list(
|
||||
usr << "<span class='warning'>You are dead!</span>"
|
||||
return 1
|
||||
|
||||
if(lacks_power())
|
||||
usr << "<span class='warning'>Power systems failure!</span>"
|
||||
return 1
|
||||
|
||||
if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
|
||||
usr << "<span class='warning'>Wireless control is disabled!</span>"
|
||||
return 1
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
var/screen // Which screen our main window displays
|
||||
var/subscreen // Which specific function of the main screen is being displayed
|
||||
|
||||
var/obj/item/device/pda/ai/pai/pda = null
|
||||
var/obj/item/device/pda/pai/pda = null
|
||||
|
||||
var/secHUD = 0 // Toggles whether the Security HUD is active or not
|
||||
var/medHUD = 0 // Toggles whether the Medical HUD is active or not
|
||||
@@ -110,6 +110,8 @@
|
||||
pda.name = pda.owner + " (" + pda.ownjob + ")"
|
||||
var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger)
|
||||
M.toff = 1
|
||||
var/datum/data/pda/app/chatroom/C = pda.find_program(/datum/data/pda/app/chatroom)
|
||||
C.toff = 1
|
||||
..()
|
||||
|
||||
/mob/living/silicon/pai/Login()
|
||||
|
||||
@@ -222,6 +222,123 @@
|
||||
M.create_message(P, target, 1)
|
||||
return 1
|
||||
|
||||
/datum/pai_software/chatroom
|
||||
name = "Digital Chatroom"
|
||||
ram_cost = 5
|
||||
id = "chatroom"
|
||||
toggle = 0
|
||||
|
||||
on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1)
|
||||
var/data[0]
|
||||
|
||||
if(!user.pda)
|
||||
return
|
||||
var/datum/data/pda/app/chatroom/M = user.pda.find_program(/datum/data/pda/app/chatroom)
|
||||
if(!M)
|
||||
return
|
||||
|
||||
data["receiver_off"] = M.toff
|
||||
data["ringer_off"] = M.notify_silent
|
||||
|
||||
var/list/rooms[0]
|
||||
for(var/datum/chatroom/c in chatrooms)
|
||||
if((M in c.users) || (M in c.invites) || c.is_public)
|
||||
rooms += list(list(name = "[c]", ref = "\ref[c]"))
|
||||
data["rooms"] = rooms
|
||||
|
||||
if(M.disconnected || !M.messaging_available(1))
|
||||
data["disconnected"] = 1
|
||||
else if(M.current_room)
|
||||
data["current_room"] = "\ref[M.current_room]"
|
||||
data["current_room_name"] = M.current_room.name
|
||||
data["current_room_topic"] = M.current_room.topic
|
||||
data["messages"] = M.current_room.logs
|
||||
var/list/users[0]
|
||||
for(var/U in M.current_room.users)
|
||||
var/datum/data/pda/app/chatroom/ch = U
|
||||
users += "<span class='good'>[ch.pda.owner]</span>"
|
||||
for(var/U in (M.current_room.invites - M.current_room.users))
|
||||
var/datum/data/pda/app/chatroom/ch = U
|
||||
users += "<span class='average'>[ch.pda.owner]</span>"
|
||||
data["users"] = users
|
||||
|
||||
ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open)
|
||||
if(!ui)
|
||||
// Don't copy-paste this unless you're making a pAI software module!
|
||||
ui = new(user, user, id, "pai_chatroom.tmpl", "Digital Chatroom", 450, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
Topic(href, href_list)
|
||||
var/mob/living/silicon/pai/P = usr
|
||||
if(!istype(P))
|
||||
return
|
||||
|
||||
if(!isnull(P.pda) && P.pda.can_use())
|
||||
var/datum/data/pda/app/chatroom/M = P.pda.find_program(/datum/data/pda/app/chatroom)
|
||||
if(!M)
|
||||
return
|
||||
|
||||
if(href_list["toggler"])
|
||||
M.toff = href_list["toggler"] != "1"
|
||||
return 1
|
||||
else if(href_list["ringer"])
|
||||
M.notify_silent = href_list["ringer"] != "1"
|
||||
return 1
|
||||
else if(href_list["topic"])
|
||||
if(!M.current_room)
|
||||
return 1
|
||||
|
||||
var/t = input("Enter new topic:", M.current_room, M.current_room.topic) as text|null
|
||||
spawn()
|
||||
if(!t || !M.check_messaging_available() || !P.pda.can_use())
|
||||
return
|
||||
t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN))
|
||||
t = readd_quotes(t)
|
||||
if (!t)
|
||||
return
|
||||
|
||||
M.current_room.topic = t
|
||||
M.current_room.announce(M, "Topic has been changed to '[t]' by [P.pda.owner].")
|
||||
return 1
|
||||
else if(href_list["select"])
|
||||
var/s = href_list["select"]
|
||||
if(s == "*NONE*")
|
||||
M.current_room = null
|
||||
else
|
||||
var/datum/chatroom/CR = locate(s)
|
||||
if(istype(CR))
|
||||
if(!(M in CR.users))
|
||||
if(!CR.login(M))
|
||||
return
|
||||
M.current_room = CR
|
||||
return 1
|
||||
else if(href_list["target"])
|
||||
if(P.silence_time)
|
||||
return alert("Communications circuits remain uninitialized.")
|
||||
|
||||
var/datum/chatroom/target = locate(href_list["target"])
|
||||
if(istype(target))
|
||||
if(!(M in target.users))
|
||||
if(!target.login(M))
|
||||
return
|
||||
var/t = input("Please enter message", target) as text|null
|
||||
spawn()
|
||||
if(!t || !M.check_messaging_available())
|
||||
return
|
||||
t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN))
|
||||
t = readd_quotes(t)
|
||||
if (!t || !P.pda.can_use())
|
||||
return
|
||||
|
||||
target.post(M, t)
|
||||
return 1
|
||||
else if(href_list["reconnect"])
|
||||
spawn()
|
||||
M.messaging_available()
|
||||
return 1
|
||||
|
||||
/datum/pai_software/med_records
|
||||
name = "Medical Records"
|
||||
ram_cost = 15
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
req_access = list(access_engine, access_robotics)
|
||||
local_transmit = 1
|
||||
ventcrawler = 2
|
||||
magpulse = 1
|
||||
|
||||
// We need to keep track of a few module items so we don't need to do list operations
|
||||
// every time we need them. These get set in New() after the module is chosen.
|
||||
|
||||
@@ -374,4 +374,4 @@
|
||||
stack = stack_plastic
|
||||
|
||||
stack.amount++
|
||||
decompiler.stored_comms[type]--;
|
||||
decompiler.stored_comms[type]--
|
||||
|
||||
@@ -241,3 +241,9 @@
|
||||
if(I == module_active)
|
||||
deselect_module(get_selected_module())
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/proc/update_module_icon()
|
||||
if(!module)
|
||||
hands.icon_state = "nomod"
|
||||
else
|
||||
hands.icon_state = lowertext(module.module_type)
|
||||
@@ -261,10 +261,8 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/update_items()
|
||||
if (src.client)
|
||||
src.client.screen -= src.contents
|
||||
for(var/obj/I in src.contents)
|
||||
if(I && !(istype(I,/obj/item/weapon/stock_parts/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi)))
|
||||
src.client.screen += I
|
||||
for(var/obj/I in get_all_slots())
|
||||
client.screen |= I
|
||||
if(src.module_state_1)
|
||||
src.module_state_1:screen_loc = ui_inv1
|
||||
if(src.module_state_2)
|
||||
|
||||
@@ -353,13 +353,11 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
if("Peacekeeper")
|
||||
module = new /obj/item/weapon/robot_module/peacekeeper(src)
|
||||
icon_state = "droidpeace"
|
||||
module.channels = list()
|
||||
icon_state = "droidpeace"
|
||||
|
||||
if("Hunter")
|
||||
module = new /obj/item/weapon/robot_module/alien/hunter(src)
|
||||
hands.icon_state = "standard"
|
||||
icon = "icons/mob/alien.dmi"
|
||||
icon_state = "xenoborg-state-a"
|
||||
modtype = "Xeno-Hu"
|
||||
@@ -375,7 +373,7 @@ var/list/robot_verbs_default = list(
|
||||
if (custom_sprite == 1)
|
||||
module_sprites["Custom"] = "[src.ckey]-[modtype]"
|
||||
|
||||
hands.icon_state = lowertext(modtype)
|
||||
hands.icon_state = lowertext(module.module_type)
|
||||
feedback_inc("cyborg_[lowertext(modtype)]",1)
|
||||
rename_character(real_name, get_default_name())
|
||||
|
||||
@@ -824,6 +822,9 @@ var/list/robot_verbs_default = list(
|
||||
if(src.module && istype(src.module, /obj/item/weapon/robot_module/medical))
|
||||
for(var/obj/item/weapon/borg_defib/F in src.module.modules)
|
||||
F.safety = 0
|
||||
if(module)
|
||||
module.module_type = "Malf" // For the cool factor
|
||||
update_module_icon()
|
||||
update_icons()
|
||||
return
|
||||
|
||||
@@ -1276,6 +1277,9 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
if(icontype)
|
||||
icon_state = module_sprites[icontype]
|
||||
if(icontype == "Bro")
|
||||
module.module_type = "Brobot"
|
||||
update_module_icon()
|
||||
lockcharge = null
|
||||
else
|
||||
src << "Something is badly wrong with the sprite selection. Harass a coder."
|
||||
@@ -1325,6 +1329,10 @@ var/list/robot_verbs_default = list(
|
||||
if (suiciding)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/robot/regenerate_icons()
|
||||
..()
|
||||
update_module_icon()
|
||||
|
||||
/mob/living/silicon/robot/deathsquad
|
||||
base_icon = "nano_bloodhound"
|
||||
icon_state = "nano_bloodhound"
|
||||
@@ -1458,4 +1466,4 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
notify_ai(2)
|
||||
notify_ai(2)
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/obj/item/borg/upgrade/jetpack = null
|
||||
var/list/subsystems = list()
|
||||
|
||||
var/module_type = "NoMod" // For icon usage
|
||||
|
||||
var/list/stacktypes
|
||||
var/channels = list()
|
||||
|
||||
@@ -101,7 +103,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/standard
|
||||
name = "standard robot module"
|
||||
|
||||
module_type = "Standard"
|
||||
|
||||
/obj/item/weapon/robot_module/standard/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -116,6 +118,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/medical
|
||||
name = "medical robot module"
|
||||
module_type = "Medical"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
|
||||
stacktypes = list(
|
||||
/obj/item/stack/medical/advanced/bruise_pack = 5,
|
||||
@@ -164,15 +167,16 @@
|
||||
|
||||
/obj/item/weapon/robot_module/engineering
|
||||
name = "engineering robot module"
|
||||
module_type = "Engineer"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor)
|
||||
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/metal = 50,
|
||||
/obj/item/stack/sheet/glass = 50,
|
||||
/obj/item/stack/sheet/rglass = 50,
|
||||
/obj/item/stack/sheet/metal/cyborg = 50,
|
||||
/obj/item/stack/sheet/glass/cyborg = 50,
|
||||
/obj/item/stack/sheet/rglass/cyborg = 50,
|
||||
/obj/item/stack/cable_coil/cyborg = 50,
|
||||
/obj/item/stack/rods = 15,
|
||||
/obj/item/stack/tile/plasteel = 15
|
||||
/obj/item/stack/rods = 30,
|
||||
/obj/item/stack/tile/plasteel = 20
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/engineering/New()
|
||||
@@ -194,34 +198,16 @@
|
||||
|
||||
src.emag = new /obj/item/borg/stun(src)
|
||||
|
||||
var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
|
||||
M.amount = 50
|
||||
src.modules += M
|
||||
|
||||
var/obj/item/stack/sheet/rglass/cyborg/R = new /obj/item/stack/sheet/rglass/cyborg(src)
|
||||
R.amount = 50
|
||||
src.modules += R
|
||||
|
||||
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src)
|
||||
G.amount = 50
|
||||
src.modules += G
|
||||
|
||||
var/obj/item/stack/cable_coil/cyborg/W = new /obj/item/stack/cable_coil/cyborg(src)
|
||||
W.amount = 50
|
||||
src.modules += W
|
||||
|
||||
var/obj/item/stack/rods/Q = new /obj/item/stack/rods(src)
|
||||
Q.amount = 15
|
||||
src.modules += Q
|
||||
|
||||
var/obj/item/stack/tile/plasteel/F = new /obj/item/stack/tile/plasteel(src) //floor tiles not regular plasteel, calm down
|
||||
F.amount = 15
|
||||
src.modules += F
|
||||
for(var/G in stacktypes) //Attempt to unify Engi-Borg material stacks into fewer lines. See Line 492 for example. Variables changed out of paranoia.
|
||||
var/obj/item/stack/sheet/M = new G(src)
|
||||
M.amount = stacktypes[G]
|
||||
src.modules += M
|
||||
|
||||
fix_modules()
|
||||
|
||||
/obj/item/weapon/robot_module/security
|
||||
name = "security robot module"
|
||||
module_type = "Security"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
|
||||
|
||||
/obj/item/weapon/robot_module/security/New()
|
||||
@@ -237,6 +223,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/janitor
|
||||
name = "janitorial robot module"
|
||||
module_type = "Janitor"
|
||||
|
||||
/obj/item/weapon/robot_module/janitor/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -254,6 +241,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/butler
|
||||
name = "service robot module"
|
||||
module_type = "Service"
|
||||
|
||||
/obj/item/weapon/robot_module/butler/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -324,6 +312,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/miner
|
||||
name = "miner robot module"
|
||||
module_type = "Miner"
|
||||
|
||||
/obj/item/weapon/robot_module/miner/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -341,6 +330,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/deathsquad
|
||||
name = "NT advanced combat module"
|
||||
module_type = "Malf"
|
||||
|
||||
/obj/item/weapon/robot_module/deathsquad/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -355,6 +345,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate
|
||||
name = "syndicate assault robot module"
|
||||
module_type = "Malf" // cuz it looks cool
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -371,6 +362,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/syndicate_medical
|
||||
name = "syndicate medical robot module"
|
||||
module_type = "Malf"
|
||||
stacktypes = list(
|
||||
/obj/item/stack/medical/advanced/bruise_pack = 25,
|
||||
/obj/item/stack/medical/advanced/ointment = 25,
|
||||
@@ -409,6 +401,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/combat
|
||||
name = "combat robot module"
|
||||
module_type = "Malf"
|
||||
|
||||
/obj/item/weapon/robot_module/combat/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -425,6 +418,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/peacekeeper
|
||||
name = "peacekeeper robot module"
|
||||
module_type = "Malf"
|
||||
|
||||
/obj/item/weapon/robot_module/peacekeeper/New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
@@ -440,6 +434,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/alien/hunter
|
||||
name = "alien hunter module"
|
||||
module_type = "Standard"
|
||||
|
||||
/obj/item/weapon/robot_module/alien/hunter/New()
|
||||
src.modules += new /obj/item/weapon/melee/energy/alien/claws(src)
|
||||
@@ -463,15 +458,15 @@
|
||||
|
||||
/obj/item/weapon/robot_module/drone
|
||||
name = "drone module"
|
||||
module_type = "Engineer"
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/wood = 1,
|
||||
/obj/item/stack/sheet/mineral/plastic = 1,
|
||||
/obj/item/stack/sheet/rglass = 5,
|
||||
/obj/item/stack/tile/wood = 5,
|
||||
/obj/item/stack/rods = 15,
|
||||
/obj/item/stack/tile/plasteel = 15,
|
||||
/obj/item/stack/sheet/metal = 20,
|
||||
/obj/item/stack/sheet/glass = 20,
|
||||
/obj/item/stack/sheet/wood/cyborg = 10,
|
||||
/obj/item/stack/sheet/rglass/cyborg = 50,
|
||||
/obj/item/stack/tile/wood = 20,
|
||||
/obj/item/stack/rods = 30,
|
||||
/obj/item/stack/tile/plasteel = 20,
|
||||
/obj/item/stack/sheet/metal/cyborg = 50,
|
||||
/obj/item/stack/sheet/glass/cyborg = 50,
|
||||
/obj/item/stack/cable_coil/cyborg = 30
|
||||
)
|
||||
|
||||
@@ -516,4 +511,4 @@
|
||||
|
||||
var/mob/living/silicon/robot/R = src.loc
|
||||
|
||||
return (src in R.module.modules)
|
||||
return (src in R.module.modules)
|
||||
|
||||
@@ -17,14 +17,6 @@
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray
|
||||
|
||||
// Allow final solutions.
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
|
||||
@@ -37,145 +29,143 @@
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bee/Life()
|
||||
..()
|
||||
/mob/living/simple_animal/bee/process_ai()
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 100 // Bees will always try to sting.
|
||||
if(M in view(src,1)) // Can I see my target?
|
||||
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit) // Are you wearing clothes?
|
||||
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
|
||||
if(worn_helmet)
|
||||
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
|
||||
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
|
||||
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
|
||||
M << "\red You have been stung!"
|
||||
|
||||
if(stat == CONSCIOUS)
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 100 // Bees will always try to sting.
|
||||
if(M in view(src,1)) // Can I see my target?
|
||||
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit) // Are you wearing clothes?
|
||||
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
|
||||
if(worn_helmet)
|
||||
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
|
||||
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
|
||||
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
|
||||
M << "\red You have been stung!"
|
||||
M.flash_pain()
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
M.flash_pain()
|
||||
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
for(var/obj/effect/check_effect in src.loc)
|
||||
if(check_effect.type in calmers)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_living = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
|
||||
for(var/mob/living/carbon/G in view(src,7))
|
||||
target_mob = G
|
||||
break
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
if(target_turf)
|
||||
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
if (prob(0.1))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
for(var/obj/effect/check_effect in src.loc)
|
||||
if(check_effect.type in calmers)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_living = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
|
||||
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
|
||||
for(var/mob/living/carbon/G in view(src,7))
|
||||
target_mob = G
|
||||
break
|
||||
|
||||
if(target_turf)
|
||||
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
if (prob(0.1))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
|
||||
/mob/living/simple_animal/bee/handle_state_icons()
|
||||
if(!parent && prob(10))
|
||||
strength -= 1
|
||||
if(strength <= 0)
|
||||
@@ -187,3 +177,5 @@
|
||||
/*icon_living = "[strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "unknown"*/
|
||||
|
||||
..()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
||||
//Cleanbot
|
||||
/mob/living/simple_animal/bot/cleanbot
|
||||
name = "\improper Cleanbot"
|
||||
desc = "A little cleaning robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "cleanbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
radio_channel = "Service" //Service
|
||||
bot_filter = RADIO_CLEANBOT
|
||||
bot_type = CLEAN_BOT
|
||||
model = "Cleanbot"
|
||||
bot_purpose = "seek out messes and clean them"
|
||||
bot_core_type = /obj/machinery/bot_core/cleanbot
|
||||
window_id = "autoclean"
|
||||
window_name = "Automatic Station Cleaner v1.1"
|
||||
pass_flags = PASSMOB
|
||||
|
||||
var/blood = 1
|
||||
var/list/target_types = list()
|
||||
var/obj/effect/decal/cleanable/target
|
||||
var/max_targets = 50 //Maximum number of targets a cleanbot can ignore.
|
||||
var/oldloc = null
|
||||
var/closest_dist
|
||||
var/closest_loc
|
||||
var/failed_steps
|
||||
var/next_dest
|
||||
var/next_dest_loc
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/New()
|
||||
..()
|
||||
get_targets()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
var/datum/job/janitor/J = new/datum/job/janitor
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_on()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/turn_off()
|
||||
..()
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/bot_reset()
|
||||
..()
|
||||
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
|
||||
target = null
|
||||
oldloc = null
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/set_custom_texts()
|
||||
text_hack = "You corrupt [name]'s cleaning software."
|
||||
text_dehack = "[name]'s software has been reset!"
|
||||
text_dehack_fail = "[name] does not seem to respond to your repair code!"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] \the [src] behaviour controls.</span>"
|
||||
else
|
||||
if(emagged)
|
||||
user << "<span class='warning'>ERROR</span>"
|
||||
if(open)
|
||||
user << "<span class='warning'>Please close the access panel before locking it.</span>"
|
||||
else
|
||||
user << "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/process_scan(obj/effect/decal/cleanable/D)
|
||||
for(var/T in target_types)
|
||||
if(istype(D, T))
|
||||
return D
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(mode == BOT_CLEANING)
|
||||
return
|
||||
|
||||
if(emagged == 2) //Emag functions
|
||||
if(istype(loc,/turf/simulated))
|
||||
if(prob(10)) //Wets floors randomly
|
||||
var/turf/simulated/T = loc
|
||||
T.MakeSlippery()
|
||||
|
||||
if(prob(5)) //Spawns foam!
|
||||
visible_message("<span class='danger'>[src] whirs and bubbles violently, before releasing a plume of froth!</span>")
|
||||
new /obj/effect/effect/foam(loc)
|
||||
|
||||
else if(prob(5))
|
||||
audible_message("[src] makes an excited beeping booping sound!")
|
||||
|
||||
if(!target) //Search for cleanables it can see.
|
||||
target = scan(/obj/effect/decal/cleanable/)
|
||||
|
||||
if(!target && auto_patrol) //Search for cleanables it can see.
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_patrol()
|
||||
|
||||
if(target)
|
||||
if(!path || path.len == 0) //No path, need a new one
|
||||
//Try to produce a path to the target, and ignore airlocks to which it has access.
|
||||
path = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card)
|
||||
if(!bot_move(target))
|
||||
add_to_ignore(target)
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
mode = BOT_MOVING
|
||||
else if(!bot_move(target))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
|
||||
if(target && loc == target.loc)
|
||||
clean(target)
|
||||
path = list()
|
||||
target = null
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/get_targets()
|
||||
target_types = new/list()
|
||||
|
||||
target_types += /obj/effect/decal/cleanable/blood/oil
|
||||
target_types += /obj/effect/decal/cleanable/vomit
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/robot
|
||||
target_types += /obj/effect/decal/cleanable/crayon
|
||||
target_types += /obj/effect/decal/cleanable/liquid_fuel
|
||||
target_types += /obj/effect/decal/cleanable/molten_item
|
||||
target_types += /obj/effect/decal/cleanable/tomato_smudge
|
||||
target_types += /obj/effect/decal/cleanable/egg_smudge
|
||||
target_types += /obj/effect/decal/cleanable/pie_smudge
|
||||
target_types += /obj/effect/decal/cleanable/flour
|
||||
target_types += /obj/effect/decal/cleanable/ash
|
||||
target_types += /obj/effect/decal/cleanable/greenglow
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
|
||||
if(blood)
|
||||
target_types += /obj/effect/decal/cleanable/blood/xeno/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/xeno
|
||||
target_types += /obj/effect/decal/cleanable/blood/
|
||||
target_types += /obj/effect/decal/cleanable/blood/gibs/
|
||||
target_types += /obj/effect/decal/cleanable/blood/tracks
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/clean(obj/effect/decal/cleanable/target)
|
||||
anchored = 1
|
||||
icon_state = "cleanbot-c"
|
||||
visible_message("<span class='notice'>[src] begins to clean up [target]</span>")
|
||||
mode = BOT_CLEANING
|
||||
spawn(50)
|
||||
if(mode == BOT_CLEANING)
|
||||
qdel(target)
|
||||
anchored = 0
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/weapon/reagent_containers/glass/bucket(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
req_one_access = list(access_janitor, access_robotics)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Cleaner v1.1 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
text("<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>"))
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += text({"<BR>Cleans Blood: []<BR>"}, text("<A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A>"))
|
||||
dat += text({"<BR>Patrol station: []<BR>"}, text("<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"))
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
switch(href_list["operation"])
|
||||
if("blood")
|
||||
blood =!blood
|
||||
get_targets()
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
|
||||
if(istype(A,/obj/effect/decal/cleanable))
|
||||
clean(A)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,480 @@
|
||||
//Bot Construction
|
||||
|
||||
//Cleanbot assembly
|
||||
/obj/item/weapon/bucket_sensor
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
name = "proxy bucket"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "bucket_proxy"
|
||||
force = 3
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Cleanbot"
|
||||
|
||||
/obj/item/weapon/bucket_sensor/attackby(obj/item/W, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(loc)
|
||||
var/mob/living/simple_animal/bot/cleanbot/A = new /mob/living/simple_animal/bot/cleanbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the bucket and sensor assembly. Beep boop!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
|
||||
//Edbot Assembly
|
||||
|
||||
/obj/item/weapon/ed209_assembly
|
||||
name = "\improper ED-209 assembly"
|
||||
desc = "Some sort of bizarre assembly."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed209_frame"
|
||||
item_state = "ed209_frame"
|
||||
var/build_step = 0
|
||||
var/created_name = "ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess
|
||||
var/lasercolor = ""
|
||||
|
||||
/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
return
|
||||
|
||||
switch(build_step)
|
||||
if(0,1)
|
||||
if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot leg to [src].</span>"
|
||||
name = "legs/frame assembly"
|
||||
if(build_step == 1)
|
||||
item_state = "ed209_leg"
|
||||
icon_state = "ed209_leg"
|
||||
else
|
||||
item_state = "ed209_legs"
|
||||
icon_state = "ed209_legs"
|
||||
|
||||
if(2)
|
||||
var/newcolor = ""
|
||||
if(istype(W, /obj/item/clothing/suit/redtag))
|
||||
newcolor = "r"
|
||||
else if(istype(W, /obj/item/clothing/suit/bluetag))
|
||||
newcolor = "b"
|
||||
if(newcolor || istype(W, /obj/item/clothing/suit/armor/vest))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
lasercolor = newcolor
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the armor to [src].</span>"
|
||||
name = "vest/legs/frame assembly"
|
||||
item_state = "[lasercolor]ed209_shell"
|
||||
icon_state = "[lasercolor]ed209_shell"
|
||||
|
||||
if(3)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0,user))
|
||||
build_step++
|
||||
name = "shielded frame assembly"
|
||||
user << "<span class='notice'>You weld the vest to [src].</span>"
|
||||
if(4)
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet/bluetaghelm))
|
||||
return
|
||||
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet/redtaghelm))
|
||||
return
|
||||
|
||||
if("")
|
||||
if(!istype(W, /obj/item/clothing/head/helmet))
|
||||
return
|
||||
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the helmet to [src].</span>"
|
||||
name = "covered and shielded frame assembly"
|
||||
item_state = "[lasercolor]ed209_hat"
|
||||
icon_state = "[lasercolor]ed209_hat"
|
||||
|
||||
if(5)
|
||||
if(isprox(W))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src].</span>"
|
||||
name = "covered, shielded and sensored frame assembly"
|
||||
item_state = "[lasercolor]ed209_prox"
|
||||
icon_state = "[lasercolor]ed209_prox"
|
||||
|
||||
if(6)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if(coil.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one length of cable to wire the ED-209!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start to wire [src]...</span>"
|
||||
if(do_after(user, 40, target = src))
|
||||
if(coil.get_amount() >= 1 && build_step == 6)
|
||||
coil.use(1)
|
||||
build_step = 7
|
||||
user << "<span class='notice'>You wire the ED-209 assembly.</span>"
|
||||
name = "wired ED-209 assembly"
|
||||
|
||||
if(7)
|
||||
var/newname = ""
|
||||
switch(lasercolor)
|
||||
if("b")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
return
|
||||
newname = "bluetag ED-209 assembly"
|
||||
if("r")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
return
|
||||
newname = "redtag ED-209 assembly"
|
||||
if("")
|
||||
if(!istype(W, /obj/item/weapon/gun/energy/advtaser))
|
||||
return
|
||||
newname = "taser ED-209 assembly"
|
||||
else
|
||||
return
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
name = newname
|
||||
build_step++
|
||||
user << "<span class='notice'>You add [W] to [src].</span>"
|
||||
item_state = "[lasercolor]ed209_taser"
|
||||
icon_state = "[lasercolor]ed209_taser"
|
||||
qdel(W)
|
||||
|
||||
if(8)
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
user << "<span class='notice'>You start attaching the gun to the frame...</span>"
|
||||
if(do_after(user, 40, target = src))
|
||||
build_step++
|
||||
name = "armed [name]"
|
||||
user << "<span class='notice'>Taser gun attached.</span>"
|
||||
|
||||
if(9)
|
||||
if(istype(W, /obj/item/weapon/stock_parts/cell))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the ED-209.</span>"
|
||||
var/turf/T = get_turf(src)
|
||||
new /mob/living/simple_animal/bot/ed209(T,created_name,lasercolor)
|
||||
qdel(W)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
//Floorbot assemblies
|
||||
/obj/item/weapon/toolbox_tiles
|
||||
desc = "It's a toolbox with tiles sticking out the top"
|
||||
name = "tiles and toolbox"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles"
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor
|
||||
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
|
||||
name = "tiles, toolbox and sensor arrangement"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles_sensor"
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
..()
|
||||
return
|
||||
if(contents.len >= 1)
|
||||
user << "<span class='warning'>They won't fit in, as there is already stuff inside.</span>"
|
||||
return
|
||||
if(T.use(10))
|
||||
if(user.s_active)
|
||||
user.s_active.close(user)
|
||||
var/obj/item/weapon/toolbox_tiles/B = new /obj/item/weapon/toolbox_tiles
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need 10 floor tiles to start building a floorbot.</span>"
|
||||
return
|
||||
|
||||
/obj/item/weapon/toolbox_tiles/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(isprox(W))
|
||||
qdel(W)
|
||||
var/obj/item/weapon/toolbox_tiles_sensor/B = new /obj/item/weapon/toolbox_tiles_sensor()
|
||||
B.created_name = created_name
|
||||
user.put_in_hands(B)
|
||||
user << "<span class='notice'>You add the sensor to the toolbox and tiles.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
/obj/item/weapon/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(user.loc)
|
||||
var/mob/living/simple_animal/bot/floorbot/A = new /mob/living/simple_animal/bot/floorbot(T)
|
||||
A.name = created_name
|
||||
user << "<span class='notice'>You add the robot arm to the odd looking toolbox assembly. Boop beep!</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
//Medbot Assembly
|
||||
/obj/item/weapon/firstaid_arm_assembly
|
||||
name = "incomplete medibot assembly."
|
||||
desc = "A first aid kit with a robot arm permanently grafted to it."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "firstaid_arm"
|
||||
var/build_step = 0
|
||||
var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess
|
||||
var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
|
||||
w_class = 3
|
||||
var/treatment_brute = "salglu_solution"
|
||||
var/treatment_oxy = "salbutamol"
|
||||
var/treatment_fire = "salglu_solution"
|
||||
var/treatment_tox = "charcoal"
|
||||
var/treatment_virus = "spaceacillin"
|
||||
req_one_access = list(access_medical, access_robotics)
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(skin)
|
||||
overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
|
||||
|
||||
/obj/item/weapon/storage/firstaid/attackby(obj/item/robot_parts/S, mob/user, params)
|
||||
|
||||
if((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
|
||||
..()
|
||||
return
|
||||
|
||||
//Making a medibot!
|
||||
if(contents.len >= 1)
|
||||
user << "<span class='warning'>You need to empty [src] out first!</span>"
|
||||
return
|
||||
|
||||
var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly
|
||||
if(istype(src,/obj/item/weapon/storage/firstaid/fire))
|
||||
A.skin = "ointment"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/toxin))
|
||||
A.skin = "tox"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/o2))
|
||||
A.skin = "o2"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/brute))
|
||||
A.skin = "brute"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/adv))
|
||||
A.skin = "adv"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/tactical))
|
||||
A.skin = "bezerk"
|
||||
else if(istype(src,/obj/item/weapon/storage/firstaid/aquatic_kit))
|
||||
A.skin = "fish"
|
||||
|
||||
A.req_one_access = req_one_access
|
||||
A.treatment_oxy = treatment_oxy
|
||||
A.treatment_brute = treatment_brute
|
||||
A.treatment_fire = treatment_fire
|
||||
A.treatment_tox = treatment_tox
|
||||
A.treatment_virus = treatment_virus
|
||||
|
||||
qdel(S)
|
||||
user.put_in_hands(A)
|
||||
user << "<span class='notice'>You add the robot arm to the first aid kit.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
else
|
||||
switch(build_step)
|
||||
if(0)
|
||||
if(istype(W, /obj/item/device/healthanalyzer))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the health sensor to [src].</span>"
|
||||
name = "First aid/robot arm/health analyzer assembly"
|
||||
overlays += image('icons/obj/aibots.dmi', "na_scanner")
|
||||
|
||||
if(1)
|
||||
if(isprox(W))
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
qdel(W)
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the Medibot. Beep boop!</span>"
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T)
|
||||
S.skin = skin
|
||||
S.name = created_name
|
||||
S.bot_core.req_one_access = req_one_access
|
||||
S.treatment_oxy = treatment_oxy
|
||||
S.treatment_brute = treatment_brute
|
||||
S.treatment_fire = treatment_fire
|
||||
S.treatment_tox = treatment_tox
|
||||
S.treatment_virus = treatment_virus
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
//Secbot Assembly
|
||||
/obj/item/weapon/secbot_assembly
|
||||
name = "incomplete securitron assembly"
|
||||
desc = "Some sort of bizarre assembly made from a proximity sensor, helmet, and signaler."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "helmet_signaler"
|
||||
item_state = "helmet"
|
||||
var/build_step = 0
|
||||
var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
|
||||
|
||||
/obj/item/clothing/head/helmet/attackby(obj/item/device/assembly/signaler/S, mob/user, params)
|
||||
..()
|
||||
if(!issignaler(S))
|
||||
..()
|
||||
return
|
||||
|
||||
if(!S.secured)
|
||||
qdel(S)
|
||||
var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly
|
||||
user.put_in_hands(A)
|
||||
user << "<span class='notice'>You add the signaler to the helmet.</span>"
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
if(!build_step)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step++
|
||||
overlays += "hs_hole"
|
||||
user << "<span class='notice'>You weld a hole in [src]!</span>"
|
||||
else if(build_step == 1)
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step--
|
||||
overlays -= "hs_hole"
|
||||
user << "<span class='notice'>You weld the hole in [src] shut!</span>"
|
||||
|
||||
else if(isprox(I) && (build_step == 1))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the prox sensor to [src]!</span>"
|
||||
overlays += "hs_eye"
|
||||
name = "helmet/signaler/prox sensor assembly"
|
||||
qdel(I)
|
||||
|
||||
else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the robot arm to [src]!</span>"
|
||||
name = "helmet/signaler/prox sensor/robot arm assembly"
|
||||
overlays += "hs_arm"
|
||||
qdel(I)
|
||||
|
||||
else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
build_step++
|
||||
user << "<span class='notice'>You complete the Securitron! Beep boop.</span>"
|
||||
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot
|
||||
S.forceMove(get_turf(src))
|
||||
S.name = created_name
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(I, /obj/item/weapon/pen))
|
||||
var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
|
||||
if(!t)
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
created_name = t
|
||||
|
||||
else if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(!build_step)
|
||||
new /obj/item/device/assembly/signaler(get_turf(src))
|
||||
new /obj/item/clothing/head/helmet(get_turf(src))
|
||||
user << "<span class='notice'>You disconnect the signaler from the helmet.</span>"
|
||||
qdel(src)
|
||||
|
||||
else if(build_step == 2)
|
||||
overlays -= "hs_eye"
|
||||
new /obj/item/device/assembly/prox_sensor(get_turf(src))
|
||||
user << "<span class='notice'>You detach the proximity sensor from [src].</span>"
|
||||
build_step--
|
||||
|
||||
else if(build_step == 3)
|
||||
overlays -= "hs_arm"
|
||||
new /obj/item/robot_parts/l_arm(get_turf(src))
|
||||
user << "<span class='notice'>You remove the robot arm from [src].</span>"
|
||||
build_step--
|
||||
@@ -0,0 +1,569 @@
|
||||
/mob/living/simple_animal/bot/ed209
|
||||
name = "\improper ED-209 Security Robot"
|
||||
desc = "A security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "ed2090"
|
||||
density = 1
|
||||
anchored = 0
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
|
||||
environment_smash = 2 //Walls can't stop THE LAW
|
||||
|
||||
radio_channel = "Security"
|
||||
bot_type = SEC_BOT
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "ED-209"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core = /obj/machinery/bot_core/secbot
|
||||
window_id = "autoed209"
|
||||
window_name = "Automatic Security Unit v2.6"
|
||||
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 3 //.3 seconds between shots
|
||||
var/lasercolor = ""
|
||||
var/disabled = 0//A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
|
||||
|
||||
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds?
|
||||
var/idcheck = 1 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
var/arrest_type = 0 //If true, don't handcuff
|
||||
var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type
|
||||
var/shoot_sound = 'sound/weapons/Taser.ogg'
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/New(loc,created_name,created_lasercolor)
|
||||
..()
|
||||
if(created_name)
|
||||
name = created_name
|
||||
if(created_lasercolor)
|
||||
lasercolor = created_lasercolor
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon() //giving it the right projectile and firing sound.
|
||||
spawn(3)
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
if(lasercolor)
|
||||
shot_delay = 6//Longer shot delay because JESUS CHRIST
|
||||
check_records = 0//Don't actively target people set to arrest
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
bot_core.req_access = list(access_maint_tunnels, access_theatre)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
if((lasercolor == "r") && (name == "\improper ED-209 Security Robot"))
|
||||
name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
|
||||
|
||||
//SECHUD
|
||||
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
permanent_huds |= secsensor
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/turn_on()
|
||||
. = ..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/turn_off()
|
||||
..()
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/set_custom_texts()
|
||||
text_hack = "You disable [name]'s combat inhibitor."
|
||||
text_dehack = "You restore [name]'s combat inhibitor."
|
||||
text_dehack_fail = "[name] ignores your attempts to restrict him!"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Security Unit v2.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
if(!lasercolor)
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol[]"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/Topic(href, href_list)
|
||||
if(lasercolor && (istype(usr,/mob/living/carbon/human)))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it
|
||||
return
|
||||
else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag)))
|
||||
return
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/retaliate(mob/living/carbon/human/H)
|
||||
threatlevel = H.assess_threat(src)
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = H
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H)
|
||||
if(H.a_intent == "harm")
|
||||
retaliate(H)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/screwdriver) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina.
|
||||
retaliate(user)
|
||||
if(lasercolor)//To make up for the fact that lasertag bots don't hunt
|
||||
shootAt(user)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='warning'>You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(disabled)
|
||||
return
|
||||
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/C in view(7, src)) //Let's find us a target
|
||||
var/threatlevel = 0
|
||||
if((C.stat) || (C.lying))
|
||||
continue
|
||||
threatlevel = C.assess_threat(src, lasercolor)
|
||||
//speak(C.real_name + text(": threat: []", threatlevel))
|
||||
if(threatlevel < 4)
|
||||
continue
|
||||
|
||||
var/dst = get_dist(src, C)
|
||||
if(dst <= 1 || dst > 7)
|
||||
continue
|
||||
|
||||
targets += C
|
||||
if(targets.len>0)
|
||||
var/mob/living/carbon/t = pick(targets)
|
||||
if((t.stat!=2) && (t.lying != 1) && (!t.handcuffed)) //we don't shoot people who are dead, cuffed or lying down.
|
||||
shootAt(t)
|
||||
switch(mode)
|
||||
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src,0)
|
||||
if(!lasercolor) //lasertag bots don't want to arrest anyone
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(!mode && auto_patrol) // still idle, and set to patrol
|
||||
mode = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
// if can't reach perp for long enough, go idle
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if(!Adjacent(target) || !isturf(target.loc) || target.weakened < 2)
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
|
||||
back_to_hunt()
|
||||
return
|
||||
else
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 0
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
bot_patrol()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
|
||||
if(disabled)
|
||||
return
|
||||
anchored = 0
|
||||
threatlevel = 0
|
||||
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
if((C.stat) || (C.handcuffed))
|
||||
continue
|
||||
|
||||
if((C.name == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src, lasercolor)
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/EDPlaceholder.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/explode()
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/ed209_assembly/Sa = new /obj/item/weapon/ed209_assembly(Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.overlays += image('icons/obj/aibots.dmi', "hs_hole")
|
||||
Sa.created_name = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(!lasercolor)
|
||||
var/obj/item/weapon/gun/energy/advtaser/G = new /obj/item/weapon/gun/energy/advtaser(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "b")
|
||||
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
else if(lasercolor == "r")
|
||||
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
|
||||
G.power_supply.charge = 0
|
||||
G.update_icon()
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_leg(Tsec)
|
||||
if(prob(25))
|
||||
new /obj/item/robot_parts/r_leg(Tsec)
|
||||
if(prob(25))//50% chance for a helmet OR vest
|
||||
if(prob(50))
|
||||
new /obj/item/clothing/head/helmet(Tsec)
|
||||
else
|
||||
if(!lasercolor)
|
||||
new /obj/item/clothing/suit/armor/vest(Tsec)
|
||||
if(lasercolor == "b")
|
||||
new /obj/item/clothing/suit/bluetag(Tsec)
|
||||
if(lasercolor == "r")
|
||||
new /obj/item/clothing/suit/redtag(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/set_weapon() //used to update the projectile type and firing sound
|
||||
shoot_sound = 'sound/weapons/laser.ogg'
|
||||
if(emagged == 2)
|
||||
if(lasercolor)
|
||||
projectile = /obj/item/projectile/lasertag
|
||||
else
|
||||
projectile = /obj/item/projectile/beam
|
||||
else
|
||||
if(!lasercolor)
|
||||
shoot_sound = 'sound/weapons/Taser.ogg'
|
||||
projectile = /obj/item/projectile/energy/electrode
|
||||
else if(lasercolor == "b")
|
||||
projectile = /obj/item/projectile/lasertag/blue
|
||||
else if(lasercolor == "r")
|
||||
projectile = /obj/item/projectile/lasertag/red
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/shootAt(mob/target)
|
||||
if(lastfired && world.time - lastfired < shot_delay)
|
||||
return
|
||||
lastfired = world.time
|
||||
var/turf/T = loc
|
||||
var/atom/U = (istype(target, /atom/movable) ? target.loc : target)
|
||||
if((!( U ) || !( T )))
|
||||
return
|
||||
while(!(istype(U, /turf)))
|
||||
U = U.loc
|
||||
if(!(istype(T, /turf)))
|
||||
return
|
||||
|
||||
if(!projectile)
|
||||
return
|
||||
|
||||
if(!(istype(U, /turf)))
|
||||
return
|
||||
var/obj/item/projectile/A = new projectile(loc)
|
||||
playsound(loc, shoot_sound, 50, 1)
|
||||
A.current = U
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
spawn(0)
|
||||
A.process()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/attack_alien(mob/living/carbon/alien/user)
|
||||
..()
|
||||
if(!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/emp_act(severity)
|
||||
|
||||
if(severity==2 && prob(70))
|
||||
..(severity-1)
|
||||
else
|
||||
var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( loc )
|
||||
pulse2.icon = 'icons/effects/effects.dmi'
|
||||
pulse2.icon_state = "empdisable"
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = 1
|
||||
pulse2.dir = pick(cardinal)
|
||||
spawn(10)
|
||||
qdel(pulse2)
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for(var/mob/living/carbon/C in view(12,src))
|
||||
if(C.stat==2)
|
||||
continue
|
||||
targets += C
|
||||
if(targets.len)
|
||||
if(prob(50))
|
||||
var/mob/toshoot = pick(targets)
|
||||
if(toshoot)
|
||||
targets-=toshoot
|
||||
if(prob(50) && emagged < 2)
|
||||
emagged = 2
|
||||
set_weapon()
|
||||
shootAt(toshoot)
|
||||
emagged = 0
|
||||
set_weapon()
|
||||
else
|
||||
shootAt(toshoot)
|
||||
else if(prob(50))
|
||||
if(targets.len)
|
||||
var/mob/toarrest = pick(targets)
|
||||
if(toarrest)
|
||||
target = toarrest
|
||||
mode = BOT_HUNT
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(!disabled)
|
||||
var/lasertag_check = 0
|
||||
if((lasercolor == "b"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/red))
|
||||
lasertag_check++
|
||||
else if((lasercolor == "r"))
|
||||
if(istype(Proj, /obj/item/projectile/lasertag/blue))
|
||||
lasertag_check++
|
||||
if(lasertag_check)
|
||||
icon_state = "[lasercolor]ed2090"
|
||||
disabled = 1
|
||||
target = null
|
||||
spawn(100)
|
||||
disabled = 0
|
||||
icon_state = "[lasercolor]ed2091"
|
||||
return 1
|
||||
else
|
||||
..(Proj)
|
||||
else
|
||||
..(Proj)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bluetag
|
||||
lasercolor = "b"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/redtag
|
||||
lasercolor = "r"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.stunned || arrest_type)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/RangedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
icon_state = "[lasercolor]ed209-c"
|
||||
spawn(2)
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
var/threat = 5
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
C.Weaken(5)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(src)
|
||||
else
|
||||
C.Weaken(5)
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
add_logs(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has stunned you!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
|
||||
spawn(60)
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_inv_handcuffed(1)
|
||||
back_to_idle()
|
||||
@@ -0,0 +1,119 @@
|
||||
/mob/living/simple_animal/bot/emote(var/act, var/m_type=1, var/message = null)
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
|
||||
var/on_CD = 0
|
||||
switch(act)
|
||||
//Cooldown-inducing emotes
|
||||
if("scream", "screams")
|
||||
on_CD = handle_emote_CD(50) //longer cooldown
|
||||
if("ping","buzz","beep","yes","no") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
//Everything else, including typos of the above emotes
|
||||
else
|
||||
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
|
||||
|
||||
if(on_CD == 1) // Check if we need to suppress the emote attempt.
|
||||
return // Suppress emote, you're still cooling off.
|
||||
//--FalseIncarnate
|
||||
|
||||
switch(act)
|
||||
if("ping")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> pings at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> pings."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("buzz")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> buzzes at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> buzzes."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("beep")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> beeps at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> beeps."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("yes")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> emits an affirmative blip at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> emits an affirmative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("no")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<B>[src]</B> emits a negative blip at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> emits a negative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("scream", "screams")
|
||||
message = "<B>[src]</B> screams!"
|
||||
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
|
||||
m_type = 2
|
||||
|
||||
..(act, m_type, message)
|
||||
@@ -0,0 +1,425 @@
|
||||
//Floorbot
|
||||
/mob/living/simple_animal/bot/floorbot
|
||||
name = "\improper Floorbot"
|
||||
desc = "A little floor repairing robot, he looks so excited!"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "floorbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
|
||||
radio_channel = "Engineering"
|
||||
bot_type = FLOOR_BOT
|
||||
bot_filter = RADIO_FLOORBOT
|
||||
model = "Floorbot"
|
||||
bot_purpose = "seek out damaged or missing floor tiles, and repair or replace them as necessary"
|
||||
bot_core = /obj/machinery/bot_core/floorbot
|
||||
window_id = "autofloor"
|
||||
window_name = "Automatic Station Floor Repairer v1.1"
|
||||
|
||||
var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details.
|
||||
var/targetdirection
|
||||
var/amount = 10
|
||||
var/replacetiles = 0
|
||||
var/eattiles = 0
|
||||
var/maketiles = 0
|
||||
var/fixfloors = 0
|
||||
var/autotile = 0
|
||||
var/nag_on_empty = 1
|
||||
var/nagged = 0 //Prevents the Floorbot nagging more than once per refill.
|
||||
var/max_targets = 50
|
||||
var/turf/target
|
||||
var/oldloc = null
|
||||
|
||||
#define HULL_BREACH 1
|
||||
#define BRIDGE_MODE 2
|
||||
#define FIX_TILE 3
|
||||
#define AUTO_TILE 4
|
||||
#define REPLACE_TILE 5
|
||||
#define TILE_EMAG 6
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/New()
|
||||
..()
|
||||
update_icon()
|
||||
var/datum/job/engineer/J = new/datum/job/engineer
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldloc = null
|
||||
ignore_list = list()
|
||||
nagged = 0
|
||||
anchored = 0
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/set_custom_texts()
|
||||
text_hack = "You corrupt [name]'s construction protocols."
|
||||
text_dehack = "You detect errors in [name] and reset his programming."
|
||||
text_dehack_fail = "[name] is not responding to reset commands!"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Floor Repairer Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Tiles left: [amount]<BR>"
|
||||
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=\ref[src];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Replace floor tiles: <A href='?src=\ref[src];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Finds tiles: <A href='?src=\ref[src];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Make pieces of metal into tiles when empty: <A href='?src=\ref[src];operation=make'>[maketiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Transmit notice when empty: <A href='?src=\ref[src];operation=emptynag'>[nag_on_empty ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Repair damaged tiles and platings: <A href='?src=\ref[src];operation=fix'>[fixfloors ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Traction Magnets: <A href='?src=\ref[src];operation=anchor'>[anchored ? "Engaged" : "Disengaged"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
var/bmode
|
||||
if(targetdirection)
|
||||
bmode = dir2text(targetdirection)
|
||||
else
|
||||
bmode = "disabled"
|
||||
dat += "Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params)
|
||||
if(istype(W, /obj/item/stack/tile/plasteel))
|
||||
var/obj/item/stack/tile/plasteel/T = W
|
||||
if(amount >= 50)
|
||||
return
|
||||
var/loaded = min(50-amount, T.amount)
|
||||
T.use(loaded)
|
||||
amount += loaded
|
||||
if(loaded > 0)
|
||||
user << "<span class='notice'>You load [loaded] tiles into the floorbot. He now contains [amount] tiles.</span>"
|
||||
nagged = 0
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='warning'>You need at least one floor tile to put into [src]!</span>"
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>[src] buzzes and beeps.</span>"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("replace")
|
||||
replacetiles = !replacetiles
|
||||
if("tiles")
|
||||
eattiles = !eattiles
|
||||
if("make")
|
||||
maketiles = !maketiles
|
||||
if("fix")
|
||||
fixfloors = !fixfloors
|
||||
if("autotile")
|
||||
autotile = !autotile
|
||||
if("emptynag")
|
||||
nag_on_empty = !nag_on_empty
|
||||
if("anchor")
|
||||
anchored = !anchored
|
||||
|
||||
if("bridgemode")
|
||||
var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable")
|
||||
switch(setdir)
|
||||
if("north")
|
||||
targetdirection = 1
|
||||
if("south")
|
||||
targetdirection = 2
|
||||
if("east")
|
||||
targetdirection = 4
|
||||
if("west")
|
||||
targetdirection = 8
|
||||
if("disable")
|
||||
targetdirection = null
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(mode == BOT_REPAIRING)
|
||||
return
|
||||
|
||||
if(amount <= 0 && !target) //Out of tiles! We must refill!
|
||||
if(eattiles) //Configured to find and consume floortiles!
|
||||
target = scan(/obj/item/stack/tile/plasteel)
|
||||
process_type = null
|
||||
|
||||
if(!target && maketiles) //We did not manage to find any floor tiles! Scan for metal stacks and make our own!
|
||||
target = scan(/obj/item/stack/sheet/metal)
|
||||
process_type = null
|
||||
return
|
||||
else
|
||||
if(nag_on_empty) //Floorbot is empty and cannot acquire more tiles, nag the engineers for more!
|
||||
nag()
|
||||
|
||||
if(prob(5))
|
||||
audible_message("[src] makes an excited booping beeping sound!")
|
||||
|
||||
//Normal scanning procedure. We have tiles loaded, are not emagged.
|
||||
if(!target && emagged < 2 && amount > 0)
|
||||
if(targetdirection != null) //The bot is in bridge mode.
|
||||
//Try to find a space tile immediately in our selected direction.
|
||||
var/turf/T = get_step(src, targetdirection)
|
||||
if(istype(T, /turf/space))
|
||||
target = T
|
||||
|
||||
else //Find a space tile farther way!
|
||||
target = scan(/turf/space)
|
||||
process_type = BRIDGE_MODE
|
||||
|
||||
if(!target)
|
||||
process_type = HULL_BREACH //Ensures the floorbot does not try to "fix" space areas or shuttle docking zones.
|
||||
target = scan(/turf/space)
|
||||
|
||||
if(!target && replacetiles) //Finds a floor without a tile and gives it one.
|
||||
process_type = REPLACE_TILE //The target must be the floor and not a tile. The floor must not already have a floortile.
|
||||
target = scan(/turf/simulated/floor)
|
||||
|
||||
if(!target && fixfloors) //Repairs damaged floors and tiles.
|
||||
process_type = FIX_TILE
|
||||
target = scan(/turf/simulated/floor)
|
||||
|
||||
if(!target && emagged == 2) //We are emagged! Time to rip up the floors!
|
||||
process_type = TILE_EMAG
|
||||
target = scan(/turf/simulated/floor)
|
||||
|
||||
|
||||
if(!target)
|
||||
|
||||
if(auto_patrol)
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_patrol()
|
||||
|
||||
if(target)
|
||||
if(path.len == 0)
|
||||
if(!istype(target, /turf/))
|
||||
var/turf/TL = get_turf(target)
|
||||
path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
|
||||
else
|
||||
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
|
||||
|
||||
if(!bot_move(target))
|
||||
add_to_ignore(target)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
else if( !bot_move(target) )
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
|
||||
if(loc == target || loc == target.loc)
|
||||
if(istype(target, /obj/item/stack/tile/plasteel))
|
||||
eattile(target)
|
||||
else if(istype(target, /obj/item/stack/sheet/metal))
|
||||
maketile(target)
|
||||
else if(istype(target, /turf/) && emagged < 2)
|
||||
repair(target)
|
||||
else if(emagged == 2 && istype(target,/turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = target
|
||||
anchored = 1
|
||||
mode = BOT_REPAIRING
|
||||
if(prob(90))
|
||||
F.break_tile_to_plating()
|
||||
else
|
||||
F.ReplaceWithLattice()
|
||||
audible_message("<span class='danger'>[src] makes an excited booping sound.</span>")
|
||||
spawn(50)
|
||||
amount ++
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us!
|
||||
if(!nagged)
|
||||
speak("Requesting refill at <b>[get_area(src)]</b>!", radio_channel)
|
||||
nagged = 1
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
|
||||
var/area/t_area = get_area(t)
|
||||
if(t_area && (t_area.name == "Space" || findtext(t_area.name, "huttle")))
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
//Floorbots, having several functions, need sort out special conditions here.
|
||||
/mob/living/simple_animal/bot/floorbot/process_scan(scan_target)
|
||||
var/result
|
||||
var/turf/simulated/floor/F
|
||||
switch(process_type)
|
||||
if(HULL_BREACH) //The most common job, patching breaches in the station's hull.
|
||||
if(is_hull_breach(scan_target)) //Ensure that the targeted space turf is actually part of the station, and not random space.
|
||||
result = scan_target
|
||||
anchored = 1 //Prevent the floorbot being blown off-course while trying to reach a hull breach.
|
||||
if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered.
|
||||
if(get_dir(src, scan_target) == targetdirection)
|
||||
result = scan_target
|
||||
anchored = 1
|
||||
if(REPLACE_TILE)
|
||||
F = scan_target
|
||||
if(istype(F, /turf/simulated/floor/plating)) //The floor must not already have a tile.
|
||||
result = F
|
||||
if(FIX_TILE) //Selects only damaged floors.
|
||||
F = scan_target
|
||||
if(istype(F) && (F.broken || F.burnt))
|
||||
result = F
|
||||
if(TILE_EMAG) //Emag mode! Rip up the floor and cause breaches to space!
|
||||
F = scan_target
|
||||
if(!istype(F, /turf/simulated/floor/plating))
|
||||
result = F
|
||||
else //If no special processing is needed, simply return the result.
|
||||
result = scan_target
|
||||
return result
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/repair(turf/target_turf)
|
||||
|
||||
if(istype(target_turf, /turf/space/))
|
||||
//Must be a hull breach or in bridge mode to continue.
|
||||
if(!is_hull_breach(target_turf) && !targetdirection)
|
||||
target = null
|
||||
return
|
||||
else if(!istype(target_turf, /turf/simulated/floor))
|
||||
return
|
||||
if(amount <= 0)
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
return
|
||||
anchored = 1
|
||||
icon_state = "floorbot-c"
|
||||
if(istype(target_turf, /turf/space/)) //If we are fixing an area not part of pure space, it is
|
||||
visible_message("<span class='notice'>[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] </span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
if(autotile) //Build the floor and include a tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
else //Build a hull plating without a floor tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plating)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
target = null
|
||||
else
|
||||
var/turf/simulated/floor/F = target_turf
|
||||
mode = BOT_REPAIRING
|
||||
visible_message("<span class='notice'>[src] begins repairing the floor.</span>")
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
F.broken = 0
|
||||
F.burnt = 0
|
||||
F.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/eattile(obj/item/stack/tile/plasteel/T)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(T))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
if(amount + T.amount > 50)
|
||||
var/i = 50 - amount
|
||||
amount += i
|
||||
T.amount -= i
|
||||
else
|
||||
amount += T.amount
|
||||
qdel(T)
|
||||
update_icon()
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/maketile(obj/item/stack/sheet/metal/M)
|
||||
if(!istype(M, /obj/item/stack/sheet/metal))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to create tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(M))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel
|
||||
T.amount = 4
|
||||
T.forceMove(M.loc)
|
||||
if(M.amount > 1)
|
||||
M.amount--
|
||||
else
|
||||
qdel(M)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/update_icon()
|
||||
if(amount > 0)
|
||||
icon_state = "floorbot[on]"
|
||||
else
|
||||
icon_state = "floorbot[on]e"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec)
|
||||
N.contents = list()
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
while(amount)//Dumps the tiles into the appropriate sized stacks
|
||||
if(amount >= 16)
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = 16
|
||||
amount -= 16
|
||||
else
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = amount
|
||||
amount = 0
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/floorbot
|
||||
req_one_access = list(access_construction, access_robotics)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A)
|
||||
if(isturf(A))
|
||||
repair(A)
|
||||
else if(istype(A,/obj/item/stack/tile/plasteel))
|
||||
eattile(A)
|
||||
else if(istype(A,/obj/item/stack/sheet/metal))
|
||||
maketile(A)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,578 @@
|
||||
//Medbot
|
||||
/mob/living/simple_animal/bot/medbot
|
||||
name = "\improper Medibot"
|
||||
desc = "A little medical robot. He looks somewhat underwhelmed."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "medibot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 20
|
||||
maxHealth = 20
|
||||
pass_flags = PASSMOB
|
||||
|
||||
radio_channel = "Medical"
|
||||
|
||||
bot_type = MED_BOT
|
||||
bot_filter = RADIO_MEDBOT
|
||||
model = "Medibot"
|
||||
bot_purpose = "seek out hurt crewmembers and ensure that they are healed"
|
||||
bot_core_type = /obj/machinery/bot_core/medbot
|
||||
window_id = "automed"
|
||||
window_name = "Automatic Medical Unit v1.1"
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
|
||||
var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits.
|
||||
var/mob/living/carbon/patient = null
|
||||
var/mob/living/carbon/oldpatient = null
|
||||
var/oldloc = null
|
||||
var/last_found = 0
|
||||
var/last_newpatient_speak = 0 //Don't spam the "HEY I'M COMING" messages
|
||||
var/injection_amount = 15 //How much reagent do we inject at a time?
|
||||
var/heal_threshold = 10 //Start healing when they have this much damage in a category
|
||||
var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents.
|
||||
var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users.
|
||||
var/declare_cooldown = 0 //Prevents spam of critical patient alerts.
|
||||
var/stationary_mode = 0 //If enabled, the Medibot will not move automatically.
|
||||
//Setting which reagents to use to treat what by default. By id.
|
||||
var/treatment_brute = "salglu_solution"
|
||||
var/treatment_oxy = "salbutamol"
|
||||
var/treatment_fire = "salglu_solution"
|
||||
var/treatment_tox = "charcoal"
|
||||
var/treatment_virus = "spaceacillin"
|
||||
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
|
||||
var/shut_up = 0 //self explanatory :)
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/tox
|
||||
skin = "tox"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/o2
|
||||
skin = "o2"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/brute
|
||||
skin = "brute"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/fire
|
||||
skin = "ointment"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/adv
|
||||
skin = "adv"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/fish
|
||||
skin = "fish"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/mysterious
|
||||
name = "\improper Mysterious Medibot"
|
||||
desc = "International Medibot of mystery."
|
||||
skin = "bezerk"
|
||||
treatment_oxy = "perfluorodecalin"
|
||||
treatment_brute = "styptic_powder"
|
||||
treatment_fire = "silver_sulfadiazine"
|
||||
treatment_tox = "charcoal"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/syndicate
|
||||
name = "Suspicious Medibot"
|
||||
desc = "You'd better have insurance!"
|
||||
skin = "bezerk"
|
||||
treatment_oxy = "perfluorodecalin"
|
||||
treatment_brute = "styptic_powder"
|
||||
treatment_fire = "silver_sulfadiazine"
|
||||
treatment_tox = "charcoal"
|
||||
bot_core_type = /obj/machinery/bot_core/medbot/syndicate
|
||||
control_freq = BOT_FREQ + 1000 // make it not show up on lists
|
||||
radio_channel = "Syndicate"
|
||||
radio_config = list("Common" = 1, "Medical" = 1, "Syndicate" = 1)
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/syndicate/New()
|
||||
..()
|
||||
Radio.syndie = 1
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/update_icon()
|
||||
if(!on)
|
||||
icon_state = "medibot0"
|
||||
return
|
||||
if(mode == BOT_HEALING)
|
||||
icon_state = "medibots[stationary_mode]"
|
||||
return
|
||||
else if(stationary_mode) //Bot has yellow light to indicate stationary mode.
|
||||
icon_state = "medibot2"
|
||||
else
|
||||
icon_state = "medibot1"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
spawn(4)
|
||||
if(skin)
|
||||
overlays += image('icons/obj/aibots.dmi', "medskin_[skin]")
|
||||
|
||||
var/datum/job/doctor/J = new/datum/job/doctor
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
medsensor.add_hud_to(src)
|
||||
permanent_huds |= medsensor
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/bot_reset()
|
||||
..()
|
||||
patient = null
|
||||
oldpatient = null
|
||||
oldloc = null
|
||||
last_found = world.time
|
||||
declare_cooldown = 0
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/soft_reset() //Allows the medibot to still actively perform its medical duties without being completely halted as a hard reset does.
|
||||
path = list()
|
||||
patient = null
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/set_custom_texts()
|
||||
text_hack = "You corrupt [name]'s reagent processor circuits."
|
||||
text_dehack = "You reset [name]'s reagent processor circuits."
|
||||
text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!"
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<TT><B>Medical Unit Controls v1.1</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Beaker: "
|
||||
if(reagent_glass)
|
||||
dat += "<A href='?src=\ref[src];eject=1'>Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]</a>"
|
||||
else
|
||||
dat += "None Loaded"
|
||||
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += "<TT>Healing Threshold: "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=-10'>--</a> "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=-5'>-</a> "
|
||||
dat += "[heal_threshold] "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=5'>+</a> "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=10'>++</a>"
|
||||
dat += "</TT><br>"
|
||||
|
||||
dat += "<TT>Injection Level: "
|
||||
dat += "<a href='?src=\ref[src];adj_inject=-5'>-</a> "
|
||||
dat += "[injection_amount] "
|
||||
dat += "<a href='?src=\ref[src];adj_inject=5'>+</a> "
|
||||
dat += "</TT><br>"
|
||||
|
||||
dat += "Reagent Source: "
|
||||
dat += "<a href='?src=\ref[src];use_beaker=1'>[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]</a><br>"
|
||||
|
||||
dat += "Treat Viral Infections: <a href='?src=\ref[src];virus=1'>[treat_virus ? "Yes" : "No"]</a><br>"
|
||||
dat += "The speaker switch is [shut_up ? "off" : "on"]. <a href='?src=\ref[src];togglevoice=[1]'>Toggle</a><br>"
|
||||
dat += "Critical Patient Alerts: <a href='?src=\ref[src];critalerts=1'>[declare_crit ? "Yes" : "No"]</a><br>"
|
||||
dat += "Patrol Station: <a href='?src=\ref[src];operation=patrol'>[auto_patrol ? "Yes" : "No"]</a><br>"
|
||||
dat += "Stationary Mode: <a href='?src=\ref[src];stationary=1'>[stationary_mode ? "Yes" : "No"]</a><br>"
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["adj_threshold"])
|
||||
var/adjust_num = text2num(href_list["adj_threshold"])
|
||||
heal_threshold += adjust_num
|
||||
if(heal_threshold < 5)
|
||||
heal_threshold = 5
|
||||
if(heal_threshold > 75)
|
||||
heal_threshold = 75
|
||||
|
||||
else if(href_list["adj_inject"])
|
||||
var/adjust_num = text2num(href_list["adj_inject"])
|
||||
injection_amount += adjust_num
|
||||
if(injection_amount < 5)
|
||||
injection_amount = 5
|
||||
if(injection_amount > 15)
|
||||
injection_amount = 15
|
||||
|
||||
else if(href_list["use_beaker"])
|
||||
use_beaker = !use_beaker
|
||||
|
||||
else if(href_list["eject"] && (!isnull(reagent_glass)))
|
||||
reagent_glass.forceMove(get_turf(src))
|
||||
reagent_glass = null
|
||||
|
||||
else if(href_list["togglevoice"])
|
||||
shut_up = !shut_up
|
||||
|
||||
else if(href_list["critalerts"])
|
||||
declare_crit = !declare_crit
|
||||
|
||||
else if(href_list["stationary"])
|
||||
stationary_mode = !stationary_mode
|
||||
path = list()
|
||||
update_icon()
|
||||
|
||||
else if(href_list["virus"])
|
||||
treat_virus = !treat_virus
|
||||
|
||||
update_controls()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/reagent_containers/glass))
|
||||
if(locked)
|
||||
user << "<span class='warning'>You cannot insert a beaker because the panel is locked!</span>"
|
||||
return
|
||||
if(!isnull(reagent_glass))
|
||||
user << "<span class='warning'>There is already a beaker loaded!</span>"
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
|
||||
W.forceMove(src)
|
||||
reagent_glass = W
|
||||
user << "<span class='notice'>You insert [W].</span>"
|
||||
show_controls(user)
|
||||
return
|
||||
|
||||
else
|
||||
var/current_health = health
|
||||
..()
|
||||
if(health < current_health) //if medbot took some damage
|
||||
step_to(src, (get_step_away(src,user)))
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
declare_crit = 0
|
||||
if(user)
|
||||
user << "<span class='notice'>You short out [src]'s reagent synthesis circuits.</span>"
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
flick("medibot_spark", src)
|
||||
if(user)
|
||||
oldpatient = user
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H)
|
||||
if(H.stat == 2)
|
||||
return
|
||||
|
||||
if((H == oldpatient) && (world.time < last_found + 200))
|
||||
return
|
||||
|
||||
if(assess_patient(H))
|
||||
last_found = world.time
|
||||
if((last_newpatient_speak + 300) < world.time) //Don't spam these messages!
|
||||
var/message = pick("Hey, [H.name]! Hold on, I'm coming.","Wait [H.name]! I want to help!","[H.name], you appear to be injured!")
|
||||
speak(message)
|
||||
last_newpatient_speak = world.time
|
||||
return H
|
||||
else
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(mode == BOT_HEALING)
|
||||
return
|
||||
|
||||
if(stunned)
|
||||
icon_state = "medibota"
|
||||
stunned--
|
||||
|
||||
oldpatient = patient
|
||||
patient = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
if(stunned <= 0)
|
||||
update_icon()
|
||||
stunned = 0
|
||||
return
|
||||
|
||||
if(frustration > 8)
|
||||
oldpatient = patient
|
||||
soft_reset()
|
||||
|
||||
if(!patient)
|
||||
if(!shut_up && prob(1))
|
||||
var/message = pick("Radar, put a mask on!","There's always a catch, and it's the best there is.","I knew it, I should've been a plastic surgeon.","What kind of medbay is this? Everyone's dropping like dead flies.","Delicious!")
|
||||
speak(message)
|
||||
var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients.
|
||||
patient = scan(/mob/living/carbon/human, oldpatient, scan_range)
|
||||
oldpatient = patient
|
||||
|
||||
if(patient && (get_dist(src,patient) <= 1)) //Patient is next to us, begin treatment!
|
||||
if(mode != BOT_HEALING)
|
||||
mode = BOT_HEALING
|
||||
update_icon()
|
||||
frustration = 0
|
||||
medicate_patient(patient)
|
||||
return
|
||||
|
||||
//Patient has moved away from us!
|
||||
else if(patient && path.len && (get_dist(patient,path[path.len]) > 2))
|
||||
path = list()
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
|
||||
else if(stationary_mode && patient) //Since we cannot move in this mode, ignore the patient and wait for another.
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
if(patient && path.len == 0 && (get_dist(src,patient) > 1))
|
||||
path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card)
|
||||
mode = BOT_MOVING
|
||||
if(!path.len) //try to get closer if you can't reach the patient directly
|
||||
path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card)
|
||||
if(!path.len) //Do not chase a patient we cannot reach.
|
||||
soft_reset()
|
||||
|
||||
if(path.len > 0 && patient)
|
||||
if(!bot_move(path[path.len]))
|
||||
oldpatient = patient
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
if(path.len > 8 && patient)
|
||||
frustration++
|
||||
|
||||
if(auto_patrol && !stationary_mode && !patient)
|
||||
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
|
||||
start_patrol()
|
||||
|
||||
if(mode == BOT_PATROL)
|
||||
bot_patrol()
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/assess_patient(mob/living/carbon/C)
|
||||
//Time to see if they need medical help!
|
||||
if(C.stat == 2)
|
||||
return 0 //welp too late for them!
|
||||
|
||||
if(C.suiciding)
|
||||
return 0 //Kevorkian school of robotic medical assistants.
|
||||
|
||||
// is secretly a silicon
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.species && H.species.reagent_tag == PROCESS_SYN)
|
||||
return 0
|
||||
|
||||
if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins)
|
||||
return 1
|
||||
|
||||
if((skin == "bezerk") && (!("syndicate" in C.faction)))
|
||||
return 0
|
||||
|
||||
if(declare_crit && C.health <= 0) //Critical condition! Call for help!
|
||||
declare(C)
|
||||
|
||||
//If they're injured, we're using a beaker, and don't have one of our WONDERCHEMS.
|
||||
if((reagent_glass) && (use_beaker) && ((C.getBruteLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getOxyLoss() >= (heal_threshold + 15))))
|
||||
for(var/datum/reagent/R in reagent_glass.reagents.reagent_list)
|
||||
if(!C.reagents.has_reagent(R.id))
|
||||
return 1
|
||||
|
||||
//They're injured enough for it!
|
||||
if((C.getBruteLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_brute)))
|
||||
return 1 //If they're already medicated don't bother!
|
||||
|
||||
if((C.getOxyLoss() >= (15 + heal_threshold)) && (!C.reagents.has_reagent(treatment_oxy)))
|
||||
return 1
|
||||
|
||||
if((C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_fire)))
|
||||
return 1
|
||||
|
||||
if((C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_tox)))
|
||||
return 1
|
||||
|
||||
if(treat_virus)
|
||||
for(var/datum/disease/D in C.viruses)
|
||||
//the medibot can't detect viruses that are undetectable to Health Analyzers or Pandemic machines.
|
||||
if(D.visibility_flags & HIDDEN_SCANNER || D.visibility_flags & HIDDEN_PANDEMIC)
|
||||
return 0
|
||||
if(D.severity == NONTHREAT) // medibot doesn't try to heal truly harmless viruses
|
||||
return 0
|
||||
if((D.stage > 1) || (D.spread_flags & AIRBORNE)) // medibot can't detect a virus in its initial stage unless it spreads airborne.
|
||||
|
||||
if(!C.reagents.has_reagent(treatment_virus))
|
||||
return 1 //STOP DISEASE FOREVER
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A)
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
patient = C
|
||||
mode = BOT_HEALING
|
||||
update_icon()
|
||||
medicate_patient(C)
|
||||
update_icon()
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view())
|
||||
..()
|
||||
if(!is_blind(src))
|
||||
chemscan(src, A)
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/medicate_patient(mob/living/carbon/C)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
if(!istype(C))
|
||||
oldpatient = patient
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
if(C.stat == 2)
|
||||
var/death_message = pick("No! NO!","Live, damnit! LIVE!","I...I've never lost a patient before. Not today, I mean.")
|
||||
speak(death_message)
|
||||
oldpatient = patient
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
var/reagent_id = null
|
||||
|
||||
if(emagged == 2) //Emagged! Time to poison everybody.
|
||||
reagent_id = "pancuronium"
|
||||
|
||||
else
|
||||
if(treat_virus)
|
||||
var/virus = 0
|
||||
for(var/datum/disease/D in C.viruses)
|
||||
//detectable virus
|
||||
if((!(D.visibility_flags & HIDDEN_SCANNER)) || (!(D.visibility_flags & HIDDEN_PANDEMIC)))
|
||||
if(D.severity != NONTHREAT) //virus is harmful
|
||||
if((D.stage > 1) || (D.spread_flags & AIRBORNE))
|
||||
virus = 1
|
||||
|
||||
if(!reagent_id && (virus))
|
||||
if(!C.reagents.has_reagent(treatment_virus))
|
||||
reagent_id = treatment_virus
|
||||
|
||||
if(!reagent_id && (C.getBruteLoss() >= heal_threshold))
|
||||
if(!C.reagents.has_reagent(treatment_brute))
|
||||
reagent_id = treatment_brute
|
||||
|
||||
if(!reagent_id && (C.getOxyLoss() >= (15 + heal_threshold)))
|
||||
if(!C.reagents.has_reagent(treatment_oxy))
|
||||
reagent_id = treatment_oxy
|
||||
|
||||
if(!reagent_id && (C.getFireLoss() >= heal_threshold))
|
||||
if(!C.reagents.has_reagent(treatment_fire))
|
||||
reagent_id = treatment_fire
|
||||
|
||||
if(!reagent_id && (C.getToxLoss() >= heal_threshold))
|
||||
if(!C.reagents.has_reagent(treatment_tox))
|
||||
reagent_id = treatment_tox
|
||||
|
||||
//If the patient is injured but doesn't have our special reagent in them then we should give it to them first
|
||||
if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
|
||||
for(var/datum/reagent/R in reagent_glass.reagents.reagent_list)
|
||||
if(!C.reagents.has_reagent(R.id))
|
||||
reagent_id = "internal_beaker"
|
||||
break
|
||||
|
||||
if(!reagent_id) //If they don't need any of that they're probably cured!
|
||||
var/message = pick("All patched up!","An apple a day keeps me away.","Feel better soon!")
|
||||
speak(message)
|
||||
bot_reset()
|
||||
return
|
||||
else
|
||||
if(!emagged && check_overdose(patient,reagent_id,injection_amount))
|
||||
soft_reset()
|
||||
return
|
||||
C.visible_message("<span class='danger'>[src] is trying to inject [patient]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to inject you!</span>")
|
||||
|
||||
spawn(30)//replace with do mob
|
||||
if((get_dist(src, patient) <= 1) && on && assess_patient(patient))
|
||||
if(reagent_id == "internal_beaker")
|
||||
if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
|
||||
var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1)
|
||||
reagent_glass.reagents.reaction(patient, 2, fraction)
|
||||
reagent_glass.reagents.trans_to(patient, injection_amount) //Inject from beaker instead.
|
||||
else
|
||||
patient.reagents.add_reagent(reagent_id,injection_amount)
|
||||
C.visible_message("<span class='danger'>[src] injects [patient] with its syringe!</span>", \
|
||||
"<span class='userdanger'>[src] injects you with its syringe!</span>")
|
||||
else
|
||||
visible_message("[src] retracts its syringe.")
|
||||
update_icon()
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
reagent_id = null
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/check_overdose(mob/living/carbon/patient,reagent_id,injection_amount)
|
||||
var/datum/reagent/R = chemical_reagents_list[reagent_id]
|
||||
if(!R.overdose_threshold)
|
||||
return 0
|
||||
var/current_volume = patient.reagents.get_reagent_amount(reagent_id)
|
||||
if(current_volume + injection_amount > R.overdose_threshold)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/bullet_act(obj/item/projectile/Proj)
|
||||
if(Proj.flag == "taser")
|
||||
stunned = min(stunned+10,20)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
switch(skin)
|
||||
if("ointment")
|
||||
new /obj/item/weapon/storage/firstaid/fire/empty(Tsec)
|
||||
if("tox")
|
||||
new /obj/item/weapon/storage/firstaid/toxin/empty(Tsec)
|
||||
if("o2")
|
||||
new /obj/item/weapon/storage/firstaid/o2/empty(Tsec)
|
||||
if("brute")
|
||||
new /obj/item/weapon/storage/firstaid/brute/empty(Tsec)
|
||||
if("adv")
|
||||
new /obj/item/weapon/storage/firstaid/adv/empty(Tsec)
|
||||
if("bezerk")
|
||||
new /obj/item/weapon/storage/firstaid/tactical/empty(Tsec)
|
||||
if("fish")
|
||||
new /obj/item/weapon/storage/firstaid/aquatic_kit(Tsec)
|
||||
else
|
||||
new /obj/item/weapon/storage/firstaid(Tsec)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
|
||||
new /obj/item/device/healthanalyzer(Tsec)
|
||||
|
||||
if(reagent_glass)
|
||||
reagent_glass.forceMove(Tsec)
|
||||
reagent_glass = null
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/declare(crit_patient)
|
||||
if(declare_cooldown)
|
||||
return
|
||||
if((skin == "bezerk"))
|
||||
return
|
||||
var/area/location = get_area(src)
|
||||
speak("Medical emergency! [crit_patient ? "<b>[crit_patient]</b>" : "A patient"] is in critical condition at [location]!", radio_channel)
|
||||
declare_cooldown = 1
|
||||
spawn(200) //Twenty seconds
|
||||
declare_cooldown = 0
|
||||
|
||||
/obj/machinery/bot_core/medbot
|
||||
req_one_access = list(access_medical, access_robotics)
|
||||
|
||||
/obj/machinery/bot_core/medbot/syndicate
|
||||
req_one_access = list(access_syndicate)
|
||||
@@ -0,0 +1,871 @@
|
||||
//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
|
||||
|
||||
#define SIGH 0
|
||||
#define ANNOYED 1
|
||||
#define DELIGHT 2
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot
|
||||
name = "\improper MULEbot"
|
||||
desc = "A Multiple Utility Load Effector bot."
|
||||
icon_state = "mulebot0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
a_intent = "harm" //No swapping
|
||||
buckle_lying = 0
|
||||
|
||||
radio_channel = "Supply"
|
||||
|
||||
bot_type = MULE_BOT
|
||||
bot_filter = RADIO_MULEBOT
|
||||
model = "MULE"
|
||||
bot_purpose = "deliver crates and other packages between departments, as requested"
|
||||
bot_core_type = /obj/machinery/bot_core/mulebot
|
||||
|
||||
suffix = ""
|
||||
|
||||
var/global/mulebot_count = 0
|
||||
var/atom/movable/load = null
|
||||
var/mob/living/passenger = null
|
||||
var/turf/target // this is turf to navigate to (location of beacon)
|
||||
var/loaddir = 0 // this the direction to unload onto/load from
|
||||
var/home_destination = "" // tag of home beacon
|
||||
|
||||
var/reached_target = 1 //true if already reached the target
|
||||
|
||||
var/auto_return = 1 // true if auto return to home beacon after unload
|
||||
var/auto_pickup = 1 // true if auto-pickup at beacon
|
||||
var/report_delivery = 1 // true if bot will announce an arrival to a location.
|
||||
|
||||
var/obj/item/weapon/stock_parts/cell/cell
|
||||
var/datum/wires/mulebot/wires = null
|
||||
var/bloodiness = 0
|
||||
var/currentBloodColor = "#A10808"
|
||||
var/currentDNA = null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/New()
|
||||
..()
|
||||
wires = new /datum/wires/mulebot(src)
|
||||
var/datum/job/cargo_tech/J = new/datum/job/cargo_tech
|
||||
access_card.access = J.get_access()
|
||||
prev_access = access_card.access
|
||||
cell = new(src)
|
||||
cell.charge = 2000
|
||||
cell.maxcharge = 2000
|
||||
|
||||
mulebot_count++
|
||||
set_suffix(suffix ? suffix : "#[mulebot_count]")
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Destroy()
|
||||
unload(0)
|
||||
if(wires)
|
||||
qdel(wires)
|
||||
wires = null
|
||||
if(cell)
|
||||
qdel(cell)
|
||||
cell = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/set_suffix(suffix)
|
||||
src.suffix = suffix
|
||||
if(paicard)
|
||||
bot_name = "\improper MULEbot ([suffix])"
|
||||
else
|
||||
name = "\improper MULEbot ([suffix])"
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bot_reset()
|
||||
..()
|
||||
reached_target = 0
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
..()
|
||||
if(open)
|
||||
on = FALSE
|
||||
update_controls()
|
||||
else if(istype(I,/obj/item/weapon/stock_parts/cell) && open && !cell)
|
||||
if(!user.drop_item())
|
||||
return
|
||||
var/obj/item/weapon/stock_parts/cell/C = I
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
visible_message("[user] inserts a cell into [src].",
|
||||
"<span class='notice'>You insert the new cell into [src].</span>")
|
||||
update_controls()
|
||||
else if(istype(I, /obj/item/weapon/crowbar) && open && cell)
|
||||
cell.add_fingerprint(usr)
|
||||
cell.forceMove(loc)
|
||||
cell = null
|
||||
visible_message("[user] crowbars out the power cell from [src].",
|
||||
"<span class='notice'>You pry the powercell out of [src].</span>")
|
||||
update_controls()
|
||||
else if (istype(I, /obj/item/weapon/wrench))
|
||||
if (health < maxHealth)
|
||||
adjustBruteLoss(-25)
|
||||
updatehealth()
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] repairs [src]!</span>",
|
||||
"<span class='notice'>You repair [src]!</span>"
|
||||
)
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair!</span>"
|
||||
else if((istype(I, /obj/item/device/multitool) || istype(I, /obj/item/weapon/wirecutters)) && open)
|
||||
return attack_hand(user)
|
||||
else if(load && ismob(load)) // chance to knock off rider
|
||||
if(prob(1 + I.force * 2))
|
||||
unload(0)
|
||||
user.visible_message("<span class='danger'>[user] knocks [load] off [src] with \the [I]!</span>",
|
||||
"<span class='danger'>You knock [load] off [src] with \the [I]!</span>")
|
||||
else
|
||||
user << "<span class='warning'>You hit [src] with \the [I] but to no effect!</span>"
|
||||
..()
|
||||
else
|
||||
..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/emag_act(mob/user)
|
||||
if(emagged < 1)
|
||||
emagged = 1
|
||||
if(!open)
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the [src]'s controls!</span>"
|
||||
flick("mulebot-emagged", src)
|
||||
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/update_icon()
|
||||
if(open)
|
||||
icon_state="mulebot-hatch"
|
||||
else
|
||||
icon_state = "mulebot[!wires.MobAvoid()]"
|
||||
overlays.Cut()
|
||||
if(load && !ismob(load))//buckling handles the mob offsets
|
||||
load.pixel_y = initial(load.pixel_y) + 9
|
||||
if(load.layer < layer)
|
||||
load.layer = layer + 0.1
|
||||
overlays += load
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ex_act(severity)
|
||||
unload(0)
|
||||
switch(severity)
|
||||
if(1)
|
||||
qdel(src)
|
||||
if(2)
|
||||
for(var/i = 1; i < 3; i++)
|
||||
wires.RandomCut()
|
||||
if(3)
|
||||
wires.RandomCut()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
|
||||
if(..())
|
||||
if(prob(50) && !isnull(load))
|
||||
unload(0)
|
||||
if(prob(25))
|
||||
visible_message("<span class='danger'>Something shorts out inside [src]!</span>")
|
||||
wires.RandomCut()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Topic(href, list/href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["op"])
|
||||
if("lock")
|
||||
toggle_lock(usr)
|
||||
if("power")
|
||||
if(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].")
|
||||
if("cellremove")
|
||||
if(open && cell && !usr.get_active_hand())
|
||||
cell.updateicon()
|
||||
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>")
|
||||
if("cellinsert")
|
||||
if(open && !cell)
|
||||
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
|
||||
if(istype(C))
|
||||
usr.drop_item()
|
||||
cell = C
|
||||
C.forceMove(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>")
|
||||
if("stop")
|
||||
if(mode >= BOT_DELIVER)
|
||||
bot_reset()
|
||||
if("go")
|
||||
if(mode == BOT_IDLE)
|
||||
start()
|
||||
if("home")
|
||||
if(mode == BOT_IDLE || mode == BOT_DELIVER)
|
||||
start_home()
|
||||
if("destination")
|
||||
var/new_dest = input(usr, "Enter Destination:", name, destination) as null|anything in deliverybeacontags
|
||||
if(new_dest)
|
||||
set_destination(new_dest)
|
||||
if("setid")
|
||||
var/new_id = stripped_input(usr, "Enter ID:", name, suffix, MAX_NAME_LEN)
|
||||
if(new_id)
|
||||
set_suffix(new_id)
|
||||
if("sethome")
|
||||
var/new_home = input(usr, "Enter Home:", name, home_destination) as null|anything in deliverybeacontags
|
||||
if(new_home)
|
||||
home_destination = new_home
|
||||
if("unload")
|
||||
if(load && mode != BOT_HUNT)
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
if("autoret")
|
||||
auto_return = !auto_return
|
||||
if("autopick")
|
||||
auto_pickup = !auto_pickup
|
||||
if("report")
|
||||
report_delivery = !report_delivery
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/toggle_lock(var/mob/user)
|
||||
if(bot_core.allowed(user))
|
||||
locked = !locked
|
||||
update_controls()
|
||||
return 1
|
||||
else
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return 0
|
||||
|
||||
// TODO: remove this; PDAs currently depend on it
|
||||
/mob/living/simple_animal/bot/mulebot/get_controls(mob/user)
|
||||
var/ai = issilicon(user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
|
||||
dat += "<b>ID:</b> [suffix]<BR>"
|
||||
dat += "<b>Power:</b> [on ? "On" : "Off"]<BR>"
|
||||
|
||||
if(!open)
|
||||
dat += "<h3>Status</h3>"
|
||||
dat += "<div class='statusDisplay'>"
|
||||
switch(mode)
|
||||
if(BOT_IDLE)
|
||||
dat += "<span class='good'>Ready</span>"
|
||||
if(BOT_DELIVER)
|
||||
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
|
||||
if(BOT_GO_HOME)
|
||||
dat += "<span class='good'>[mode_name[BOT_GO_HOME]]</span>"
|
||||
if(BOT_BLOCKED)
|
||||
dat += "<span class='average'>[mode_name[BOT_BLOCKED]]</span>"
|
||||
if(BOT_NAV,BOT_WAIT_FOR_NAV)
|
||||
dat += "<span class='average'>[mode_name[BOT_NAV]]</span>"
|
||||
if(BOT_NO_ROUTE)
|
||||
dat += "<span class='bad'>[mode_name[BOT_NO_ROUTE]]</span>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<b>Current Load:</b> [load ? load.name : "<i>none</i>"]<BR>"
|
||||
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
|
||||
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
|
||||
|
||||
if(locked && !ai && !check_rights(R_ADMIN, 0, user))
|
||||
dat += " <br /><div class='notice'>Controls are locked</div><A href='?src=\ref[src];op=unlock'>Unlock Controls</A>"
|
||||
else
|
||||
dat += " <br /><div class='notice'>Controls are unlocked</div><A href='?src=\ref[src];op=lock'>Lock Controls</A><BR><BR>"
|
||||
|
||||
dat += "<A href='?src=\ref[src];op=power'>Toggle Power</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=stop'>Stop</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=go'>Proceed</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=home'>Return to Home</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=destination'>Set Destination</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=sethome'>Set Home</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
|
||||
dat += "<A href='?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
|
||||
dat += "<A href='?src=\ref[src];op=report'>Toggle Delivery Reporting</A> ([report_delivery ? "On" : "Off"])<BR>"
|
||||
if(load)
|
||||
dat += "<A href='?src=\ref[src];op=unload'>Unload Now</A><BR>"
|
||||
dat += "<div class='notice'>The maintenance hatch is closed.</div>"
|
||||
else
|
||||
if(!ai)
|
||||
dat += "<div class='notice'>The maintenance hatch is open.</div><BR>"
|
||||
dat += "<b>Power cell:</b> "
|
||||
if(cell)
|
||||
dat += "<A href='?src=\ref[src];op=cellremove'>Installed</A><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];op=cellinsert'>Removed</A><BR>"
|
||||
|
||||
dat += wires.GetInteractWindow()
|
||||
else
|
||||
dat += "<div class='notice'>The bot is in maintenance mode and cannot be controlled.</div><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
// returns true if the bot has power
|
||||
/mob/living/simple_animal/bot/mulebot/proc/has_power()
|
||||
return !open && cell && cell.charge > 0 && wires.HasPower()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
|
||||
switch(type)
|
||||
if(SIGH)
|
||||
audible_message("[src] makes a sighing buzz.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
if(ANNOYED)
|
||||
audible_message("[src] makes an annoyed buzzing sound.", "<span class='emote'>You hear an electronic buzzing sound.</span>")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
if(DELIGHT)
|
||||
audible_message("[src] makes a delighted ping!", "<span class='emote'>You hear a ping.</span>")
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
|
||||
|
||||
// mousedrop a crate to load the bot
|
||||
// can load anything if hacked
|
||||
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
|
||||
|
||||
if(user.incapacitated() || user.lying || get_dist(user, src) > 1)
|
||||
return
|
||||
|
||||
if(!istype(AM))
|
||||
return
|
||||
|
||||
load(AM)
|
||||
|
||||
// called to load a crate
|
||||
/mob/living/simple_animal/bot/mulebot/proc/load(atom/movable/AM)
|
||||
if(!on || load || AM.anchored || get_dist(src, AM) > 1)
|
||||
return
|
||||
|
||||
|
||||
//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(AM, /obj/item) && !istype(AM, /obj/machinery) && !istype(AM, /obj/structure) && !ismob(AM))
|
||||
return
|
||||
if(!isturf(AM.loc)) //To prevent the loading from stuff from someone's inventory or screen icons.
|
||||
return
|
||||
|
||||
var/obj/structure/closet/crate/CRATE
|
||||
if(istype(AM,/obj/structure/closet/crate))
|
||||
CRATE = AM
|
||||
else
|
||||
if(wires.LoadCheck())
|
||||
buzz(SIGH)
|
||||
return // if not hacked, only allow crates to be loaded
|
||||
|
||||
if(CRATE) // if it's a crate, close before loading
|
||||
CRATE.close()
|
||||
|
||||
if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
if(O.buckled_mob || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it.
|
||||
buzz(SIGH)
|
||||
return
|
||||
|
||||
if(isliving(AM))
|
||||
if(!load_mob(AM))
|
||||
return
|
||||
else
|
||||
AM.forceMove(src)
|
||||
|
||||
load = AM
|
||||
mode = BOT_IDLE
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/load_mob(mob/living/M)
|
||||
can_buckle = TRUE
|
||||
if(buckle_mob(M))
|
||||
passenger = M
|
||||
load = M
|
||||
can_buckle = FALSE
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/post_buckle_mob(mob/living/M)
|
||||
if(M == buckled_mob) //post buckling
|
||||
M.pixel_y = initial(M.pixel_y) + 9
|
||||
if(M.layer < layer)
|
||||
M.layer = layer + 0.1
|
||||
|
||||
else //post unbuckling
|
||||
load = null
|
||||
M.layer = initial(M.layer)
|
||||
M.pixel_y = initial(M.pixel_y)
|
||||
|
||||
// called to unload the bot
|
||||
// argument is optional direction to unload
|
||||
// if zero, unload at bot's location
|
||||
/mob/living/simple_animal/bot/mulebot/proc/unload(dirn)
|
||||
if(!load)
|
||||
return
|
||||
|
||||
mode = BOT_IDLE
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
if(ismob(load))
|
||||
var/mob/M = load
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = M
|
||||
unbuckle_mob()
|
||||
|
||||
if(load)
|
||||
load.forceMove(loc)
|
||||
load.pixel_y = initial(load.pixel_y)
|
||||
load.layer = initial(load.layer)
|
||||
if(dirn)
|
||||
var/turf/T = loc
|
||||
var/turf/newT = get_step(T,dirn)
|
||||
if(load.CanPass(load,newT)) //Can't get off onto anything that wouldn't let you pass normally
|
||||
step(load, dirn)
|
||||
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 == access_card || AM == Radio || AM == bot_core || AM == paicard)
|
||||
continue
|
||||
|
||||
AM.forceMove(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 = M
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/call_bot()
|
||||
..()
|
||||
var/area/dest_area
|
||||
if(path && path.len)
|
||||
target = ai_waypoint //Target is the end point of the path, the waypoint set by the AI.
|
||||
dest_area = get_area(target)
|
||||
destination = format_text(dest_area.name)
|
||||
pathset = 1 //Indicates the AI's custom path is initialized.
|
||||
start()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/handle_automated_action()
|
||||
diag_hud_set_botmode()
|
||||
|
||||
if(!has_power())
|
||||
on = 0
|
||||
return
|
||||
if(on)
|
||||
var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
|
||||
//world << "speed: [speed]"
|
||||
var/num_steps = 0
|
||||
switch(speed)
|
||||
if(0)
|
||||
// do nothing
|
||||
if(1)
|
||||
num_steps = 10
|
||||
if(2)
|
||||
num_steps = 5
|
||||
if(3)
|
||||
num_steps = 3
|
||||
|
||||
if(num_steps)
|
||||
process_bot()
|
||||
num_steps--
|
||||
if(mode != BOT_IDLE)
|
||||
spawn(0)
|
||||
for(var/i=num_steps,i>0,i--)
|
||||
sleep(2)
|
||||
process_bot()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/process_bot()
|
||||
if(!on)
|
||||
return
|
||||
update_icon()
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
return
|
||||
|
||||
if(BOT_DELIVER, BOT_GO_HOME, BOT_BLOCKED) // 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])"
|
||||
|
||||
var/oldloc = loc
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(cell) cell.use(1)
|
||||
if(moved && oldloc!=loc) // successful move
|
||||
//world << "Successful move."
|
||||
blockcount = 0
|
||||
path -= loc
|
||||
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
|
||||
else // failed to move
|
||||
|
||||
//world << "Unable to move."
|
||||
blockcount++
|
||||
mode = BOT_BLOCKED
|
||||
if(blockcount == 3)
|
||||
buzz(ANNOYED)
|
||||
|
||||
if(blockcount > 10) // attempt 10 times before recomputing
|
||||
// find new path excluding blocked turf
|
||||
buzz(SIGH)
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
blockcount = 0
|
||||
spawn(20)
|
||||
calc_path(avoid=next)
|
||||
if(path.len > 0)
|
||||
buzz(DELIGHT)
|
||||
mode = BOT_BLOCKED
|
||||
return
|
||||
return
|
||||
else
|
||||
buzz(ANNOYED)
|
||||
//world << "Bad turf."
|
||||
mode = BOT_NAV
|
||||
return
|
||||
else
|
||||
//world << "No path."
|
||||
mode = BOT_NAV
|
||||
return
|
||||
|
||||
if(BOT_NAV) // calculate new path
|
||||
//world << "Calc new path."
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
spawn(0)
|
||||
calc_path()
|
||||
|
||||
if(path.len > 0)
|
||||
blockcount = 0
|
||||
mode = BOT_BLOCKED
|
||||
buzz(DELIGHT)
|
||||
|
||||
else
|
||||
buzz(SIGH)
|
||||
|
||||
mode = BOT_NO_ROUTE
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Move(turf/simulated/next)
|
||||
var/turf/simulated/last = loc
|
||||
|
||||
if(istype(last) && bloodiness)
|
||||
last.AddTracks(/obj/effect/decal/cleanable/blood/tracks/wheels, currentDNA, 0, get_dir(last, next), currentBloodColor)
|
||||
|
||||
. = ..()
|
||||
|
||||
if(. && istype(next))
|
||||
if(bloodiness)
|
||||
next.AddTracks(/obj/effect/decal/cleanable/blood/tracks/wheels, currentDNA, get_dir(last, next), 0, currentBloodColor)
|
||||
bloodiness--
|
||||
|
||||
for(var/mob/living/carbon/human/H in next)
|
||||
RunOver(H)
|
||||
|
||||
// calculates a path to the current destination
|
||||
// given an optional turf to avoid
|
||||
/mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null)
|
||||
check_bot_access()
|
||||
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid)
|
||||
|
||||
// sets the current destination
|
||||
// signals all beacons matching the delivery code
|
||||
// beacons will return a signal giving their locations
|
||||
/mob/living/simple_animal/bot/mulebot/proc/set_destination(new_dest)
|
||||
new_destination = new_dest
|
||||
get_nav()
|
||||
|
||||
// starts bot moving to current destination
|
||||
/mob/living/simple_animal/bot/mulebot/proc/start()
|
||||
if(!on)
|
||||
return
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
update_icon()
|
||||
get_nav()
|
||||
|
||||
// starts bot moving to home
|
||||
// sends a beacon query to find
|
||||
/mob/living/simple_animal/bot/mulebot/proc/start_home()
|
||||
if(!on)
|
||||
return
|
||||
spawn(0)
|
||||
set_destination(home_destination)
|
||||
mode = BOT_BLOCKED
|
||||
update_icon()
|
||||
|
||||
// called when bot reaches current target
|
||||
/mob/living/simple_animal/bot/mulebot/proc/at_target()
|
||||
if(!reached_target)
|
||||
radio_channel = "Supply" //Supply channel
|
||||
audible_message("[src] makes a chiming sound!", "<span class='emote'>You hear a chime.</span>")
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
|
||||
reached_target = 1
|
||||
|
||||
if(pathset) //The AI called us here, so notify it of our arrival.
|
||||
loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
|
||||
if(calling_ai)
|
||||
calling_ai << "<span class='notice'>\icon[src] [src] wirelessly plays a chiming sound!</span>"
|
||||
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
|
||||
calling_ai = null
|
||||
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
|
||||
|
||||
if(load) // if loaded, unload at target
|
||||
if(report_delivery)
|
||||
speak("Destination <b>[destination]</b> reached. Unloading [load].", radio_channel)
|
||||
if(istype(load, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/C = load
|
||||
C.notifyRecipient(destination)
|
||||
unload(loaddir)
|
||||
else
|
||||
// not loaded
|
||||
if(auto_pickup) // find a crate
|
||||
var/atom/movable/AM
|
||||
if(wires.LoadCheck()) // if hacked, 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 && AM.Adjacent(src))
|
||||
load(AM)
|
||||
if(report_delivery)
|
||||
speak("Now loading [load] at <b>[get_area(src)]</b>.", radio_channel)
|
||||
// whatever happened, check to see if we return home
|
||||
|
||||
if(auto_return && home_destination && destination != home_destination)
|
||||
// auto return set and not at home already
|
||||
start_home()
|
||||
mode = BOT_BLOCKED
|
||||
else
|
||||
bot_reset() // otherwise go idle
|
||||
|
||||
return
|
||||
|
||||
// called when bot bumps into anything
|
||||
/mob/living/simple_animal/bot/mulebot/Bump(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))
|
||||
visible_message("<span class='danger'>[src] bumps into [M]!</span>")
|
||||
else
|
||||
add_logs(src, M, "knocked down")
|
||||
visible_message("<span class='danger'>[src] knocks over [M]!</span>")
|
||||
M.stop_pulling()
|
||||
M.Stun(8)
|
||||
M.Weaken(5)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H)
|
||||
add_logs(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])")
|
||||
H.visible_message("<span class='danger'>[src] drives over [H]!</span>", \
|
||||
"<span class='userdanger'>[src] drives over you!<span>")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/damage = rand(5,15)
|
||||
H.apply_damage(2*damage, BRUTE, "head", run_armor_check("head", "melee"))
|
||||
H.apply_damage(2*damage, BRUTE, "chest", run_armor_check("chest", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_leg", run_armor_check("l_leg", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_leg", run_armor_check("r_leg", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_arm", run_armor_check("l_arm", "melee"))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_arm", run_armor_check("r_arm", "melee"))
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/B = new(loc)
|
||||
B.blood_DNA = list()
|
||||
B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
currentDNA = B.blood_DNA
|
||||
|
||||
bloodiness += 4
|
||||
|
||||
currentBloodColor = "#A10808"
|
||||
if(istype(H))
|
||||
var/datum/reagent/blood/bld = H.get_blood(H.vessel)
|
||||
if(bld.data["blood_colour"])
|
||||
currentBloodColor = bld.data["blood_colour"]
|
||||
return
|
||||
B.basecolor = currentBloodColor
|
||||
B.update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bot_control_message(command, mob/user, user_turf)
|
||||
switch(command)
|
||||
if("start")
|
||||
if(load)
|
||||
src << "<span class='warning big'>DELIVER [load] TO [destination]</span>"
|
||||
else
|
||||
src << "<span class='warning big'>PICK UP DELIVERY AT [destination]</span>"
|
||||
if("unload")
|
||||
if(load)
|
||||
src << "<span class='warning big'>UNLOAD</span>"
|
||||
else
|
||||
src << "<span class='warning big'>LOAD</span>"
|
||||
if("autoret", "autopick", "target")
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/receive_signal(datum/signal/signal)
|
||||
if(!wires.RemoteRX() || ..())
|
||||
return 1
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
|
||||
// process control input
|
||||
switch(recv)
|
||||
if("start")
|
||||
start()
|
||||
|
||||
if("target")
|
||||
set_destination(signal.data["destination"])
|
||||
|
||||
if("unload")
|
||||
if(client)
|
||||
return 1
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
|
||||
if("autoret")
|
||||
auto_return = text2num(signal.data["value"])
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = text2num(signal.data["value"])
|
||||
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval)
|
||||
if(!wires.RemoteTX())
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
// signals bot status etc. to controller
|
||||
/mob/living/simple_animal/bot/mulebot/send_status()
|
||||
var/list/kv = list(
|
||||
"type" = MULE_BOT,
|
||||
"name" = suffix,
|
||||
"loca" = get_area(src),
|
||||
"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)
|
||||
|
||||
// player on mulebot attempted to move
|
||||
/mob/living/simple_animal/bot/mulebot/relaymove(mob/user)
|
||||
if(user.incapacitated())
|
||||
return
|
||||
if(load == user)
|
||||
unload(0)
|
||||
|
||||
|
||||
//Update navigation data. Called when commanded to deliver, return home, or a route update is needed...
|
||||
/mob/living/simple_animal/bot/mulebot/proc/get_nav()
|
||||
if(!on || !wires.BeaconRX())
|
||||
return
|
||||
|
||||
for(var/obj/machinery/navbeacon/NB in deliverybeacons)
|
||||
if(NB.location == new_destination) // if the beacon location matches the set destination
|
||||
destination = new_destination // the we will navigate there
|
||||
target = NB.loc
|
||||
var/direction = NB.dir // this will be the load/unload dir
|
||||
loaddir = direction
|
||||
update_icon()
|
||||
calc_path()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/emp_act(severity)
|
||||
if(cell)
|
||||
cell.emp_act(severity)
|
||||
if(load)
|
||||
load.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/explode()
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/rods(Tsec)
|
||||
new /obj/item/stack/cable_coil/cut(Tsec)
|
||||
if(cell)
|
||||
cell.forceMove(Tsec)
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/remove_air(amount) //To prevent riders suffocating
|
||||
if(loc)
|
||||
return loc.remove_air(amount)
|
||||
else
|
||||
return null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/resist()
|
||||
..()
|
||||
if(load)
|
||||
unload()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/UnarmedAttack(atom/A)
|
||||
if(isturf(A) && isturf(loc) && loc.Adjacent(A) && load)
|
||||
unload(get_dir(loc, A))
|
||||
else
|
||||
..()
|
||||
|
||||
#undef SIGH
|
||||
#undef ANNOYED
|
||||
#undef DELIGHT
|
||||
|
||||
/obj/machinery/bot_core/mulebot
|
||||
req_access = list(access_cargo)
|
||||
@@ -0,0 +1,465 @@
|
||||
/mob/living/simple_animal/bot/secbot
|
||||
name = "\improper Securitron"
|
||||
desc = "A little security robot. He looks less than thrilled."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "secbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
pass_flags = PASSMOB
|
||||
|
||||
radio_channel = "Security" //Security channel
|
||||
bot_type = SEC_BOT
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "Securitron"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core_type = /obj/machinery/bot_core/secbot
|
||||
window_id = "autosec"
|
||||
window_name = "Automatic Security Unit v1.6"
|
||||
|
||||
var/base_icon = "secbot"
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
|
||||
var/idcheck = 0 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
var/arrest_type = 0 //If true, don't handcuff
|
||||
var/harmbaton = 0 //If true, beat instead of stun
|
||||
var/flashing_lights = 0 //If true, flash lights
|
||||
var/prev_flashing_lights = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Officer Beepsky"
|
||||
desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey."
|
||||
idcheck = 0
|
||||
weaponscheck = 0
|
||||
auto_patrol = 1
|
||||
allow_pai = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/explode()
|
||||
var/turf/Tsec = get_turf(src)
|
||||
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/S = new(Tsec)
|
||||
S.reagents.add_reagent("whiskey", 15)
|
||||
S.on_reagent_change()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/pingsky
|
||||
name = "Officer Pingsky"
|
||||
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
|
||||
radio_channel = "AI Private"
|
||||
allow_pai = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/ofitser
|
||||
name = "Prison Ofitser"
|
||||
desc = "It's Prison Ofitser! Powered by the tears and sweat of prisoners."
|
||||
idcheck = 0
|
||||
weaponscheck = 1
|
||||
auto_patrol = 1
|
||||
allow_pai = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/buzzsky
|
||||
name = "Officer Buzzsky"
|
||||
desc = "It's Officer Buzzsky! Rusted and falling apart, he seems less than thrilled with the crew for leaving him in his current state."
|
||||
base_icon = "rustbot"
|
||||
icon_state = "rustbot0"
|
||||
declare_arrests = 0
|
||||
arrest_type = 1
|
||||
harmbaton = 1
|
||||
emagged = 2
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/New()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
spawn(3)
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
//SECHUD
|
||||
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
permanent_huds |= secsensor
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_on()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_off()
|
||||
..()
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bot_reset()
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = 0
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/set_custom_texts()
|
||||
|
||||
text_hack = "You overload [name]'s target identification system."
|
||||
text_dehack = "You reboot [name] and restore the target identification."
|
||||
text_dehack_fail = "[name] refuses to accept your authority!"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
|
||||
var/dat
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
update_controls()
|
||||
if("weaponscheck")
|
||||
weaponscheck = !weaponscheck
|
||||
update_controls()
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
update_controls()
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
update_controls()
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
|
||||
threatlevel = H.assess_threat(src)
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = H
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
|
||||
if(H.a_intent == "harm")
|
||||
retaliate(H)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry.
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
retaliate(user)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << "<span class='danger'>You short out [src]'s target assessment circuits.</span>"
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.stunned || arrest_type)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrower && (istype(I.thrower, /mob/living/carbon/human)))
|
||||
var/mob/living/carbon/human/H = I.thrower
|
||||
retaliate(H)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
spawn(60)
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_inv_handcuffed(1)
|
||||
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
|
||||
back_to_idle()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
if(harmbaton)
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
icon_state = "[base_icon]-c"
|
||||
spawn(2)
|
||||
icon_state = "[base_icon][on]"
|
||||
var/threat = 5
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
C.stuttering = 5
|
||||
if(harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave
|
||||
C.apply_damage(10, BRUTE)
|
||||
C.Stun(5)
|
||||
C.Weaken(5)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(src)
|
||||
else
|
||||
C.Weaken(5)
|
||||
C.stuttering = 5
|
||||
C.Stun(5)
|
||||
add_logs(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message("<span class='danger'>[src] has [harmbaton ? "beaten" : "stunned"] [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has [harmbaton ? "beaten" : "stunned"] you!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Life()
|
||||
. = ..()
|
||||
if(flashing_lights)
|
||||
switch(light_color)
|
||||
if(LIGHT_COLOR_PURE_RED)
|
||||
light_color = LIGHT_COLOR_PURE_BLUE
|
||||
if(LIGHT_COLOR_PURE_BLUE)
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
update_light()
|
||||
else if(prev_flashing_lights)
|
||||
light_color = LIGHT_COLOR_PURE_RED
|
||||
update_light()
|
||||
|
||||
prev_flashing_lights = flashing_lights
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/verb/toggle_flashing_lights()
|
||||
set name = "Toggle Flashing Lights"
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
|
||||
flashing_lights = !flashing_lights
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
flashing_lights = mode == BOT_HUNT
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src,0)
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(!mode && auto_patrol) // still idle, and set to patrol
|
||||
mode = BOT_START_PATROL // switch to patrol mode
|
||||
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
// if can't reach perp for long enough, go idle
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 1
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
|
||||
back_to_hunt()
|
||||
return
|
||||
else //Try arresting again if the target escapes.
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = 0
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
bot_patrol()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
|
||||
anchored = 0
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
|
||||
anchored = 0
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
|
||||
anchored = 0
|
||||
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
if((C.stat) || (C.handcuffed))
|
||||
continue
|
||||
|
||||
if((C.name == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(src)
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
break
|
||||
else
|
||||
continue
|
||||
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='userdanger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.overlays += "hs_hole"
|
||||
Sa.created_name = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/weapon/melee/baton(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(loc)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
|
||||
..()
|
||||
if(!isalien(target))
|
||||
target = user
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
|
||||
if(ismob(AM) && target)
|
||||
var/mob/living/carbon/C = AM
|
||||
if(!istype(C) || !C || in_range(src, target))
|
||||
return
|
||||
C.visible_message("<span class='warning'>[pick( \
|
||||
"[C] dives out of [src]'s way!", \
|
||||
"[C] stumbles over [src]!", \
|
||||
"[C] jumps out of [src]'s path!", \
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
C.Weaken(2)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/secbot
|
||||
req_access = list(access_security)
|
||||
@@ -14,14 +14,7 @@
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
faction = list("cult")
|
||||
flying = 1
|
||||
@@ -110,7 +103,7 @@
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/Life()
|
||||
weakened = 0
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
density = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = 2
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 0
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 0)
|
||||
|
||||
/mob/living/simple_animal/butterfly/New()
|
||||
..()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "cat2"
|
||||
icon_living = "cat2"
|
||||
icon_dead = "cat2_dead"
|
||||
icon_resting = "cat_rest"
|
||||
icon_resting = "cat2_rest"
|
||||
gender = MALE
|
||||
speak = list("Meow!", "Esp!", "Purr!", "HSSSSS")
|
||||
speak_emote = list("purrs", "meows")
|
||||
@@ -16,8 +16,7 @@
|
||||
see_in_dark = 6
|
||||
simplespecies = /mob/living/simple_animal/pet/cat
|
||||
childtype = /mob/living/simple_animal/pet/cat/kitten
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
@@ -28,7 +27,8 @@
|
||||
desc = "GCAT"
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat2_dead"
|
||||
icon_dead = "cat_dead"
|
||||
icon_resting = "cat_rest"
|
||||
gender = FEMALE
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
speak_chance = 1
|
||||
turns_per_move = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/corgi = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
@@ -32,31 +31,6 @@
|
||||
..()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/handle_hud_icons()
|
||||
..()
|
||||
if(fire)
|
||||
if(fire_alert) fire.icon_state = "fire[fire_alert]" //fire_alert is either 0 if no alert, 1 for heat and 2 for cold.
|
||||
else fire.icon_state = "fire0"
|
||||
if(oxygen)
|
||||
if(oxygen_alert) oxygen.icon_state = "oxy1"
|
||||
else oxygen.icon_state = "oxy0"
|
||||
if(toxin)
|
||||
if(toxins_alert) toxin.icon_state = "tox1"
|
||||
else toxin.icon_state = "tox0"
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/handle_hud_icons_health()
|
||||
..()
|
||||
if(healths)
|
||||
switch(health)
|
||||
if(30 to INFINITY) healths.icon_state = "health0"
|
||||
if(26 to 29) healths.icon_state = "health1"
|
||||
if(21 to 25) healths.icon_state = "health2"
|
||||
if(16 to 20) healths.icon_state = "health3"
|
||||
if(11 to 15) healths.icon_state = "health4"
|
||||
if(6 to 10) healths.icon_state = "health5"
|
||||
if(1 to 5) healths.icon_state = "health6"
|
||||
if(0) healths.icon_state = "health7"
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Life()
|
||||
. = ..()
|
||||
regenerate_icons()
|
||||
@@ -73,19 +47,21 @@
|
||||
user.set_machine(src)
|
||||
if(user.stat) return
|
||||
|
||||
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
|
||||
if(inventory_head)
|
||||
dat += "<br><b>Head:</b> [inventory_head] (<a href='?src=\ref[src];remove_inv=head'>Remove</a>)"
|
||||
else
|
||||
dat += "<br><b>Head:</b> <a href='?src=\ref[src];add_inv=head'>Nothing</a>"
|
||||
if(inventory_back)
|
||||
dat += "<br><b>Back:</b> [inventory_back] (<a href='?src=\ref[src];remove_inv=back'>Remove</a>)"
|
||||
else
|
||||
dat += "<br><b>Back:</b> <a href='?src=\ref[src];add_inv=back'>Nothing</a>"
|
||||
var/dat = {"<table>"}
|
||||
|
||||
user << browse(dat, text("window=mob[];size=325x500", real_name))
|
||||
onclose(user, "mob[real_name]")
|
||||
return
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=\ref[src];[inventory_head?"remove_inv":"add_inv"]=head'>[(inventory_head && !(inventory_head.flags&ABSTRACT)) ? inventory_head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];[inventory_back?"remove_inv":"add_inv"]=back'>[(inventory_back && !(inventory_back.flags&ABSTRACT)) ? inventory_back : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
if(can_collar)
|
||||
dat += "<tr><td> </td></tr>"
|
||||
dat += "<tr><td><B>Collar:</B></td><td><A href='?src=\ref[src];[collar?"remove_inv":"add_inv"]=collar'>[(collar && !(collar.flags&ABSTRACT)) ? collar : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(inventory_head && inventory_back)
|
||||
@@ -422,11 +398,11 @@
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Ian/Life()
|
||||
/mob/living/simple_animal/pet/corgi/Ian/process_ai()
|
||||
..()
|
||||
|
||||
//Feeding, chasing food, FOOOOODDDD
|
||||
if(!stat && !resting && !buckled && (ckey == null))
|
||||
if(!resting && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
turns_since_scan = 0
|
||||
@@ -473,10 +449,9 @@
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("dances around.","chases its tail!"))
|
||||
spawn(0)
|
||||
if (ckey == null)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
@@ -542,11 +517,7 @@
|
||||
overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
|
||||
else
|
||||
overlays += image('icons/mob/mask.dmi',"facehugger_corgi")
|
||||
if(pcollar)
|
||||
overlays += collar
|
||||
overlays += pettag
|
||||
|
||||
return
|
||||
..(0)
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/puppy
|
||||
name = "\improper corgi puppy"
|
||||
@@ -590,20 +561,18 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Lisa/Life()
|
||||
/mob/living/simple_animal/pet/corgi/Lisa/process_ai()
|
||||
..()
|
||||
|
||||
make_babies()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
if (ckey == null)
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
dir = i
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
emote_see = list("clacks")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "stomps the"
|
||||
@@ -22,6 +21,7 @@
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_mask
|
||||
can_hide = 1
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/crab/handle_automated_movement()
|
||||
//CRAB movement
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 0 //I'm so funny
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 4)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
response_harm = "kicks"
|
||||
can_collar = 1
|
||||
@@ -38,6 +38,7 @@
|
||||
var/list/donors = list()
|
||||
var/ready_evolve = 0
|
||||
holder_type = /obj/item/weapon/holder/diona
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/diona/New()
|
||||
..()
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 4
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 4)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
@@ -26,6 +25,7 @@
|
||||
melee_damage_upper = 2
|
||||
stop_automated_movement_when_pulled = 1
|
||||
var/milk_content = 0
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/handle_automated_movement()
|
||||
..()
|
||||
@@ -102,8 +102,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 6)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
@@ -111,6 +110,7 @@
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
health = 50
|
||||
var/milk_content = 0
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/cow/New()
|
||||
..()
|
||||
@@ -166,8 +166,7 @@
|
||||
density = 0
|
||||
speak_chance = 2
|
||||
turns_per_move = 2
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
@@ -178,6 +177,7 @@
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
small = 1
|
||||
can_hide = 1
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/chick/New()
|
||||
..()
|
||||
@@ -208,8 +208,7 @@ var/global/chicken_count = 0
|
||||
density = 0
|
||||
speak_chance = 2
|
||||
turns_per_move = 3
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 2
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 2)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
@@ -220,6 +219,7 @@ var/global/chicken_count = 0
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
small = 1
|
||||
can_hide = 1
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/chicken/New()
|
||||
..()
|
||||
@@ -290,13 +290,13 @@ var/global/chicken_count = 0
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/ham
|
||||
meat_amount = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/ham = 6)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
attacktext = "kicks"
|
||||
health = 50
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/turkey
|
||||
name = "turkey"
|
||||
@@ -311,13 +311,13 @@ var/global/chicken_count = 0
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat //enough to make one turkey
|
||||
meat_amount = 4
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 4)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
attacktext = "pecks"
|
||||
health = 50
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/goose
|
||||
name = "goose"
|
||||
@@ -332,13 +332,13 @@ var/global/chicken_count = 0
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 6)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
attacktext = "kicks"
|
||||
health = 50
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/seal
|
||||
name = "seal"
|
||||
@@ -353,13 +353,13 @@ var/global/chicken_count = 0
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 6)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
attacktext = "kicks"
|
||||
health = 50
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/walrus
|
||||
name = "walrus"
|
||||
@@ -374,10 +374,10 @@ var/global/chicken_count = 0
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 6
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 6)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "kicks the"
|
||||
attacktext = "kicks"
|
||||
health = 50
|
||||
can_collar = 1
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
density = 0
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
can_hide = 1
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
can_collar = 1
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
see_in_dark = 6
|
||||
maxHealth = 5
|
||||
health = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "stamps on the"
|
||||
@@ -25,12 +24,13 @@
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
var/mouse_color //brown, gray and white, leave blank for random
|
||||
layer = MOB_LAYER
|
||||
min_oxy = 16 //Require atleast 16kPA oxygen
|
||||
atmos_requirements = list("min_oxy" = 16, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 223 //Below -50 Degrees Celcius
|
||||
maxbodytemp = 323 //Above 50 Degrees Celcius
|
||||
universal_speak = 0
|
||||
can_hide = 1
|
||||
holder_type = /obj/item/weapon/holder/mouse
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/mouse/handle_automated_speech()
|
||||
..()
|
||||
@@ -40,14 +40,7 @@
|
||||
|
||||
/mob/living/simple_animal/mouse/Life()
|
||||
. = ..()
|
||||
|
||||
if(!ckey && stat == CONSCIOUS && prob(0.5))
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]_sleep"
|
||||
wander = 0
|
||||
speak_chance = 0
|
||||
//snuffles
|
||||
else if(stat == UNCONSCIOUS)
|
||||
if(stat == UNCONSCIOUS)
|
||||
if(ckey || prob(1))
|
||||
stat = CONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]"
|
||||
@@ -55,6 +48,15 @@
|
||||
else if(prob(5))
|
||||
emote("snuffles")
|
||||
|
||||
/mob/living/simple_animal/mouse/process_ai()
|
||||
..()
|
||||
|
||||
if(prob(0.5))
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "mouse_[mouse_color]_sleep"
|
||||
wander = 0
|
||||
speak_chance = 0
|
||||
|
||||
/mob/living/simple_animal/mouse/New()
|
||||
..()
|
||||
if(!mouse_color)
|
||||
|
||||
@@ -1,22 +1,8 @@
|
||||
/mob/living/simple_animal/pet
|
||||
icon = 'icons/mob/pets.dmi'
|
||||
var/obj/item/clothing/accessory/petcollar/pcollar = null
|
||||
var/image/collar = null
|
||||
var/image/pettag = null
|
||||
can_collar = 1
|
||||
|
||||
/mob/living/simple_animal/pet/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(istype(O, /obj/item/clothing/accessory/petcollar) && !pcollar)
|
||||
var/obj/item/clothing/accessory/petcollar/P = O
|
||||
pcollar = P
|
||||
collar = image('icons/mob/pets.dmi', src, "[icon_state]collar")
|
||||
pettag = image('icons/mob/pets.dmi', src, "[icon_state]tag")
|
||||
regenerate_icons()
|
||||
user << "<span class='notice'>You put the [P] around [src]'s neck.</span>"
|
||||
if(P.tagname)
|
||||
name = P.tagname
|
||||
real_name = P.tagname
|
||||
qdel(P)
|
||||
return
|
||||
if(istype(O, /obj/item/weapon/newspaper))
|
||||
if(!stat)
|
||||
user.visible_message("[user] baps [name] on the nose with the rolled up [O].")
|
||||
@@ -27,12 +13,6 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/New()
|
||||
..()
|
||||
if(pcollar)
|
||||
pcollar = new(src)
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/revive()
|
||||
..()
|
||||
regenerate_icons()
|
||||
@@ -41,7 +21,9 @@
|
||||
..()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/regenerate_icons()
|
||||
overlays.Cut()
|
||||
overlays += collar
|
||||
overlays += pettag
|
||||
/mob/living/simple_animal/pet/regenerate_icons(cut_overlays = 1)
|
||||
if(cut_overlays)
|
||||
overlays.Cut()
|
||||
if(collar)
|
||||
overlays += "[icon_state]collar"
|
||||
overlays += "[icon_state]tag"
|
||||
@@ -12,17 +12,16 @@
|
||||
emote_see = list("shakes its head.", "chases its tail.","shivers.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/pug
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/pug = 3)
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
see_in_dark = 5
|
||||
|
||||
/mob/living/simple_animal/pet/pug/Life()
|
||||
/mob/living/simple_animal/pet/pug/process_ai()
|
||||
..()
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("chases its tail."))
|
||||
spawn(0)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/mob/living/simple_animal/spiderbot
|
||||
|
||||
min_oxy = 0
|
||||
max_tox = 0
|
||||
max_co2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 500
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
turns_per_move = 5
|
||||
maxHealth = 15
|
||||
health = 15
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/tomatomeat = 3)
|
||||
response_help = "prods the"
|
||||
response_disarm = "pushes aside the"
|
||||
response_harm = "smacks the"
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
response_disarm = "shoves the"
|
||||
response_harm = "hits the"
|
||||
speed = 0
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/xenomeat = 3)
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
harm_intent_damage = 5
|
||||
@@ -21,14 +20,7 @@
|
||||
speak_emote = list("hisses")
|
||||
a_intent = I_HARM
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
var/dead = 0
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("alien")
|
||||
@@ -50,14 +42,16 @@
|
||||
var/plant_cooldown = 30
|
||||
var/plants_off = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/drone/Life()
|
||||
..()
|
||||
if(!stat)
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
/mob/living/simple_animal/hostile/alien/drone/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/sentinel
|
||||
name = "alien sentinel"
|
||||
@@ -95,18 +89,18 @@
|
||||
var/egg_cooldown = 30
|
||||
var/plant_cooldown = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/Life()
|
||||
/mob/living/simple_animal/hostile/alien/queen/process_ai()
|
||||
..()
|
||||
if(!stat)
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
if(!sterile && prob(10) && egg_cooldown<=0)
|
||||
egg_cooldown = initial(egg_cooldown)
|
||||
LayEggs()
|
||||
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
if(!sterile && prob(10) && egg_cooldown<=0)
|
||||
egg_cooldown = initial(egg_cooldown)
|
||||
LayEggs()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/proc/SpreadPlants()
|
||||
if(!isturf(loc) || istype(loc, /turf/space))
|
||||
@@ -145,3 +139,25 @@
|
||||
dead = 1
|
||||
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
|
||||
playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/maid
|
||||
name = "lusty xenomorph maid"
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
a_intent = "help"
|
||||
friendly = "caresses"
|
||||
environment_smash = 0
|
||||
icon_state = "maid"
|
||||
icon_living = "maid"
|
||||
icon_dead = "maid_dead"
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
|
||||
if(istype(target, /atom/movable))
|
||||
if(istype(target, /obj/effect/decal/cleanable))
|
||||
visible_message("<span class='notice'>\The [src] cleans up \the [target].</span>")
|
||||
qdel(target)
|
||||
return
|
||||
var/atom/movable/M = target
|
||||
M.clean_blood()
|
||||
visible_message("<span class='notice'>\The [src] polishes \the [target].</span>")
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
icon_gib = "bat_dead"
|
||||
speak_chance = 0
|
||||
turns_per_move = 3
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 1)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
@@ -23,15 +22,7 @@
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
// break_stuff_probability = 2
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
|
||||
meat_amount = 5
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/bearmeat = 5, /obj/item/clothing/head/bearpelt = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
@@ -27,14 +26,7 @@
|
||||
attack_sound = 'sound/weapons/genhit3.ogg'
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
var/stance_step = 0
|
||||
|
||||
@@ -56,12 +48,11 @@
|
||||
else
|
||||
icon_state = "bearfloor"
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Life()
|
||||
/mob/living/simple_animal/hostile/bear/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
|
||||
switch(stance)
|
||||
|
||||
if(HOSTILE_STANCE_TIRED)
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
icon_gib = "carp_gib"
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
|
||||
meat_amount = 2
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/carpmeat = 2)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
@@ -26,14 +25,7 @@
|
||||
speak_emote = list("gnashes")
|
||||
|
||||
//Space carp aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 1500
|
||||
|
||||
|
||||
@@ -20,14 +20,7 @@
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
speak_emote = list("growls")
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
speed = 4
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
speak_chance = 5
|
||||
turns_per_move = 5
|
||||
see_in_dark = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/spidermeat
|
||||
meat_amount = 2
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/spidermeat = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
@@ -57,8 +56,8 @@
|
||||
icon_state = "nurse"
|
||||
icon_living = "nurse"
|
||||
icon_dead = "nurse_dead"
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/spidereggs
|
||||
meat_amount = 4
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/spidermeat = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8, /obj/item/weapon/reagent_containers/food/snacks/spidereggs = 4)
|
||||
|
||||
maxHealth = 40
|
||||
health = 40
|
||||
melee_damage_lower = 5
|
||||
@@ -95,19 +94,6 @@
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
|
||||
// Chops off each leg with a 50/50 chance of harvesting one, until finally calling
|
||||
// default harvest action
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/harvest()
|
||||
if(butcher_state > 0)
|
||||
butcher_state--
|
||||
icon_state = icon_dead + "[butcher_state]"
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/spiderleg(src.loc)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(var/C)
|
||||
spawn(100)
|
||||
if(busy == MOVING_TO_TARGET)
|
||||
|
||||
@@ -18,14 +18,7 @@
|
||||
projectilesound = 'sound/weapons/Gunshot.ogg'
|
||||
projectiletype = /obj/item/projectile/hivebotbullet
|
||||
faction = list("hivebot")
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
speak_emote = list("states")
|
||||
|
||||
@@ -79,37 +72,36 @@
|
||||
warpbots()
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.start()
|
||||
visible_message("\red <B>The [src] warps in!</B>")
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/New()
|
||||
..()
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.start()
|
||||
visible_message("\red <B>The [src] warps in!</B>")
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
|
||||
|
||||
warpbots()
|
||||
icon_state = "def_radar"
|
||||
visible_message("\red The [src] turns on!")
|
||||
while(bot_amt > 0)
|
||||
bot_amt--
|
||||
switch(bot_type)
|
||||
if("norm")
|
||||
var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
|
||||
H.faction = faction
|
||||
if("range")
|
||||
var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
|
||||
R.faction = faction
|
||||
if("rapid")
|
||||
var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
|
||||
F.faction = faction
|
||||
spawn(100)
|
||||
qdel(src)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/warpbots()
|
||||
icon_state = "def_radar"
|
||||
visible_message("\red The [src] turns on!")
|
||||
while(bot_amt > 0)
|
||||
bot_amt--
|
||||
switch(bot_type)
|
||||
if("norm")
|
||||
var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
|
||||
H.faction = faction
|
||||
if("range")
|
||||
var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
|
||||
R.faction = faction
|
||||
if("rapid")
|
||||
var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
|
||||
F.faction = faction
|
||||
spawn(100)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
|
||||
Life()
|
||||
..()
|
||||
if(stat == 0)
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
@@ -32,33 +32,34 @@
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
|
||||
. = ..()
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
if(client)
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/process_ai()
|
||||
..()
|
||||
if(!AICanContinue())
|
||||
return 0
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
icon_gib = "panther_dead"
|
||||
speak_chance = 0
|
||||
turns_per_move = 3
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 3
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 3)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
@@ -72,8 +71,7 @@
|
||||
icon_gib = "snake_dead"
|
||||
speak_chance = 0
|
||||
turns_per_move = 1
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
meat_amount = 2
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 2)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
|
||||
@@ -23,14 +23,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
speak_emote = list("creaks")
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("mimic")
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/
|
||||
vision_range = 2
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("mining")
|
||||
environment_smash = 2
|
||||
@@ -387,7 +380,7 @@
|
||||
anchored = 1 //Stays anchored until death as to be unpullable
|
||||
var/pre_attack = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/process_ai()
|
||||
..()
|
||||
handle_preattack()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
turns_per_move = 1
|
||||
maxHealth = 10
|
||||
health = 10
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "whacks"
|
||||
|
||||
@@ -19,14 +19,7 @@
|
||||
attacktext = "slashes"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
speak_emote = list("yarrs")
|
||||
var/corpse = /obj/effect/landmark/mobcorpse/pirate
|
||||
|
||||
@@ -22,14 +22,7 @@
|
||||
flying = 1
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(var/check_drift = 0)
|
||||
|
||||
@@ -23,15 +23,6 @@
|
||||
attacktext = "attacks"
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
environment_smash = 0
|
||||
|
||||
min_oxy = 5
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 1
|
||||
min_co2 = 0
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 270
|
||||
maxbodytemp = 370
|
||||
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
|
||||
@@ -35,14 +35,7 @@
|
||||
var/exploding = 0
|
||||
|
||||
//Drones aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
var/has_loot = 1
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
icon_gib = "carp_gib"
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
|
||||
meat_amount = 1
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/carpmeat = 1)
|
||||
response_help = "pets the"
|
||||
response_disarm = "gently pushes aside the"
|
||||
response_harm = "hits the"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user