mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-20 03:26:37 +01:00
Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into clickcooldown
Conflicts: code/_onclick/click.dm code/_onclick/telekinesis.dm code/game/objects/items.dm code/game/objects/structures/grille.dm code/game/turfs/simulated/walls.dm code/modules/mob/living/carbon/resist.dm code/modules/mob/living/simple_animal/simple_animal.dm
This commit is contained in:
@@ -58,7 +58,7 @@ proc/admin_notice(var/message, var/rights)
|
||||
<a href='?src=\ref[src];traitor=\ref[M]'>TP</a> -
|
||||
<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a> -
|
||||
<a href='?src=\ref[src];subtlemessage=\ref[M]'>SM</a> -
|
||||
<a href='?src=\ref[src];adminplayerobservejump=\ref[M]'>JMP</a>\] </b><br>
|
||||
[admin_jump_link(M, src)]\] </b><br>
|
||||
<b>Mob type</b> = [M.type]<br><br>
|
||||
<A href='?src=\ref[src];boot2=\ref[M]'>Kick</A> |
|
||||
<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> |
|
||||
@@ -1164,7 +1164,7 @@ proc/admin_notice(var/message, var/rights)
|
||||
out += "<b>Core antag id:</b> <a href='?src=\ref[ticker.mode];debug_antag=[ticker.mode.antag_tag]'>[ticker.mode.antag_tag]</a>.</br>"
|
||||
|
||||
if(ticker.mode.round_autoantag)
|
||||
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.antag_prob]% spawn chance)"
|
||||
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.get_antag_prob()]% spawn chance)"
|
||||
if(ticker.mode.antag_scaling_coeff)
|
||||
out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)"
|
||||
out += "<br/>"
|
||||
@@ -1306,15 +1306,15 @@ proc/admin_notice(var/message, var/rights)
|
||||
|
||||
if(2) //Admins
|
||||
var/ref_mob = "\ref[M]"
|
||||
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)</b>"
|
||||
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)</b>"
|
||||
|
||||
if(3) //Devs
|
||||
var/ref_mob = "\ref[M]"
|
||||
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>)(<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>)</b>"
|
||||
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>)([admin_jump_link(M, src)])</b>"
|
||||
|
||||
if(4) //Mentors
|
||||
var/ref_mob = "\ref[M]"
|
||||
return "<b>[key_name(C, link, name, highlight_special)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>)</b>"
|
||||
return "<b>[key_name(C, link, name, highlight_special)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)])</b>"
|
||||
|
||||
|
||||
/proc/ishost(whom)
|
||||
|
||||
@@ -177,6 +177,10 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/toggledebuglogs,
|
||||
/client/proc/SDQL_query,
|
||||
/client/proc/SDQL2_query,
|
||||
/client/proc/Jump,
|
||||
/client/proc/jumptomob,
|
||||
/client/proc/jumptocoord,
|
||||
/client/proc/dsay
|
||||
)
|
||||
|
||||
var/list/admin_verbs_paranoid_debug = list(
|
||||
@@ -735,7 +739,7 @@ var/list/admin_verbs_mentor = list(
|
||||
var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in silicon_mob_list
|
||||
if(!S) return
|
||||
|
||||
var/obj/nano_module/law_manager/L = new(S)
|
||||
var/datum/nano_module/law_manager/L = new(S)
|
||||
L.ui_interact(usr, state = admin_state)
|
||||
admin_log_and_message_admins("has opened [S]'s law manager.")
|
||||
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -27,26 +27,6 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
|
||||
return
|
||||
|
||||
|
||||
//handles adding notes to the end of a ckey's buffer
|
||||
//originally had seperate entries such as var/by to record who left the note and when
|
||||
//but the current bansystem is a heap of dung.
|
||||
/proc/notes_add(var/ckey, var/note)
|
||||
if(!ckey)
|
||||
ckey = ckey(input(usr,"Who would you like to add notes for?","Enter a ckey",null) as text|null)
|
||||
if(!ckey) return
|
||||
|
||||
if(!note)
|
||||
note = html_encode(input(usr,"Enter your note:","Enter some text",null) as message|null)
|
||||
if(!note) return
|
||||
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return
|
||||
notesfile.cd = "/[ckey]"
|
||||
notesfile.eof = 1 //move to the end of the buffer
|
||||
notesfile << "[time2text(world.realtime,"DD-MMM-YYYY")] | [note][(usr && usr.ckey)?" ~[usr.ckey]":""]"
|
||||
return
|
||||
|
||||
//handles removing entries from the buffer, or removing the entire directory if no start_index is given
|
||||
/proc/notes_remove(var/ckey, var/start_index, var/end_index)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
@@ -85,7 +65,7 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
|
||||
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
|
||||
|
||||
/proc/notes_add(var/key, var/note, var/mob/usr)
|
||||
/proc/notes_add(var/key, var/note, var/mob/user)
|
||||
if (!key || !note)
|
||||
return
|
||||
|
||||
@@ -111,9 +91,9 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
|
||||
|
||||
var/datum/player_info/P = new
|
||||
if (usr)
|
||||
P.author = usr.key
|
||||
P.rank = usr.client.holder.rank
|
||||
if (user)
|
||||
P.author = user.key
|
||||
P.rank = user.client.holder.rank
|
||||
else
|
||||
P.author = "Adminbot"
|
||||
P.rank = "Friendly Robot"
|
||||
@@ -123,8 +103,8 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
infos += P
|
||||
info << infos
|
||||
|
||||
message_admins("\blue [key_name_admin(usr)] has edited [key]'s notes.")
|
||||
log_admin("[key_name(usr)] has edited [key]'s notes.")
|
||||
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
|
||||
log_admin("[key_name(user)] has edited [key]'s notes.")
|
||||
|
||||
qdel(info)
|
||||
|
||||
|
||||
@@ -410,43 +410,11 @@
|
||||
dat += "Launching now..."
|
||||
|
||||
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
|
||||
|
||||
//todo
|
||||
|
||||
dat += "<hr>"
|
||||
for(var/antag_type in all_antag_types)
|
||||
var/datum/antagonist/A = all_antag_types[antag_type]
|
||||
dat += A.get_check_antag_output(src)
|
||||
dat += "</body></html>"
|
||||
usr << browse(dat, "window=roundstatus;size=400x500")
|
||||
else
|
||||
alert("The game hasn't started yet!")
|
||||
|
||||
/proc/check_role_table(name, list/members, admins, show_objectives=1)
|
||||
var/txt = "<br><table cellspacing=5><tr><td><b>[name]</b></td><td></td></tr>"
|
||||
for(var/datum/mind/M in members)
|
||||
txt += check_role_table_row(M.current, admins, show_objectives)
|
||||
txt += "</table>"
|
||||
return txt
|
||||
|
||||
/proc/check_role_table_row(mob/M, admins=src, show_objectives)
|
||||
if (!istype(M))
|
||||
return "<tr><td><i>Not found!</i></td></tr>"
|
||||
|
||||
var/txt = {"
|
||||
<tr>
|
||||
<td>
|
||||
<a href='?src=\ref[admins];adminplayeropts=\ref[M]'>[M.real_name]</a>
|
||||
[M.client ? "" : " <i>(logged out)</i>"]
|
||||
[M.is_dead() ? " <b><font color='red'>(DEAD)</font></b>" : ""]
|
||||
</td>
|
||||
<td>
|
||||
<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>
|
||||
</td>
|
||||
"}
|
||||
|
||||
if (show_objectives)
|
||||
txt += {"
|
||||
<td>
|
||||
<a href='?src=\ref[admins];traitor=\ref[M]'>Show Objective</a>
|
||||
</td>
|
||||
"}
|
||||
|
||||
txt += "</tr>"
|
||||
return txt
|
||||
|
||||
+32
-25
@@ -85,6 +85,7 @@
|
||||
banreason = "[banreason] (CUSTOM CID)"
|
||||
else
|
||||
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob")
|
||||
notes_add(playermob.ckey,banreason,usr)
|
||||
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
|
||||
|
||||
@@ -671,7 +672,7 @@
|
||||
msg = job
|
||||
else
|
||||
msg += ", [job]"
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]")
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
|
||||
message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes", 1)
|
||||
M << "\red<BIG><B>You have been jobbanned by [usr.client.ckey] from: [msg].</B></BIG>"
|
||||
M << "\red <B>The reason is: [reason]</B>"
|
||||
@@ -692,7 +693,7 @@
|
||||
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
|
||||
if(!msg) msg = job
|
||||
else msg += ", [job]"
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]")
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
|
||||
message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
|
||||
M << "\red<BIG><B>You have been jobbanned by [usr.client.ckey] from: [msg].</B></BIG>"
|
||||
M << "\red <B>The reason is: [reason]</B>"
|
||||
@@ -746,25 +747,7 @@
|
||||
message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1)
|
||||
//M.client = null
|
||||
qdel(M.client)
|
||||
/*
|
||||
//Player Notes
|
||||
else if(href_list["notes"])
|
||||
var/ckey = href_list["ckey"]
|
||||
if(!ckey)
|
||||
var/mob/M = locate(href_list["mob"])
|
||||
if(ismob(M))
|
||||
ckey = M.ckey
|
||||
|
||||
switch(href_list["notes"])
|
||||
if("show")
|
||||
notes_show(ckey)
|
||||
if("add")
|
||||
notes_add(ckey,href_list["text"])
|
||||
notes_show(ckey)
|
||||
if("remove")
|
||||
notes_remove(ckey,text2num(href_list["from"]),text2num(href_list["to"]))
|
||||
notes_show(ckey)
|
||||
*/
|
||||
else if(href_list["removejobban"])
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
@@ -799,6 +782,7 @@
|
||||
return
|
||||
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
|
||||
ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.")
|
||||
notes_add(M.ckey,"[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.",usr)
|
||||
M << "\red<BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG>"
|
||||
M << "\red This is a temporary ban, it will be removed in [mins] minutes."
|
||||
feedback_inc("ban_tmp",1)
|
||||
@@ -831,6 +815,7 @@
|
||||
else
|
||||
M << "\red No ban appeals URL has been set."
|
||||
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
|
||||
notes_add(M.ckey,"[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.",usr)
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
feedback_inc("ban_perma",1)
|
||||
@@ -1247,7 +1232,7 @@
|
||||
src.owner << "Name = <b>[M.name]</b>; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = <b>[M.key]</b>;"
|
||||
src.owner << "Location = [location_description];"
|
||||
src.owner << "[special_role_description]"
|
||||
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) (<A HREF='?src=\ref[src];adminplayerobservejump=\ref[M]'>JMP</A>) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
|
||||
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
|
||||
|
||||
else if(href_list["adminspawncookie"])
|
||||
if(!check_rights(R_ADMIN|R_FUN)) return
|
||||
@@ -1749,13 +1734,13 @@
|
||||
feedback_add_details("admin_secrets_fun_used","Aliens")
|
||||
log_admin("[key_name(usr)] spawned an alien infestation", 1)
|
||||
message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1)
|
||||
xenomorphs.random_spawn()
|
||||
xenomorphs.attempt_random_spawn()
|
||||
if("borers")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","Borers")
|
||||
log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1)
|
||||
message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1)
|
||||
borers.random_spawn()
|
||||
borers.attempt_random_spawn()
|
||||
|
||||
if("power")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
@@ -2061,7 +2046,7 @@
|
||||
if("aliens")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","AL")
|
||||
if(xenomorphs.random_spawn())
|
||||
if(xenomorphs.attempt_random_spawn())
|
||||
message_admins("[key_name_admin(usr)] has spawned aliens", 1)
|
||||
if("spiders")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
@@ -2659,4 +2644,26 @@ mob/living/carbon/human/can_centcom_reply()
|
||||
return istype(l_ear, /obj/item/device/radio/headset) || istype(r_ear, /obj/item/device/radio/headset)
|
||||
|
||||
mob/living/silicon/ai/can_centcom_reply()
|
||||
return common_radio != null && !check_unable(2)
|
||||
return common_radio != null && !check_unable(2)
|
||||
|
||||
/atom/proc/extra_admin_link()
|
||||
return
|
||||
|
||||
/mob/extra_admin_link(var/source)
|
||||
if(client && eyeobj)
|
||||
return "|<A HREF='?[source];adminplayerobservejump=\ref[eyeobj]'>EYE</A>"
|
||||
|
||||
/mob/dead/observer/extra_admin_link(var/source)
|
||||
if(mind && mind.current)
|
||||
return "|<A HREF='?[source];adminplayerobservejump=\ref[mind.current]'>BDY</A>"
|
||||
|
||||
/proc/admin_jump_link(var/atom/target, var/source)
|
||||
if(!target) return
|
||||
// The way admin jump links handle their src is weirdly inconsistent...
|
||||
if(istype(source, /datum/admins))
|
||||
source = "src=\ref[source]"
|
||||
else
|
||||
source = "_src_=holder"
|
||||
|
||||
. = "<A HREF='?[source];adminplayerobservejump=\ref[target]'>JMP</A>"
|
||||
. += target.extra_admin_link(source)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
/mob/proc/on_mob_jump()
|
||||
return
|
||||
|
||||
/mob/dead/observer/on_mob_jump()
|
||||
following = null
|
||||
|
||||
/client/proc/Jump(var/area/A in return_sorted_areas())
|
||||
set name = "Jump to Area"
|
||||
set desc = "Area to jump to"
|
||||
set category = "Admin"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = pick(get_area_turfs(A))
|
||||
|
||||
log_admin("[key_name(usr)] jumped to [A]")
|
||||
@@ -18,12 +24,12 @@
|
||||
/client/proc/jumptoturf(var/turf/T in world)
|
||||
set name = "Jump to Turf"
|
||||
set category = "Admin"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
if(config.allow_admin_jump)
|
||||
log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]", 1)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = T
|
||||
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -34,8 +40,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Mob"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -46,6 +51,7 @@
|
||||
var/turf/T = get_turf(M)
|
||||
if(T && isturf(T))
|
||||
feedback_add_details("admin_verb","JM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
A.on_mob_jump()
|
||||
A.loc = T
|
||||
else
|
||||
A << "This mob is not located in the game world."
|
||||
@@ -56,13 +62,13 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Coordinate"
|
||||
|
||||
if (!holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if (config.allow_admin_jump)
|
||||
if(src.mob)
|
||||
var/mob/A = src.mob
|
||||
A.on_mob_jump()
|
||||
A.x = tx
|
||||
A.y = ty
|
||||
A.z = tz
|
||||
@@ -76,8 +82,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Key"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -91,6 +96,7 @@
|
||||
var/mob/M = selection:mob
|
||||
log_admin("[key_name(usr)] jumped to [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = M.loc
|
||||
feedback_add_details("admin_verb","JK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -100,12 +106,12 @@
|
||||
set category = "Admin"
|
||||
set name = "Get Mob"
|
||||
set desc = "Mob to teleport"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
if(config.allow_admin_jump)
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -116,8 +122,7 @@
|
||||
set name = "Get Key"
|
||||
set desc = "Key to teleport"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -134,6 +139,7 @@
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1)
|
||||
if(M)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
feedback_add_details("admin_verb","GK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -142,16 +148,16 @@
|
||||
/client/proc/sendmob(var/mob/M in sortmobs())
|
||||
set category = "Admin"
|
||||
set name = "Send Mob"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
var/area/A = input(usr, "Pick an area.", "Pick an area") in return_sorted_areas()
|
||||
if(A)
|
||||
if(config.allow_admin_jump)
|
||||
M.on_mob_jump()
|
||||
M.loc = pick(get_area_turfs(A))
|
||||
feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]", 1)
|
||||
else
|
||||
alert("Admin jumping disabled")
|
||||
alert("Admin jumping disabled")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
if(check_rights(R_ADMIN,0))
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>(<a href='?_src_=holder;adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
|
||||
C << "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>([admin_jump_link(mob, src)]): <span class='message'>[msg]</span></span>"
|
||||
|
||||
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
sender_name = "<span class='admin'>[sender_name]</span>"
|
||||
for(var/client/C in admins)
|
||||
C << "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>(<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
|
||||
C << "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>"
|
||||
|
||||
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -18,16 +18,7 @@
|
||||
if (src.handle_spam_prevention(msg,MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
var/stafftype = null
|
||||
|
||||
if (src.holder.rights & R_MOD)
|
||||
stafftype = "MOD"
|
||||
|
||||
if (src.holder.rights & R_MENTOR)
|
||||
stafftype = "MENTOR"
|
||||
|
||||
if (src.holder.rights & R_ADMIN)
|
||||
stafftype = "ADMIN"
|
||||
var/stafftype = uppertext(holder.rank)
|
||||
|
||||
msg = sanitize(msg)
|
||||
log_admin("[key_name(src)] : [msg]")
|
||||
|
||||
@@ -641,13 +641,13 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_r_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_l_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/plasteel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
M.equip_to_slot_or_del(new /obj/item/stack/tile/steel(M), slot_in_backpack)
|
||||
|
||||
if ("pirate")
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
|
||||
|
||||
@@ -111,11 +111,10 @@ proc/Icarus_FireCannon(var/turf/target)
|
||||
target = locate(x, y, target.z)
|
||||
|
||||
// Finally fire the fucker.
|
||||
var/obj/effect/meteor/small/projectile = new (start)
|
||||
var/obj/effect/meteor/projectile = new (start)
|
||||
projectile.dest = target
|
||||
projectile.name = "main gun projectile" // stealthy
|
||||
projectile.hits = 6
|
||||
projectile.detonation_chance = 99 // it's a missile/cannon round thing!
|
||||
|
||||
// Make sure it travels
|
||||
spawn(0)
|
||||
|
||||
@@ -4,6 +4,10 @@ var/list/forbidden_varedit_object_types = list(
|
||||
/datum/feedback_variable //Prevents people messing with feedback gathering
|
||||
)
|
||||
|
||||
var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "bound_x", "bound_y", "step_x", "step_y", "force_ending")
|
||||
var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays")
|
||||
var/list/VVckey_edit = list("key", "ckey")
|
||||
|
||||
/*
|
||||
/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world)
|
||||
set category = "Debug"
|
||||
@@ -44,7 +48,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("text")
|
||||
var_value = input("Enter new text:","Text") as null|text//todo: sanitize ???
|
||||
var_value = input("Enter new text:","Text") as null|text
|
||||
|
||||
if("num")
|
||||
var_value = input("Enter new number:","Num") as null|num
|
||||
@@ -72,7 +76,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
return var_value
|
||||
|
||||
|
||||
/client/proc/mod_list_add(var/list/L)
|
||||
/client/proc/mod_list_add(var/list/L, atom/O, original_name, objectvar)
|
||||
|
||||
var/class = "text"
|
||||
if(src.holder && src.holder.marked_datum)
|
||||
@@ -93,7 +97,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("text")
|
||||
var_value = input("Enter new text:","Text") as text//todo: sanitize ???
|
||||
var_value = input("Enter new text:","Text") as text
|
||||
|
||||
if("num")
|
||||
var_value = input("Enter new number:","Num") as num
|
||||
@@ -124,30 +128,58 @@ var/list/forbidden_varedit_object_types = list(
|
||||
L[var_value] = mod_list_add_ass() //haha
|
||||
if("No")
|
||||
L += var_value
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: ADDED=[var_value]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
|
||||
/client/proc/mod_list(var/list/L)
|
||||
/client/proc/mod_list(var/list/L, atom/O, original_name, objectvar)
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
if(!istype(L,/list)) src << "Not a List."
|
||||
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state")
|
||||
var/list/names = sortList(L)
|
||||
if(L.len > 1000)
|
||||
var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort")
|
||||
if(confirm != "Continue")
|
||||
return
|
||||
|
||||
var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)"
|
||||
var/assoc = 0
|
||||
if(L.len > 0)
|
||||
var/a = L[1]
|
||||
if(istext(a) && L[a] != null)
|
||||
assoc = 1 //This is pretty weak test but i can't think of anything else
|
||||
usr << "List appears to be associative."
|
||||
|
||||
var/list/names = null
|
||||
if(!assoc)
|
||||
names = sortList(L)
|
||||
|
||||
var/variable
|
||||
var/assoc_key
|
||||
if(assoc)
|
||||
variable = input("Which var?","Var") as null|anything in L + "(ADD VAR)"
|
||||
else
|
||||
variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)"
|
||||
|
||||
if(variable == "(ADD VAR)")
|
||||
mod_list_add(L)
|
||||
mod_list_add(L, O, original_name, objectvar)
|
||||
return
|
||||
|
||||
if(!variable)
|
||||
if(assoc)
|
||||
assoc_key = variable
|
||||
variable = L[assoc_key]
|
||||
|
||||
if(!assoc && !variable || assoc && !assoc_key)
|
||||
return
|
||||
|
||||
var/default
|
||||
|
||||
var/dir
|
||||
|
||||
if(variable in locked)
|
||||
if(variable in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(variable in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
if(isnull(variable))
|
||||
usr << "Unable to determine variable type."
|
||||
@@ -212,14 +244,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
usr << "If a direction, direction is: [dir]"
|
||||
|
||||
var/class = "text"
|
||||
var/list/choices = list("text","num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
|
||||
if(src.holder && src.holder.marked_datum)
|
||||
choices += "marked datum ([holder.marked_datum.type])"
|
||||
if(!isnull(default) && default != "num")
|
||||
choices += "edit associated variable"
|
||||
choices += "DELETE FROM LIST"
|
||||
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in choices
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
|
||||
"num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST")
|
||||
else
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
|
||||
"num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST")
|
||||
|
||||
if(!class)
|
||||
return
|
||||
@@ -227,61 +257,107 @@ var/list/forbidden_varedit_object_types = list(
|
||||
if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
|
||||
class = "marked datum"
|
||||
|
||||
var/original_var
|
||||
if(assoc)
|
||||
original_var = L[assoc_key]
|
||||
else
|
||||
original_var = L[L.Find(variable)]
|
||||
|
||||
var/new_var
|
||||
switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet.
|
||||
|
||||
if("list")
|
||||
mod_list(variable)
|
||||
mod_list(variable, O, original_name, objectvar)
|
||||
|
||||
if("restore to default")
|
||||
L[L.Find(variable)]=initial(variable)
|
||||
new_var = initial(variable)
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("edit referenced object")
|
||||
modify_variables(variable)
|
||||
|
||||
if("DELETE FROM LIST")
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[variable]")]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]")
|
||||
L -= variable
|
||||
return
|
||||
|
||||
if("text")
|
||||
L[L.Find(variable)] = input("Enter new text:","Text") as text//todo: sanitize ???
|
||||
new_var = input("Enter new text:","Text") as text
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("num")
|
||||
L[L.Find(variable)] = input("Enter new number:","Num") as num
|
||||
new_var = input("Enter new number:","Num") as num
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("type")
|
||||
L[L.Find(variable)] = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
|
||||
new_var = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("reference")
|
||||
L[L.Find(variable)] = input("Select reference:","Reference") as mob|obj|turf|area in world
|
||||
new_var = input("Select reference:","Reference") as mob|obj|turf|area in world
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("mob reference")
|
||||
L[L.Find(variable)] = input("Select reference:","Reference") as mob in world
|
||||
new_var = input("Select reference:","Reference") as mob in world
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("file")
|
||||
L[L.Find(variable)] = input("Pick file:","File") as file
|
||||
new_var = input("Pick file:","File") as file
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("icon")
|
||||
L[L.Find(variable)] = input("Pick icon:","Icon") as icon
|
||||
new_var = input("Pick icon:","Icon") as icon
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("marked datum")
|
||||
L[L.Find(variable)] = holder.marked_datum
|
||||
|
||||
if("edit associated variable")
|
||||
var/temp_var = mod_list_add_ass()
|
||||
if(temp_var)
|
||||
L[variable] = temp_var
|
||||
new_var = holder.marked_datum
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: [original_var]=[new_var]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
|
||||
|
||||
/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state")
|
||||
|
||||
for(var/p in forbidden_varedit_object_types)
|
||||
if( istype(O,p) )
|
||||
usr << "\red It is forbidden to edit this object's variables."
|
||||
usr << "<span class='danger'>It is forbidden to edit this object's variables.</span>"
|
||||
return
|
||||
|
||||
if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key"))
|
||||
usr << "<span class='danger'>You cannot edit ckeys on client objects.</span>"
|
||||
return
|
||||
|
||||
var/class
|
||||
var/variable
|
||||
var/var_value
|
||||
@@ -291,8 +367,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])"
|
||||
return
|
||||
|
||||
if(param_var_name == "holder" || (param_var_name in locked))
|
||||
if(param_var_name in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(param_var_name in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(param_var_name in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
variable = param_var_name
|
||||
|
||||
@@ -349,8 +429,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
if(!variable) return
|
||||
var_value = O.vars[variable]
|
||||
|
||||
if(variable == "holder" || (variable in locked))
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(variable in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
if(!autodetect_class)
|
||||
|
||||
@@ -440,7 +524,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("list")
|
||||
mod_list(O.vars[variable])
|
||||
mod_list(O.vars[variable], O, original_name, variable)
|
||||
return
|
||||
|
||||
if("restore to default")
|
||||
@@ -450,7 +534,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
return .(O.vars[variable])
|
||||
|
||||
if("text")
|
||||
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text//todo: sanitize ???
|
||||
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text
|
||||
if(var_new==null) return
|
||||
O.vars[variable] = var_new
|
||||
|
||||
@@ -504,5 +588,4 @@ var/list/forbidden_varedit_object_types = list(
|
||||
|
||||
world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1)
|
||||
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return
|
||||
|
||||
var/image/cross = image('icons/obj/storage.dmi',"bible")
|
||||
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
|
||||
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
@@ -29,13 +29,13 @@
|
||||
//log_admin("HELP: [key_name(src)]: [msg]")
|
||||
|
||||
/proc/Centcomm_announce(var/msg, var/mob/Sender, var/iamessage)
|
||||
msg = "\blue <b><font color=orange>CENTCOMM[iamessage ? " IA" : ""]:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
msg = "\blue <b><font color=orange>CENTCOMM[iamessage ? " IA" : ""]:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << msg
|
||||
|
||||
/proc/Syndicate_announce(var/msg, var/mob/Sender)
|
||||
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << msg
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
|
||||
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
|
||||
src << "<span class='info'>You have unread updates in the changelog.</span>"
|
||||
winset(src, "rpane.changelogb", "background-color=#eaeaea;font-style=bold")
|
||||
winset(src, "rpane.changelog", "background-color=#eaeaea;font-style=bold")
|
||||
if(config.aggressive_changelog)
|
||||
src.changes()
|
||||
|
||||
@@ -178,6 +178,25 @@
|
||||
return ..()
|
||||
|
||||
|
||||
// here because it's similar to below
|
||||
|
||||
// Returns null if no DB connection can be established, or -1 if the requested key was not found in the database
|
||||
|
||||
/proc/get_player_age(key)
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
return null
|
||||
|
||||
var/sql_ckey = sql_sanitize_text(ckey(key))
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT datediff(Now(),firstseen) as age FROM erro_player WHERE ckey = '[sql_ckey]'")
|
||||
query.Execute()
|
||||
|
||||
if(query.NextRow())
|
||||
return text2num(query.item[1])
|
||||
else
|
||||
return -1
|
||||
|
||||
|
||||
/client/proc/log_client_to_db()
|
||||
|
||||
|
||||
@@ -25,8 +25,11 @@
|
||||
action_button_name = "Flip Welding Mask"
|
||||
siemens_coefficient = 0.9
|
||||
w_class = 3
|
||||
var/base_state
|
||||
|
||||
/obj/item/clothing/head/welding/attack_self()
|
||||
if(!base_state)
|
||||
base_state = icon_state
|
||||
toggle()
|
||||
|
||||
|
||||
@@ -40,13 +43,13 @@
|
||||
src.up = !src.up
|
||||
src.flags |= (HEADCOVERSEYES | HEADCOVERSMOUTH)
|
||||
flags_inv |= (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
|
||||
icon_state = initial(icon_state)
|
||||
icon_state = base_state
|
||||
usr << "You flip the [src] down to protect your eyes."
|
||||
else
|
||||
src.up = !src.up
|
||||
src.flags &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH)
|
||||
flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
|
||||
icon_state = "[initial(icon_state)]up"
|
||||
icon_state = "[base_state]up"
|
||||
usr << "You push the [src] up out of your face."
|
||||
update_clothing_icon() //so our mob-overlays
|
||||
usr.update_action_buttons()
|
||||
@@ -138,21 +141,17 @@
|
||||
desc = "A pair of kitty ears. Meow!"
|
||||
icon_state = "kitty"
|
||||
body_parts_covered = 0
|
||||
var/icon/mob
|
||||
var/icon/mob2
|
||||
siemens_coefficient = 1.5
|
||||
item_icons = list()
|
||||
|
||||
update_icon(var/mob/living/carbon/human/user)
|
||||
if(!istype(user)) return
|
||||
mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty")
|
||||
mob2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty2")
|
||||
mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD)
|
||||
mob2.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD)
|
||||
var/icon/ears = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty")
|
||||
ears.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD)
|
||||
|
||||
var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner")
|
||||
var/icon/earbit2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner2")
|
||||
mob.Blend(earbit, ICON_OVERLAY)
|
||||
mob2.Blend(earbit2, ICON_OVERLAY)
|
||||
ears.Blend(earbit, ICON_OVERLAY)
|
||||
|
||||
|
||||
/obj/item/clothing/head/richard
|
||||
name = "chicken mask"
|
||||
|
||||
@@ -5,8 +5,17 @@
|
||||
* /obj/item/rig_module/mounted/taser
|
||||
* /obj/item/rig_module/shield
|
||||
* /obj/item/rig_module/fabricator
|
||||
* /obj/item/rig_module/device/flash
|
||||
*/
|
||||
|
||||
/obj/item/rig_module/device/flash
|
||||
name = "mounted flash"
|
||||
desc = "You are the law."
|
||||
icon_state = "flash"
|
||||
interface_name = "mounted flash"
|
||||
interface_desc = "Stuns your target by blinding them with a bright light."
|
||||
device_type = /obj/item/device/flash
|
||||
|
||||
/obj/item/rig_module/grenade_launcher
|
||||
|
||||
name = "mounted grenade launcher"
|
||||
@@ -76,7 +85,7 @@
|
||||
|
||||
charge.charges--
|
||||
var/obj/item/weapon/grenade/new_grenade = new charge.product_type(get_turf(H))
|
||||
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!")
|
||||
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!</span>")
|
||||
new_grenade.activate(H)
|
||||
new_grenade.throw_at(target,fire_force,fire_distance)
|
||||
|
||||
@@ -230,7 +239,7 @@
|
||||
firing.throw_at(target,fire_force,fire_distance)
|
||||
else
|
||||
if(H.l_hand && H.r_hand)
|
||||
H << "<span class='danger'>Your hands are full."
|
||||
H << "<span class='danger'>Your hands are full.</span>"
|
||||
else
|
||||
var/obj/item/new_weapon = new fabrication_type()
|
||||
new_weapon.loc = H
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
* /obj/item/rig_module/chem_dispenser
|
||||
* /obj/item/rig_module/chem_dispenser/injector
|
||||
* /obj/item/rig_module/voice
|
||||
* /obj/item/rig_module/device/paperdispenser
|
||||
* /obj/item/rig_module/device/pen
|
||||
* /obj/item/rig_module/device/stamp
|
||||
*/
|
||||
|
||||
/obj/item/rig_module/device
|
||||
@@ -94,7 +97,6 @@
|
||||
if(device_type) device = new device_type(src)
|
||||
|
||||
/obj/item/rig_module/device/engage(atom/target)
|
||||
|
||||
if(!..() || !device)
|
||||
return 0
|
||||
|
||||
@@ -377,4 +379,64 @@
|
||||
jets.holder = null
|
||||
jets.ion_trail.set_up(jets)
|
||||
|
||||
/obj/item/rig_module/foam_sprayer
|
||||
/obj/item/rig_module/foam_sprayer
|
||||
|
||||
/obj/item/rig_module/device/paperdispenser
|
||||
name = "hardsuit paper dispenser"
|
||||
desc = "Crisp sheets."
|
||||
icon_state = "paper"
|
||||
interface_name = "paper dispenser"
|
||||
interface_desc = "Dispenses warm, clean, and crisp sheets of paper."
|
||||
engage_string = "Dispense"
|
||||
usable = 1
|
||||
selectable = 0
|
||||
device_type = /obj/item/weapon/paper_bin
|
||||
|
||||
/obj/item/rig_module/device/paperdispenser/engage(atom/target)
|
||||
|
||||
if(!..() || !device)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
device.attack_hand(holder.wearer)
|
||||
return 1
|
||||
|
||||
/obj/item/rig_module/device/pen
|
||||
name = "mounted pen"
|
||||
desc = "For mecha John Hancocks."
|
||||
icon_state = "pen"
|
||||
interface_name = "mounted pen"
|
||||
interface_desc = "Signatures with style(tm)."
|
||||
engage_string = "Change color"
|
||||
usable = 1
|
||||
device_type = /obj/item/weapon/pen/multi
|
||||
|
||||
/obj/item/rig_module/device/stamp
|
||||
name = "mounted internal affairs stamp"
|
||||
desc = "DENIED."
|
||||
icon_state = "stamp"
|
||||
interface_name = "mounted stamp"
|
||||
interface_desc = "Leave your mark."
|
||||
engage_string = "Toggle stamp type"
|
||||
usable = 1
|
||||
var/iastamp
|
||||
var/deniedstamp
|
||||
|
||||
/obj/item/rig_module/device/stamp/New()
|
||||
..()
|
||||
iastamp = new /obj/item/weapon/stamp/internalaffairs(src)
|
||||
deniedstamp = new /obj/item/weapon/stamp/denied(src)
|
||||
device = iastamp
|
||||
|
||||
/obj/item/rig_module/device/stamp/engage(atom/target)
|
||||
if(!..() || !device)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
if(device == iastamp)
|
||||
device = deniedstamp
|
||||
holder.wearer << "<span class='notice'>Switched to denied stamp.</span>"
|
||||
else if(device == deniedstamp)
|
||||
device = iastamp
|
||||
holder.wearer << "<span class='notice'>Switched to internal affairs stamp.</span>"
|
||||
return 1
|
||||
@@ -370,7 +370,7 @@
|
||||
if(sealing)
|
||||
fail_msg = "<span class='warning'>The hardsuit is in the process of adjusting seals and cannot be activated.</span>"
|
||||
else if(!fail_msg && ((use_unconcious && user.stat > 1) || (!use_unconcious && user.stat)))
|
||||
fail_msg = "<span class='warning'>You are in no fit state to do that."
|
||||
fail_msg = "<span class='warning'>You are in no fit state to do that.</span>"
|
||||
else if(!cell)
|
||||
fail_msg = "<span class='warning'>There is no cell installed in the suit.</span>"
|
||||
else if(cost && cell.charge < cost * 10) //TODO: Cellrate?
|
||||
@@ -754,7 +754,7 @@
|
||||
|
||||
if(wearer)
|
||||
if(dam_module.damage >= 2)
|
||||
wearer << "<span class='danger'>The [source] has disabled your [dam_module.interface_name]!"
|
||||
wearer << "<span class='danger'>The [source] has disabled your [dam_module.interface_name]!</span>"
|
||||
else
|
||||
wearer << "<span class='warning'>The [source] has damaged your [dam_module.interface_name]!"
|
||||
dam_module.deactivate()
|
||||
|
||||
@@ -11,20 +11,11 @@
|
||||
return chest.attackby(W,user)
|
||||
|
||||
// Lock or unlock the access panel.
|
||||
if(istype(W, /obj/item/weapon/card) || istype(W, /obj/item/device/pda))
|
||||
|
||||
if(W.GetID())
|
||||
if(subverted)
|
||||
locked = 0
|
||||
user << "<span class='danger'>It looks like the locking system has been shorted out.</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
locked_dna = null
|
||||
req_access.Cut()
|
||||
req_one_access.Cut()
|
||||
locked = 0
|
||||
subverted = 1
|
||||
user << "<span class='danger'>You short out the access protocol for the suit.</span>"
|
||||
return
|
||||
|
||||
if((!req_access || !req_access.len) && (!req_one_access || !req_one_access.len))
|
||||
locked = 0
|
||||
@@ -193,4 +184,14 @@
|
||||
if(electrified != 0)
|
||||
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/rig/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!subverted)
|
||||
locked_dna = null
|
||||
req_access.Cut()
|
||||
req_one_access.Cut()
|
||||
locked = 0
|
||||
subverted = 1
|
||||
user << "<span class='danger'>You short out the access protocol for the suit.</span>"
|
||||
return 1
|
||||
|
||||
@@ -19,6 +19,42 @@
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list("Security")
|
||||
|
||||
/obj/item/weapon/rig/internalaffairs
|
||||
name = "augmented tie"
|
||||
suit_type = "augmented suit"
|
||||
desc = "Prepare for paperwork."
|
||||
icon_state = "internalaffairs_rig"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.9
|
||||
slowdown = 0
|
||||
offline_slowdown = 0
|
||||
offline_vision_restriction = 0
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/briefcase,/obj/item/weapon/storage/secure/briefcase)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
glove_type = null
|
||||
helm_type = null
|
||||
boot_type = null
|
||||
|
||||
/obj/item/weapon/rig/internalaffairs/equipped
|
||||
|
||||
req_access = list(access_lawyer)
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
/obj/item/rig_module/device/flash,
|
||||
/obj/item/rig_module/device/paperdispenser,
|
||||
/obj/item/rig_module/device/pen,
|
||||
/obj/item/rig_module/device/stamp
|
||||
)
|
||||
|
||||
glove_type = null
|
||||
helm_type = null
|
||||
boot_type = null
|
||||
|
||||
/obj/item/weapon/rig/industrial
|
||||
name = "industrial suit control module"
|
||||
suit_type = "industrial hardsuit"
|
||||
|
||||
@@ -83,6 +83,10 @@
|
||||
if(H.wear_suit != src)
|
||||
return
|
||||
|
||||
if(boots)
|
||||
if (H.equip_to_slot_if_possible(boots, slot_shoes))
|
||||
boots.canremove = 0
|
||||
|
||||
if(helmet)
|
||||
if(H.head)
|
||||
M << "You are unable to deploy your suit's helmet as \the [H.head] is in the way."
|
||||
@@ -90,10 +94,6 @@
|
||||
M << "Your suit's helmet deploys with a hiss."
|
||||
helmet.canremove = 0
|
||||
|
||||
if(boots)
|
||||
if (H.equip_to_slot_if_possible(boots, slot_shoes))
|
||||
boots.canremove = 0
|
||||
|
||||
if(tank)
|
||||
if(H.s_store) //In case someone finds a way.
|
||||
M << "Alarmingly, the valve on your suit's installed tank fails to engage."
|
||||
@@ -101,6 +101,7 @@
|
||||
M << "The valve on your suit's installed tank safely engages."
|
||||
tank.canremove = 0
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/void/dropped()
|
||||
..()
|
||||
|
||||
@@ -151,7 +152,7 @@
|
||||
helmet.loc = src
|
||||
else
|
||||
if(H.head)
|
||||
H << "<span class='danger'>You cannot deploy your helmet while wearing another helmet.</span>"
|
||||
H << "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>"
|
||||
return
|
||||
if(H.equip_to_slot_if_possible(helmet, slot_head))
|
||||
helmet.pickup(H)
|
||||
@@ -161,7 +162,7 @@
|
||||
|
||||
/obj/item/clothing/suit/space/void/verb/eject_tank()
|
||||
|
||||
set name = "Eject Tank"
|
||||
set name = "Eject Voidsuit Tank"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
@@ -187,22 +188,26 @@
|
||||
if(!istype(user,/mob/living)) return
|
||||
|
||||
if(istype(src.loc,/mob/living))
|
||||
user << "<span class='danger'>How do you propose to modify a hardsuit while it is being worn?</span>"
|
||||
user << "<span class='danger'>How do you propose to modify a voidsuit while it is being worn?</span>"
|
||||
return
|
||||
|
||||
if(istype(W,/obj/item/weapon/screwdriver))
|
||||
if(tank)
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
src.tank = null
|
||||
else if(helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
src.helmet = null
|
||||
else if (boots)
|
||||
user << "You detatch \the [boots] from \the [src]'s boot mounts."
|
||||
boots.loc = get_turf(src)
|
||||
src.boots = null
|
||||
if(helmet || boots || tank)
|
||||
var/choice = input("What component would you like to remove?") as null|anything in list(helmet,boots,tank)
|
||||
if(!choice) return
|
||||
|
||||
if(choice == tank) //No, a switch doesn't work here. Sorry. ~Techhead
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
src.tank = null
|
||||
else if(choice == helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
src.helmet = null
|
||||
else if(choice == boots)
|
||||
user << "You detatch \the [boots] from \the [src]'s boot mounts."
|
||||
boots.loc = get_turf(src)
|
||||
src.boots = null
|
||||
else
|
||||
user << "\The [src] does not have anything installed."
|
||||
return
|
||||
|
||||
@@ -72,12 +72,12 @@
|
||||
|
||||
if(icon_state == icon_badge)
|
||||
icon_state = icon_nobadge
|
||||
usr << "You unclip the badge from the vest."
|
||||
usr << "You conceal \the [src]'s badge."
|
||||
else if(icon_state == icon_nobadge)
|
||||
icon_state = icon_badge
|
||||
usr << "You clip the badge to the vest."
|
||||
usr << "You reveal \the [src]'s badge."
|
||||
else
|
||||
usr << "You can't find a badge for [src]."
|
||||
usr << "\The [src] does not have a vest badge."
|
||||
return
|
||||
update_clothing_icon()
|
||||
|
||||
|
||||
@@ -55,19 +55,18 @@
|
||||
user << "Waving around a holobadge before swiping an ID would be pretty pointless."
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/badge/holo/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (emagged)
|
||||
user << "<span class='danger'>\The [src] is already cracked.</span>"
|
||||
return
|
||||
else
|
||||
emagged = 1
|
||||
user << "<span class='danger'>You crack the holobadge security checks.</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/accessory/badge/holo/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
|
||||
if (istype(O, /obj/item/weapon/card/emag))
|
||||
if (emagged)
|
||||
user << "<span class='danger'>[src] is already cracked.</span>"
|
||||
return
|
||||
else
|
||||
emagged = 1
|
||||
user << "<span class='danger'>You swipe [O] and crack the holobadge security checks.</span>"
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
|
||||
if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
|
||||
|
||||
var/obj/item/weapon/card/id/id_card = null
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
else
|
||||
if(user.a_intent == I_HURT)
|
||||
usr.visible_message(
|
||||
"\red [user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='danger'>[user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='warning'>You draw \the [holstered], ready to shoot!</span>"
|
||||
)
|
||||
else
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
item_state = "paper"
|
||||
throwforce = 1
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_EARS
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
F.add_fingerprint(M)
|
||||
F.icon_state = "fingerprint1"
|
||||
F.name = text("FPrintC- '[M.name]'")
|
||||
user << "<span class='notice'>Done printing."
|
||||
user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]"
|
||||
user << "<span class='notice'>Done printing.</span>"
|
||||
user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]</span>"
|
||||
if ( M.blood_DNA && M.blood_DNA.len )
|
||||
user << "<span class='notice'>Blood found on [M]. Analysing...</span>"
|
||||
spawn(15)
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
screen = "details"
|
||||
current = files[href_list["identifier"]]
|
||||
else
|
||||
usr << "<spawn class='warning'>No record found.</span>"
|
||||
usr << "<span class='warning'>No record found.</span>"
|
||||
if("delete")
|
||||
if(href_list["identifier"])
|
||||
if(alert("Are you sure you want to delete this record?","Record deletion", "Yes", "No") == "Yes")
|
||||
@@ -265,7 +265,7 @@
|
||||
M.drop_item()
|
||||
I.loc = src
|
||||
else
|
||||
usr << "<spawn class='warning'>Invalid object, rejected.</span>"
|
||||
usr << "<span class='warning'>Invalid object, rejected.</span>"
|
||||
if("scan")
|
||||
if(scanning)
|
||||
scan_progress = 10
|
||||
@@ -279,7 +279,7 @@
|
||||
M.drop_item()
|
||||
qdel(I)
|
||||
else
|
||||
usr << "<spawn class='warning'>Invalid fingerprint card, rejected.</span>"
|
||||
usr << "<span class='warning'>Invalid fingerprint card, rejected.</span>"
|
||||
if("print")
|
||||
if(current)
|
||||
var/obj/item/weapon/paper/P = new(loc)
|
||||
|
||||
+17
-10
@@ -62,6 +62,22 @@ log transactions
|
||||
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
|
||||
break
|
||||
|
||||
/obj/machinery/atm/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!emagged)
|
||||
return
|
||||
|
||||
//short out the machine, shoot sparks, spew money!
|
||||
emagged = 1
|
||||
spark_system.start()
|
||||
spawn_money(rand(100,500),src.loc)
|
||||
//we don't want to grief people by locking their id in an emagged ATM
|
||||
release_held_id(user)
|
||||
|
||||
//display a message to the user
|
||||
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
|
||||
user << "<span class='warning'>\icon[src] The [src] beeps: \"[response]\"</span>"
|
||||
return 1
|
||||
|
||||
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/card))
|
||||
if(emagged > 0)
|
||||
@@ -69,16 +85,7 @@ log transactions
|
||||
user << "\red \icon[src] CARD READER ERROR. This system has been compromised!"
|
||||
return
|
||||
else if(istype(I,/obj/item/weapon/card/emag))
|
||||
//short out the machine, shoot sparks, spew money!
|
||||
emagged = 1
|
||||
spark_system.start()
|
||||
spawn_money(rand(100,500),src.loc)
|
||||
//we don't want to grief people by locking their id in an emagged ATM
|
||||
release_held_id(user)
|
||||
|
||||
//display a message to the user
|
||||
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
|
||||
user << "\red \icon[src] The [src] beeps: \"[response]\""
|
||||
I.resolve_attackby(src, user)
|
||||
return
|
||||
|
||||
var/obj/item/weapon/card/id/idcard = I
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "aiupload"
|
||||
density = 1
|
||||
req_one_access = list(access_hop, access_captain, access_cent_captain)
|
||||
anchored = 1
|
||||
var/receipt_num
|
||||
var/machine_id = ""
|
||||
var/obj/item/weapon/card/id/held_card
|
||||
|
||||
@@ -153,7 +153,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_SCIENTIST = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
|
||||
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, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
|
||||
@@ -168,13 +168,13 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
/datum/event_container/major
|
||||
severity = EVENT_LEVEL_MAJOR
|
||||
available_events = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
|
||||
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, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
|
||||
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, "Nothing", /datum/event/nothing, 1320),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
|
||||
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, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ var/list/event_last_fired = list()
|
||||
possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"]
|
||||
if(minutes_passed >= 30) // Give engineers time to set up engine
|
||||
possibleEvents[/datum/event/meteor_wave] = 10 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/meteor_shower] = 20 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/blob] = 10 * active_with_role["Engineer"]
|
||||
|
||||
if(active_with_role["Medical"] > 0)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in world)
|
||||
if(prob(botEmagChance))
|
||||
bot.Emag()
|
||||
bot.emag_act(1)
|
||||
|
||||
/datum/event/ionstorm/end()
|
||||
spawn(rand(5000,8000))
|
||||
|
||||
@@ -1,44 +1,39 @@
|
||||
//meteor storms are much heavier
|
||||
/datum/event/meteor_wave
|
||||
startWhen = 6
|
||||
endWhen = 33
|
||||
|
||||
/datum/event/meteor_wave/setup()
|
||||
endWhen = rand(15,30) * 3
|
||||
|
||||
/datum/event/meteor_wave/announce()
|
||||
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
|
||||
/datum/event/meteor_wave/tick()
|
||||
if(IsMultiple(activeFor, 3))
|
||||
meteor_wave(rand(2,5))
|
||||
|
||||
/datum/event/meteor_wave/end()
|
||||
command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert")
|
||||
|
||||
//
|
||||
/datum/event/meteor_shower
|
||||
startWhen = 5
|
||||
endWhen = 7
|
||||
var/next_meteor = 6
|
||||
var/waves = 1
|
||||
|
||||
/datum/event/meteor_shower/setup()
|
||||
waves = rand(2,5)
|
||||
/datum/event/meteor_wave/setup()
|
||||
waves = severity * rand(1,3)
|
||||
|
||||
/datum/event/meteor_shower/announce()
|
||||
command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert")
|
||||
/datum/event/meteor_wave/announce()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
else
|
||||
command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert")
|
||||
|
||||
//meteor showers are lighter and more common,
|
||||
/datum/event/meteor_shower/tick()
|
||||
if(activeFor >= next_meteor)
|
||||
meteor_wave(rand(1,4))
|
||||
next_meteor += rand(20,100)
|
||||
/datum/event/meteor_wave/tick()
|
||||
if(waves && activeFor >= next_meteor)
|
||||
spawn() spawn_meteors(severity * rand(1,2), get_meteors())
|
||||
next_meteor += rand(15, 30) / severity
|
||||
waves--
|
||||
if(waves <= 0)
|
||||
endWhen = activeFor + 1
|
||||
else
|
||||
endWhen = next_meteor + 1
|
||||
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
|
||||
|
||||
/datum/event/meteor_shower/end()
|
||||
command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert")
|
||||
/datum/event/meteor_wave/end()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert")
|
||||
else
|
||||
command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert")
|
||||
|
||||
/datum/event/meteor_wave/proc/get_meteors()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
return meteors_catastrophic
|
||||
if(EVENT_LEVEL_MODERATE)
|
||||
return meteors_threatening
|
||||
else
|
||||
return meteors_normal
|
||||
|
||||
@@ -44,27 +44,12 @@
|
||||
for(var/area/A in world)
|
||||
if(is_type_in_list(A,areaType) && !is_type_in_list(A,areaNotType))
|
||||
areas += A
|
||||
|
||||
if(areas && areas.len > 0)
|
||||
var/pass = 0
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
var/rc_message = "An unknown malicious program has been detected in the [english_list(areaName)] lighting and airlock control systems at [worldtime2text()]. Systems will be fully compromised within approximately three minutes. Direct intervention is required immediately.<br>"
|
||||
for(var/obj/machinery/message_server/MS in world)
|
||||
MS.send_rc_message("Engineering", my_department, rc_message, "", "", 2)
|
||||
pass = 1
|
||||
if(pass) //This entire block should be handled by send_rc_message(). I'm not rewriting it.
|
||||
var/sending = rc_message + "<font color='blue'><b>Message dispatched by [my_department].</b></font>"
|
||||
for (var/obj/machinery/requests_console/Console in allConsoles)
|
||||
var/keyed_department = ckey(Console.department)
|
||||
if(keyed_department == ckey("Engineering"))
|
||||
if(Console.newmessagepriority < 2)
|
||||
Console.newmessagepriority = 2
|
||||
Console.icon_state = "req_comp2"
|
||||
if(!Console.silent)
|
||||
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(5, Console.loc))
|
||||
O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [my_department]'"))
|
||||
Console.messages += "<B><FONT color='red'>High Priority message from [my_department]</FONT></B><BR>[sending]"
|
||||
|
||||
for(var/mob/living/silicon/ai/A in player_list)
|
||||
A << "<span class='danger'>Malicious program detected in the [english_list(areaName)] lighting and airlock control systems by [my_department].</span>"
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
valid_types |= antag
|
||||
if(valid_types.len)
|
||||
var/datum/antagonist/antag = pick(valid_types)
|
||||
antag.random_spawn()
|
||||
antag.attempt_random_spawn()
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
/proc/send2irc(var/channel, var/msg)
|
||||
if(config.use_irc_bot && config.irc_bot_host)
|
||||
if(config.use_lib_nudge)
|
||||
var/nudge_lib
|
||||
if(world.system_type == MS_WINDOWS)
|
||||
nudge_lib = "lib\\nudge.dll"
|
||||
else
|
||||
nudge_lib = "lib/nudge.so"
|
||||
|
||||
spawn(0)
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
if(config.irc_bot_export)
|
||||
world.Export("http://[config.irc_bot_host]:45678?[list2params(list(pwd=config.comms_password, chan=channel, mesg=msg))]")
|
||||
else
|
||||
spawn(0)
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
if(config.use_lib_nudge)
|
||||
var/nudge_lib
|
||||
if(world.system_type == MS_WINDOWS)
|
||||
nudge_lib = "lib\\nudge.dll"
|
||||
else
|
||||
nudge_lib = "lib/nudge.so"
|
||||
|
||||
spawn(0)
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
else
|
||||
spawn(0)
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
return
|
||||
|
||||
/proc/send2mainirc(var/msg)
|
||||
@@ -26,6 +29,6 @@
|
||||
|
||||
|
||||
/hook/startup/proc/ircNotify()
|
||||
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
|
||||
send2mainirc("Server starting up on byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -109,6 +109,6 @@ proc/populate_ghost_traps()
|
||||
/datum/ghosttrap/plant/welcome_candidate(var/mob/target)
|
||||
target << "<span class='alium><B>You awaken slowly, stirring into sluggish motion as the air caresses you.</B></span>"
|
||||
// This is a hack, replace with some kind of species blurb proc.
|
||||
if(istype(host,/mob/living/carbon/alien/diona))
|
||||
if(istype(target,/mob/living/carbon/alien/diona))
|
||||
target << "<B>You are \a [target], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
|
||||
target << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
|
||||
@@ -120,17 +120,17 @@
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
if(istype(D, /obj/item/weapon/card/emag))
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
last_to_emag = user //emag again to change the owner
|
||||
if (!emagged)
|
||||
emagged = 1
|
||||
safety_disabled = 1
|
||||
update_projections()
|
||||
user << "<span class='notice'>You vastly increase projector power and override the safety and security protocols.</span>"
|
||||
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
|
||||
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
|
||||
/obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
last_to_emag = user //emag again to change the owner
|
||||
if (!emagged)
|
||||
emagged = 1
|
||||
safety_disabled = 1
|
||||
update_projections()
|
||||
user << "<span class='notice'>You vastly increase projector power and override the safety and security protocols.</span>"
|
||||
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
|
||||
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
|
||||
return 1
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
@@ -158,16 +158,6 @@
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/meteorhit(var/obj/O as obj)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/emp_act(severity)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/ex_act(severity)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
@@ -55,4 +55,5 @@
|
||||
#define TRAIT_PRODUCT_COLOUR 35
|
||||
#define TRAIT_BIOLUM 36
|
||||
#define TRAIT_BIOLUM_COLOUR 37
|
||||
#define TRAIT_IMMUTABLE 38
|
||||
#define TRAIT_IMMUTABLE 38
|
||||
#define TRAIT_FLESH_COLOUR 39
|
||||
@@ -167,8 +167,8 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(seed) seed.thrown_at(src,hit_atom)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
|
||||
@@ -194,9 +194,11 @@
|
||||
else if(seed.chems)
|
||||
if(istype(W,/obj/item/weapon/material/hatchet) && !isnull(seed.chems["woodpulp"]))
|
||||
user.show_message("<span class='notice'>You make planks out of \the [src]!</span>", 1)
|
||||
var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
for(var/i=0,i<2,i++)
|
||||
var/obj/item/stack/material/wood/NG = new (user.loc)
|
||||
NG.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) NG.color = flesh_colour
|
||||
for (var/obj/item/stack/material/wood/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
@@ -221,6 +223,15 @@
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
else if(seed.get_trait(TRAIT_FLESH_COLOUR))
|
||||
user << "You slice up \the [src]."
|
||||
var/slices = rand(3,5)
|
||||
var/reagents_to_transfer = round(reagents.total_volume/slices)
|
||||
for(var/i=i;i<=slices;i++)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/F = new(get_turf(src),seed)
|
||||
if(reagents_to_transfer) reagents.trans_to_obj(F,reagents_to_transfer)
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone)
|
||||
@@ -301,9 +312,11 @@
|
||||
|
||||
if(seed.kitchen_tag == "grass")
|
||||
user.show_message("<span class='notice'>You make a grass tile out of \the [src]!</span>", 1)
|
||||
var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
for(var/i=0,i<2,i++)
|
||||
var/obj/item/stack/tile/grass/G = new (user.loc)
|
||||
G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) G.color = flesh_colour
|
||||
for (var/obj/item/stack/tile/grass/NG in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
@@ -358,3 +371,35 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris
|
||||
plantname = "ambrosia"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/fruit_slice
|
||||
name = "fruit slice"
|
||||
desc = "A slice of some tasty fruit."
|
||||
icon = 'icons/obj/hydroponics_misc.dmi'
|
||||
icon_state = ""
|
||||
|
||||
var/list/fruit_icon_cache = list()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/New(var/newloc, var/datum/seed/S)
|
||||
..(newloc)
|
||||
// Need to go through and make a general image caching controller. Todo.
|
||||
if(!istype(S))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
name = "[S.seed_name] slice"
|
||||
desc = "A slice of \a [S.seed_name]. Tasty, probably."
|
||||
|
||||
var/rind_colour = S.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
var/flesh_colour = S.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = rind_colour
|
||||
if(!fruit_icon_cache["rind-[rind_colour]"])
|
||||
var/image/I = image(icon,"fruit_rind")
|
||||
I.color = rind_colour
|
||||
fruit_icon_cache["rind-[rind_colour]"] = I
|
||||
overlays |= fruit_icon_cache["rind-[rind_colour]"]
|
||||
if(!fruit_icon_cache["slice-[rind_colour]"])
|
||||
var/image/I = image(icon,"fruit_slice")
|
||||
I.color = flesh_colour
|
||||
fruit_icon_cache["slice-[rind_colour]"] = I
|
||||
overlays |= fruit_icon_cache["slice-[rind_colour]"]
|
||||
|
||||
@@ -169,8 +169,9 @@
|
||||
if(get_trait(TRAIT_BIOLUM_COLOUR))
|
||||
clr = get_trait(TRAIT_BIOLUM_COLOUR)
|
||||
splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
|
||||
if(get_trait(TRAIT_PRODUCT_COLOUR))
|
||||
splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
var/flesh_colour = get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
|
||||
if(chems)
|
||||
for(var/mob/living/M in T.contents)
|
||||
@@ -229,7 +230,8 @@
|
||||
for(var/mob/living/M in T.contents)
|
||||
apply_special_effect(M)
|
||||
splatter(T,thrown)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] explodes!</span>")
|
||||
if(origin_turf)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] explodes!</span>")
|
||||
qdel(thrown)
|
||||
return
|
||||
|
||||
@@ -242,7 +244,8 @@
|
||||
|
||||
if(get_trait(TRAIT_JUICY) && splatted)
|
||||
splatter(origin_turf,thrown)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] splatters against [target]!</span>")
|
||||
if(origin_turf)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] splatters against [target]!</span>")
|
||||
qdel(thrown)
|
||||
|
||||
/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only)
|
||||
@@ -637,7 +640,7 @@
|
||||
if(GENE_STRUCTURE)
|
||||
traits_to_copy = list(TRAIT_PLANT_ICON,TRAIT_PRODUCT_ICON,TRAIT_HARVEST_REPEAT)
|
||||
if(GENE_FRUIT)
|
||||
traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_JUICY)
|
||||
traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_FLESH_COLOUR,TRAIT_JUICY)
|
||||
if(GENE_SPECIAL)
|
||||
traits_to_copy = list(TRAIT_TELEPORTING)
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@
|
||||
set_trait(TRAIT_PRODUCT_ICON,"apple")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#FF540A")
|
||||
set_trait(TRAIT_PLANT_ICON,"tree2")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#E8E39B")
|
||||
|
||||
/datum/seed/apple/poison
|
||||
name = "poisonapple"
|
||||
@@ -804,6 +805,7 @@
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#326B30")
|
||||
set_trait(TRAIT_PLANT_COLOUR,"#257522")
|
||||
set_trait(TRAIT_PLANT_ICON,"vine2")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#F22C2C")
|
||||
|
||||
/datum/seed/pumpkin
|
||||
name = "pumpkin"
|
||||
@@ -842,6 +844,7 @@
|
||||
set_trait(TRAIT_PRODUCT_ICON,"treefruit")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#3AF026")
|
||||
set_trait(TRAIT_PLANT_ICON,"tree")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#3AF026")
|
||||
|
||||
/datum/seed/citrus/lemon
|
||||
name = "lemon"
|
||||
@@ -854,6 +857,7 @@
|
||||
..()
|
||||
set_trait(TRAIT_PRODUCES_POWER,1)
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#F0E226")
|
||||
|
||||
/datum/seed/citrus/orange
|
||||
name = "orange"
|
||||
@@ -865,6 +869,7 @@
|
||||
/datum/seed/citrus/orange/New()
|
||||
..()
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#FFC20A")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#FFC20A")
|
||||
|
||||
/datum/seed/grass
|
||||
name = "grass"
|
||||
|
||||
@@ -196,16 +196,19 @@
|
||||
layer = 3
|
||||
density = 0
|
||||
|
||||
/obj/effect/plant/proc/calc_dir(turf/location = loc)
|
||||
/obj/effect/plant/proc/calc_dir()
|
||||
set background = 1
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
|
||||
var/direction = 16
|
||||
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/newTurf = get_step(location,wallDir)
|
||||
var/turf/newTurf = get_step(T,wallDir)
|
||||
if(newTurf.density)
|
||||
direction |= wallDir
|
||||
|
||||
for(var/obj/effect/plant/shroom in location)
|
||||
for(var/obj/effect/plant/shroom in T.contents)
|
||||
if(shroom == src)
|
||||
continue
|
||||
if(shroom.floor) //special
|
||||
|
||||
@@ -576,7 +576,7 @@
|
||||
usr << "[src] is empty."
|
||||
return
|
||||
|
||||
usr << "<span class='notice'>[seed.display_name]</span> are growing here.</span>"
|
||||
usr << "<span class='notice'>[seed.display_name] are growing here.</span>"
|
||||
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
|
||||
@@ -236,10 +236,13 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
|
||||
//dat += "<A HREF='?src=\ref[user];mach_close=library'>Close</A><br><br>"
|
||||
user << browse(dat, "window=library")
|
||||
onclose(user, "library")
|
||||
|
||||
/obj/machinery/librarycomp/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (src.density && !src.emagged)
|
||||
src.emagged = 1
|
||||
return 1
|
||||
|
||||
/obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (src.density && istype(W, /obj/item/weapon/card/emag))
|
||||
src.emagged = 1
|
||||
if(istype(W, /obj/item/weapon/barcodescanner))
|
||||
var/obj/item/weapon/barcodescanner/scanner = W
|
||||
scanner.computer = src
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
recipes += new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0)
|
||||
recipes += new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20)
|
||||
recipes += new/datum/stack_recipe("floor tile", /obj/item/stack/tile/steel, 1, 4, 20)
|
||||
recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60)
|
||||
recipes += new/datum/stack_recipe("computer frame", /obj/structure/computerframe, 5, time = 25, one_per_turf = 1, on_floor = 1)
|
||||
recipes += new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1)
|
||||
@@ -74,7 +74,7 @@
|
||||
recipes += new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade)
|
||||
recipes += new/datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2)
|
||||
recipes += new/datum/stack_recipe("small light fixture frame", /obj/item/frame/light/small, 1)
|
||||
recipes += new/datum/stack_recipe("apc frame", /obj/item/apc_frame, 2)
|
||||
recipes += new/datum/stack_recipe("apc frame", /obj/item/frame/apc, 2)
|
||||
recipes += new/datum/stack_recipe("air alarm frame", /obj/item/frame/air_alarm, 2)
|
||||
recipes += new/datum/stack_recipe("fire alarm frame", /obj/item/frame/fire_alarm, 2)
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
desc = "A stack of sheets of [material.display_name]."
|
||||
recipes = material.get_recipes()
|
||||
stacktype = material.stack_type
|
||||
origin_tech = material.stack_origin_tech.Copy()
|
||||
if(islist(material.stack_origin_tech))
|
||||
origin_tech = material.stack_origin_tech.Copy()
|
||||
perunit = SHEET_MATERIAL_AMOUNT
|
||||
|
||||
if(apply_colour)
|
||||
@@ -47,6 +48,19 @@
|
||||
return 0
|
||||
..(S,tamount,1)
|
||||
|
||||
/obj/item/stack/material/attack_self(var/mob/user)
|
||||
if(!material.build_windows(user, src))
|
||||
..()
|
||||
|
||||
/obj/item/stack/material/attackby(var/obj/item/W, var/mob/user)
|
||||
if(istype(W,/obj/item/stack/cable_coil))
|
||||
material.build_wired_product(user, W, src)
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/rods))
|
||||
material.build_rod_product(user, W, src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/material/iron
|
||||
name = "iron"
|
||||
icon_state = "sheet-silver"
|
||||
@@ -75,7 +89,7 @@
|
||||
default_type = "phoron"
|
||||
|
||||
/obj/item/stack/material/plastic
|
||||
name = "Plastic"
|
||||
name = "plastic"
|
||||
icon_state = "sheet-plastic"
|
||||
default_type = "plastic"
|
||||
|
||||
@@ -151,3 +165,27 @@
|
||||
singular_name = "leather piece"
|
||||
icon_state = "sheet-leather"
|
||||
default_type = "leather"
|
||||
|
||||
/obj/item/stack/material/glass
|
||||
name = "glass"
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-glass"
|
||||
default_type = "glass"
|
||||
|
||||
/obj/item/stack/material/glass/reinforced
|
||||
name = "reinforced glass"
|
||||
singular_name = "reinforced glass sheet"
|
||||
icon_state = "sheet-rglass"
|
||||
default_type = "reinforced glass"
|
||||
|
||||
/obj/item/stack/material/glass/phoronglass
|
||||
name = "phoron glass"
|
||||
singular_name = "phoron glass sheet"
|
||||
icon_state = "sheet-phoronglass"
|
||||
default_type = "phoron glass"
|
||||
|
||||
/obj/item/stack/material/glass/phoronrglass
|
||||
name = "reinforced phoron glass"
|
||||
singular_name = "reinforced phoron glass sheet"
|
||||
icon_state = "sheet-phoronrglass"
|
||||
default_type = "reinforced phoron glass"
|
||||
|
||||
@@ -13,20 +13,26 @@
|
||||
matter = null
|
||||
|
||||
/obj/item/stack/material/cyborg/plastic
|
||||
icon_state = "sheet-plastic"
|
||||
default_type = "plastic"
|
||||
|
||||
/obj/item/stack/material/cyborg/steel
|
||||
icon_state = "sheet-metal"
|
||||
default_type = "steel"
|
||||
|
||||
/obj/item/stack/material/cyborg/plasteel
|
||||
icon_state = "sheet-plasteel"
|
||||
default_type = "plasteel"
|
||||
|
||||
/obj/item/stack/material/cyborg/wood
|
||||
icon_state = "sheet-wood"
|
||||
default_type = "wood"
|
||||
|
||||
/obj/item/stack/material/cyborg/glass
|
||||
icon_state = "sheet-glass"
|
||||
default_type = "glass"
|
||||
|
||||
/obj/item/stack/material/cyborg/glass/reinforced
|
||||
icon_state = "sheet-rglass"
|
||||
default_type = "reinforced glass"
|
||||
charge_costs = list(500, 1000)
|
||||
@@ -68,7 +68,7 @@ var/list/name_to_material
|
||||
// Attributes
|
||||
var/cut_delay = 0 // Delay in ticks when cutting through this wall.
|
||||
var/radioactivity // Radiation var. Used in wall and object processing to irradiate surroundings.
|
||||
var/ignition_point // Point at which the material catches on fire.
|
||||
var/ignition_point // K, point at which the material catches on fire.
|
||||
var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this
|
||||
var/integrity = 150 // General-use HP value for products.
|
||||
var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors.
|
||||
@@ -76,6 +76,12 @@ var/list/name_to_material
|
||||
var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn.
|
||||
var/list/composite_material // If set, object matter var will be a list containing these values.
|
||||
|
||||
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
|
||||
var/created_window
|
||||
var/rod_product
|
||||
var/wire_product
|
||||
var/list/window_options = list()
|
||||
|
||||
// Damage values.
|
||||
var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons.
|
||||
var/weight = 20 // Determines blunt damage/throwforce for weapons.
|
||||
@@ -89,6 +95,37 @@ var/list/name_to_material
|
||||
// Wallrot crumble message.
|
||||
var/rotting_touch_message = "crumbles under your touch"
|
||||
|
||||
// Placeholders for light tiles and rglass.
|
||||
/material/proc/build_rod_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
|
||||
if(!rod_product)
|
||||
user << "<span class='warning'>You cannot make anything out of \the [target_stack]</span>"
|
||||
return
|
||||
if(used_stack.get_amount() < 1 || target_stack.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one rod and one sheet of [display_name] to make anything useful.</span>"
|
||||
return
|
||||
used_stack.use(1)
|
||||
target_stack.use(1)
|
||||
var/obj/item/stack/S = new rod_product(get_turf(user))
|
||||
S.add_fingerprint(user)
|
||||
S.add_to_stacks(user)
|
||||
if(!(user.l_hand && user.r_hand))
|
||||
user.put_in_hands(S)
|
||||
|
||||
/material/proc/build_wired_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
|
||||
if(!wire_product)
|
||||
user << "<span class='warning'>You cannot make anything out of \the [target_stack]</span>"
|
||||
return
|
||||
if(used_stack.get_amount() < 5 || target_stack.get_amount() < 1)
|
||||
user << "<span class='warning'>You need five wires and one sheet of [display_name] to make anything useful.</span>"
|
||||
return
|
||||
|
||||
used_stack.use(5)
|
||||
target_stack.use(1)
|
||||
user << "<span class='notice'>You attach wire to the [name].</span>"
|
||||
var/obj/item/product = new wire_product(get_turf(user))
|
||||
if(!(user.l_hand && user.r_hand))
|
||||
user.put_in_hands(product)
|
||||
|
||||
// Make sure we have a display name and shard icon even if they aren't explicitly set.
|
||||
/material/New()
|
||||
..()
|
||||
@@ -99,6 +136,10 @@ var/list/name_to_material
|
||||
if(!shard_icon)
|
||||
shard_icon = shard_type
|
||||
|
||||
// This is a placeholder for proper integration of windows/windoors into the system.
|
||||
/material/proc/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
|
||||
return 0
|
||||
|
||||
// Weapons handle applying a divisor for this value locally.
|
||||
/material/proc/get_blunt_damage()
|
||||
return weight //todo
|
||||
@@ -206,7 +247,7 @@ var/list/name_to_material
|
||||
/material/phoron
|
||||
name = "phoron"
|
||||
stack_type = /obj/item/stack/material/phoron
|
||||
ignition_point = 100
|
||||
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE
|
||||
icon_base = "stone"
|
||||
icon_colour = "#FC2BC5"
|
||||
shard_type = SHARD_SHARD
|
||||
@@ -214,6 +255,8 @@ var/list/name_to_material
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2, TECH_PHORON = 2)
|
||||
door_icon_base = "stone"
|
||||
|
||||
/*
|
||||
// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately.
|
||||
/material/phoron/combustion_effect(var/turf/T, var/temperature, var/effect_multiplier)
|
||||
if(isnull(ignition_point))
|
||||
return 0
|
||||
@@ -227,6 +270,7 @@ var/list/name_to_material
|
||||
spawn (0)
|
||||
target_tile.hotspot_expose(temperature, 400)
|
||||
return round(totalPhoron/100)
|
||||
*/
|
||||
|
||||
/material/stone
|
||||
name = "sandstone"
|
||||
@@ -249,6 +293,7 @@ var/list/name_to_material
|
||||
/material/steel
|
||||
name = DEFAULT_WALL_MATERIAL
|
||||
stack_type = /obj/item/stack/material/steel
|
||||
integrity = 150
|
||||
icon_base = "solid"
|
||||
icon_reinf = "reinf_over"
|
||||
icon_colour = "#666666"
|
||||
@@ -262,7 +307,7 @@ var/list/name_to_material
|
||||
/material/plasteel
|
||||
name = "plasteel"
|
||||
stack_type = /obj/item/stack/material/plasteel
|
||||
integrity = 800
|
||||
integrity = 400
|
||||
melting_point = 6000
|
||||
icon_base = "solid"
|
||||
icon_reinf = "reinf_over"
|
||||
@@ -271,7 +316,7 @@ var/list/name_to_material
|
||||
hardness = 80
|
||||
weight = 23
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
composite_material = list() //todo
|
||||
composite_material = list(DEFAULT_WALL_MATERIAL = 3750, "platinum" = 3750) //todo
|
||||
|
||||
/material/glass
|
||||
name = "glass"
|
||||
@@ -286,21 +331,82 @@ var/list/name_to_material
|
||||
weight = 15
|
||||
door_icon_base = "stone"
|
||||
destruction_desc = "shatters"
|
||||
window_options = list("One Direction", "Full Window")
|
||||
created_window = /obj/structure/window/basic
|
||||
wire_product = /obj/item/stack/light_w
|
||||
rod_product = /obj/item/stack/material/glass/reinforced
|
||||
|
||||
/material/glass/phoron
|
||||
name = "phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronglass
|
||||
flags = MATERIAL_BRITTLE
|
||||
ignition_point = 300
|
||||
integrity = 200 // idk why but phoron windows are strong, so.
|
||||
icon_colour = "#FC2BC5"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3, TECH_PHORON = 2)
|
||||
/material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
|
||||
|
||||
/material/glass/phoron/reinforced
|
||||
name = "reinforced phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronrglass
|
||||
stack_origin_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 2)
|
||||
composite_material = list() //todo
|
||||
if(!user || !used_stack || !created_window || !window_options.len)
|
||||
return 0
|
||||
|
||||
if(!user.IsAdvancedToolUser())
|
||||
user << "<span class='warning'>This task is too complex for your clumsy hands.</span>"
|
||||
return 1
|
||||
|
||||
var/turf/T = user.loc
|
||||
if(!istype(T))
|
||||
user << "<span class='warning'>You must be standing on open flooring to build a window.</span>"
|
||||
return 1
|
||||
|
||||
var/title = "Sheet-[used_stack.name] ([used_stack.get_amount()] sheet\s left)"
|
||||
var/choice = input(title, "What would you like to construct?") as null|anything in window_options
|
||||
|
||||
if(!choice || !used_stack || !user || used_stack.loc != user || user.stat || user.loc != T)
|
||||
return 1
|
||||
|
||||
// Get data for building windows here.
|
||||
var/list/possible_directions = cardinal.Copy()
|
||||
var/window_count = 0
|
||||
for (var/obj/structure/window/check_window in user.loc)
|
||||
window_count++
|
||||
possible_directions -= check_window.dir
|
||||
|
||||
// Get the closest available dir to the user's current facing.
|
||||
var/build_dir = SOUTHWEST //Default to southwest for fulltile windows.
|
||||
var/failed_to_build
|
||||
|
||||
if(window_count >= 4)
|
||||
failed_to_build = 1
|
||||
else
|
||||
if(choice in list("One Direction","Windoor"))
|
||||
if(possible_directions.len)
|
||||
for(var/direction in list(user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
|
||||
if(direction in possible_directions)
|
||||
build_dir = direction
|
||||
break
|
||||
else
|
||||
failed_to_build = 1
|
||||
if(!failed_to_build && choice == "Windoor")
|
||||
if(!is_reinforced())
|
||||
user << "<span class='warning'>This material is not reinforced enough to use for a door.</span>"
|
||||
return
|
||||
if((locate(/obj/structure/windoor_assembly) in T.contents) || (locate(/obj/machinery/door/window) in T.contents))
|
||||
failed_to_build = 1
|
||||
if(failed_to_build)
|
||||
user << "<span class='warning'>There is no room in this location.</span>"
|
||||
return 1
|
||||
|
||||
var/build_path = /obj/structure/windoor_assembly
|
||||
var/sheets_needed = 4
|
||||
if(choice == "Windoor")
|
||||
sheets_needed = 5
|
||||
build_dir = user.dir
|
||||
else
|
||||
build_path = created_window
|
||||
|
||||
if(used_stack.get_amount() < sheets_needed)
|
||||
user << "<span class='warning'>You need at least [sheets_needed] sheets to build this.</span>"
|
||||
return 1
|
||||
|
||||
// Build the structure and update sheet count etc.
|
||||
used_stack.use(sheets_needed)
|
||||
new build_path(T, build_dir, 1)
|
||||
return 1
|
||||
|
||||
/material/glass/proc/is_reinforced()
|
||||
return (hardness > 35) //todo
|
||||
|
||||
/material/glass/reinforced
|
||||
name = "reinforced glass"
|
||||
@@ -313,8 +419,36 @@ var/list/name_to_material
|
||||
tableslam_noise = 'sound/effects/Glasshit.ogg'
|
||||
hardness = 40
|
||||
weight = 30
|
||||
stack_origin_tech = "materials=2"
|
||||
composite_material = list(DEFAULT_WALL_MATERIAL = 1875,"glass" = 3750)
|
||||
window_options = list("One Direction", "Full Window", "Windoor")
|
||||
created_window = /obj/structure/window/reinforced
|
||||
wire_product = null
|
||||
rod_product = null
|
||||
|
||||
/material/glass/phoron
|
||||
name = "phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronglass
|
||||
flags = MATERIAL_BRITTLE
|
||||
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE+300
|
||||
integrity = 200 // idk why but phoron windows are strong, so.
|
||||
icon_colour = "#FC2BC5"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3, TECH_PHORON = 2)
|
||||
created_window = /obj/structure/window/phoronbasic
|
||||
wire_product = null
|
||||
rod_product = /obj/item/stack/material/glass/phoronrglass
|
||||
|
||||
/material/glass/phoron/reinforced
|
||||
name = "reinforced phoron glass"
|
||||
stack_type = /obj/item/stack/material/glass/phoronrglass
|
||||
stack_origin_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 2)
|
||||
composite_material = list() //todo
|
||||
created_window = /obj/structure/window/phoronreinforced
|
||||
hardness = 40
|
||||
weight = 30
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
composite_material = list() //todo
|
||||
rod_product = null
|
||||
|
||||
/material/plastic
|
||||
name = "plastic"
|
||||
@@ -325,8 +459,15 @@ var/list/name_to_material
|
||||
icon_colour = "#CCCCCC"
|
||||
hardness = 10
|
||||
weight = 12
|
||||
melting_point = T0C+371 //assuming heat resistant plastic
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3)
|
||||
|
||||
/material/plastic/holographic
|
||||
name = "holographic plastic"
|
||||
display_name = "plastic"
|
||||
stack_type = null
|
||||
shard_type = SHARD_NONE
|
||||
|
||||
/material/osmium
|
||||
name = "osmium"
|
||||
stack_type = /obj/item/stack/material/osmium
|
||||
@@ -381,6 +522,8 @@ var/list/name_to_material
|
||||
shard_can_repair = 0 // you can't weld splinters back into planks
|
||||
hardness = 15
|
||||
weight = 18
|
||||
melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood
|
||||
ignition_point = T0C+288
|
||||
stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
|
||||
dooropen_noise = 'sound/effects/doorcreaky.ogg'
|
||||
door_icon_base = "wood"
|
||||
@@ -402,6 +545,8 @@ var/list/name_to_material
|
||||
icon_colour = "#AAAAAA"
|
||||
hardness = 1
|
||||
weight = 1
|
||||
ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough
|
||||
melting_point = T0C+232 //temperature at which cardboard walls would be destroyed
|
||||
stack_origin_tech = list(TECH_MATERIAL = 1)
|
||||
door_icon_base = "wood"
|
||||
destruction_desc = "crumples"
|
||||
@@ -410,6 +555,8 @@ var/list/name_to_material
|
||||
name = "cloth"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
door_icon_base = "wood"
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
flags = MATERIAL_PADDING
|
||||
|
||||
/material/cult
|
||||
@@ -438,6 +585,7 @@ var/list/name_to_material
|
||||
icon_colour = "#E85DD8"
|
||||
dooropen_noise = 'sound/effects/attackblob.ogg'
|
||||
door_icon_base = "resin"
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/resin/can_open_material_door(var/mob/living/user)
|
||||
var/mob/living/carbon/M = user
|
||||
@@ -451,6 +599,8 @@ var/list/name_to_material
|
||||
icon_colour = "#5C4831"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+300
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/carpet
|
||||
name = "carpet"
|
||||
@@ -458,12 +608,16 @@ var/list/name_to_material
|
||||
use_name = "red upholstery"
|
||||
icon_colour = "#DA020A"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cotton
|
||||
name = "cotton"
|
||||
display_name ="cotton"
|
||||
icon_colour = "#FFFFFF"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_teal
|
||||
name = "teal"
|
||||
@@ -471,6 +625,8 @@ var/list/name_to_material
|
||||
use_name = "teal cloth"
|
||||
icon_colour = "#00EAFA"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_black
|
||||
name = "black"
|
||||
@@ -478,6 +634,8 @@ var/list/name_to_material
|
||||
use_name = "black cloth"
|
||||
icon_colour = "#505050"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_green
|
||||
name = "green"
|
||||
@@ -485,6 +643,8 @@ var/list/name_to_material
|
||||
use_name = "green cloth"
|
||||
icon_colour = "#01C608"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_puple
|
||||
name = "purple"
|
||||
@@ -492,6 +652,8 @@ var/list/name_to_material
|
||||
use_name = "purple cloth"
|
||||
icon_colour = "#9C56C4"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_blue
|
||||
name = "blue"
|
||||
@@ -499,6 +661,8 @@ var/list/name_to_material
|
||||
use_name = "blue cloth"
|
||||
icon_colour = "#6B6FE3"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_beige
|
||||
name = "beige"
|
||||
@@ -506,6 +670,8 @@ var/list/name_to_material
|
||||
use_name = "beige cloth"
|
||||
icon_colour = "#E8E7C8"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
/material/cloth_lime
|
||||
name = "lime"
|
||||
@@ -513,3 +679,5 @@ var/list/name_to_material
|
||||
use_name = "lime cloth"
|
||||
icon_colour = "#62E36C"
|
||||
flags = MATERIAL_PADDING
|
||||
ignition_point = T0C+232
|
||||
melting_point = T0C+300
|
||||
|
||||
@@ -171,12 +171,14 @@
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (locked)
|
||||
user << "<span class='notice'>The crate unlocks!</span>"
|
||||
locked = 0
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(locked)
|
||||
if (istype(W, /obj/item/weapon/card/emag))
|
||||
user << "<span class='notice'>The crate unlocks!</span>"
|
||||
locked = 0
|
||||
if (istype(W, /obj/item/device/multitool)) // Greetings Urist McProfessor, how about a nice game of cows and bulls?
|
||||
user << "<span class='notice'>DECA-CODE LOCK REPORT:</span>"
|
||||
if (attempts == 1)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
force = 0.0
|
||||
throwforce = 0.0
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_EARS
|
||||
var/string_attached
|
||||
var/sides = 2
|
||||
|
||||
|
||||
@@ -672,7 +672,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
mob/dead/observer/MayRespawn(var/feedback = 0)
|
||||
if(!client)
|
||||
return 0
|
||||
if(mind && mind.current && mind.current.stat != DEAD)
|
||||
if(mind && mind.current && mind.current.stat != DEAD && can_reenter_corpse)
|
||||
if(feedback)
|
||||
src << "<span class='warning'>Your non-dead body prevent you from respawning.</span>"
|
||||
return 0
|
||||
@@ -681,3 +681,19 @@ mob/dead/observer/MayRespawn(var/feedback = 0)
|
||||
src << "<span class='warning'>antagHUD restrictions prevent you from respawning.</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/atom/proc/extra_ghost_link()
|
||||
return
|
||||
|
||||
/mob/extra_ghost_link(var/atom/ghost)
|
||||
if(client && eyeobj)
|
||||
return "|<a href='byond://?src=\ref[ghost];track=\ref[eyeobj]'>eye</a>"
|
||||
|
||||
/mob/dead/observer/extra_ghost_link(var/atom/ghost)
|
||||
if(mind && mind.current)
|
||||
return "|<a href='byond://?src=\ref[ghost];track=\ref[mind.current]'>body</a>"
|
||||
|
||||
/proc/ghost_follow_link(var/atom/target, var/atom/ghost)
|
||||
if((!target) || (!ghost)) return
|
||||
. = "<a href='byond://?src=\ref[ghost];track=\ref[target]'>follow</a>"
|
||||
. += target.extra_ghost_link(ghost)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//added different sort of gibs and animations. N
|
||||
/mob/proc/gib(anim="gibbed-m",do_gibs)
|
||||
death(1)
|
||||
monkeyizing = 1
|
||||
transforming = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
@@ -28,7 +28,7 @@
|
||||
/mob/proc/dust(anim="dust-m",remains=/obj/effect/decal/cleanable/ash)
|
||||
death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
monkeyizing = 1
|
||||
transforming = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/death(gibbed, deathmessage="seizes up and falls limp...")
|
||||
if(..())
|
||||
if(..(gibbed, deathmessage))
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cultnet.updateVisibility(src)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
return
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "(<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>) "
|
||||
track = "([ghost_follow_link(speaker, src)]) "
|
||||
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
|
||||
message = "<b>[message]</b>"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
if(istype(src, /mob/dead/observer))
|
||||
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "[speaker_name] (<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>)"
|
||||
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
|
||||
|
||||
var/formatted
|
||||
if(language)
|
||||
@@ -197,18 +197,18 @@
|
||||
return "<span class='say_quote'>\[[worldtime2text()]\]</span>"
|
||||
|
||||
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
src << "[part_a][speaker_name][part_b][formatted]</span></span>"
|
||||
src << "[part_a][speaker_name][part_b][formatted]"
|
||||
|
||||
/mob/dead/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
src << "[part_a][track][part_b][formatted]</span></span>"
|
||||
src << "[part_a][track][part_b][formatted]"
|
||||
|
||||
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
var/time = say_timestamp()
|
||||
src << "[time][part_a][speaker_name][part_b][formatted]</span></span>"
|
||||
src << "[time][part_a][speaker_name][part_b][formatted]"
|
||||
|
||||
/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
var/time = say_timestamp()
|
||||
src << "[time][part_a][track][part_b][formatted]</span></span>"
|
||||
src << "[time][part_a][track][part_b][formatted]"
|
||||
|
||||
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
|
||||
if(!client)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/flags = 0 // Various language flags.
|
||||
var/native // If set, non-native speakers will have trouble speaking.
|
||||
var/list/syllables // Used when scrambling text for a non-speaker.
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string.
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
|
||||
|
||||
/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4)
|
||||
if(!syllables || !syllables.len)
|
||||
@@ -101,11 +101,22 @@
|
||||
log_say("[key_name(speaker)] : ([name]) [message]")
|
||||
|
||||
if(!speaker_mask) speaker_mask = speaker.name
|
||||
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [format_message(message, get_spoken_verb(message))]</span></i>"
|
||||
|
||||
for(var/mob/player in player_list)
|
||||
if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
|
||||
player << msg
|
||||
player.hear_broadcast(src, speaker, speaker_mask, format_message(message, get_spoken_verb(message)))
|
||||
|
||||
/mob/proc/hear_broadcast(var/datum/language/language, var/speaker, var/message)
|
||||
if((language in languages) && language.check_special_condition(src))
|
||||
var/msg = "<i><span class='game say'>[language.name], <span class='name'>[speaker]</span> [message]</span></i>"
|
||||
src << msg
|
||||
|
||||
/mob/new_player/hear_broadcast()
|
||||
return
|
||||
|
||||
/mob/dead/observer/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
|
||||
if(speaker.name == speaker_name || antagHUD)
|
||||
src << "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> ([ghost_follow_link(speaker, src)]) [message]</span></i>"
|
||||
else
|
||||
src << "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> [message]</span></i>"
|
||||
|
||||
/datum/language/proc/check_special_condition(var/mob/other)
|
||||
return 1
|
||||
|
||||
@@ -41,18 +41,18 @@
|
||||
colour = "tajaran"
|
||||
key = "j"
|
||||
flags = WHITELISTED
|
||||
syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \
|
||||
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \
|
||||
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \
|
||||
"hal","ket","jurl","mah","tul","cresh","azu","ragh", "mro", "mra")
|
||||
syllables = list("mrr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr",
|
||||
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r",
|
||||
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
|
||||
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
|
||||
|
||||
/datum/language/tajaran/get_random_name(var/gender)
|
||||
|
||||
var/new_name = ..(gender,1)
|
||||
if(prob(80))
|
||||
new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]"
|
||||
if(prob(50))
|
||||
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
|
||||
else
|
||||
new_name += ..(gender,1)
|
||||
new_name += " [..(gender,1)]"
|
||||
return new_name
|
||||
|
||||
/datum/language/skrell
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
for (var/mob/M in dead_mob_list)
|
||||
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
|
||||
M.show_message("[message_start] [message_body]", 2)
|
||||
M.show_message("[message_start] ([ghost_follow_link(speaker, M)]) [message_body]", 2)
|
||||
|
||||
for (var/mob/living/S in living_mob_list)
|
||||
|
||||
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
|
||||
continue
|
||||
else if(istype(S , /mob/living/silicon/ai))
|
||||
message_start = "<i><span class='game say'>[name], <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[speaker];trackname=[html_encode(speaker.name)]'><span class='name'>[speaker.name]</span></a>"
|
||||
message_start = "<i><span class='game say'>[name], <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[speaker];trackname=[html_encode(speaker.name)]'><span class='name'>[speaker.name]</span></a></span>"
|
||||
else if (!S.binarycheck())
|
||||
continue
|
||||
|
||||
|
||||
@@ -80,9 +80,6 @@
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair.</span>"
|
||||
return
|
||||
else if (istype(O, /obj/item/weapon/card/emag) && !emagged)
|
||||
Emag(user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -102,9 +99,8 @@
|
||||
if(!istype(D, /obj/machinery/door/firedoor) && !istype(D, /obj/machinery/door/blast) && D.check_access(botcard))
|
||||
D.open()
|
||||
|
||||
/mob/living/bot/proc/Emag(var/mob/user)
|
||||
log_and_message_admins("emagged [src]")
|
||||
return
|
||||
/mob/living/bot/emag_act(var/remaining_charges, var/mob/user)
|
||||
return 0
|
||||
|
||||
/mob/living/bot/proc/turn_on()
|
||||
if(stat)
|
||||
|
||||
@@ -232,12 +232,14 @@
|
||||
usr << "<span class='notice'>You press the weird button.</span>"
|
||||
attack_hand(usr)
|
||||
|
||||
/mob/living/bot/cleanbot/Emag(var/mob/user)
|
||||
..()
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
/mob/living/bot/cleanbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!screwloose || !oddbutton)
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/cleanbot/proc/get_targets()
|
||||
target_types = list()
|
||||
|
||||
@@ -64,13 +64,15 @@
|
||||
onclose(user, "autofarm")
|
||||
return
|
||||
|
||||
/mob/living/bot/farmbot/Emag(var/mob/user)
|
||||
..()
|
||||
if(user)
|
||||
user << "<span class='notice'>You short out [src]'s plant identifier circuits.</span>"
|
||||
spawn(rand(30, 50))
|
||||
visible_message("<span class='warning'>[src] buzzes oddly.</span>")
|
||||
emagged = 1
|
||||
/mob/living/bot/farmbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
if(user)
|
||||
user << "<span class='notice'>You short out [src]'s plant identifier circuits.</span>"
|
||||
spawn(rand(30, 50))
|
||||
visible_message("<span class='warning'>[src] buzzes oddly.</span>")
|
||||
emagged = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/farmbot/Topic(href, href_list)
|
||||
if(..())
|
||||
|
||||
@@ -47,11 +47,13 @@
|
||||
onclose(user, "autorepair")
|
||||
return
|
||||
|
||||
/mob/living/bot/floorbot/Emag(var/mob/user)
|
||||
..()
|
||||
emagged = 1
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
/mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
return 1
|
||||
|
||||
/mob/living/bot/floorbot/Topic(href, href_list)
|
||||
if(..())
|
||||
@@ -148,7 +150,7 @@
|
||||
|
||||
if(!target && amount < maxAmount && eattiles || maketiles) // Eat tiles
|
||||
if(eattiles)
|
||||
for(var/obj/item/stack/tile/plasteel/T in view(src))
|
||||
for(var/obj/item/stack/tile/steel/T in view(src))
|
||||
if(T in ignorelist)
|
||||
continue
|
||||
target = T
|
||||
@@ -215,7 +217,7 @@
|
||||
if(A && (locate(/obj/structure/lattice, A) && building == 1 || !locate(/obj/structure/lattice, A) && building == 2)) // Make sure that it still needs repairs
|
||||
var/obj/item/I
|
||||
if(building == 1)
|
||||
I = new /obj/item/stack/tile/plasteel(src)
|
||||
I = new /obj/item/stack/tile/steel(src)
|
||||
else
|
||||
I = PoolOrNew(/obj/item/stack/rods, src)
|
||||
A.attackby(I, src)
|
||||
@@ -230,14 +232,14 @@
|
||||
visible_message("<span class='notice'>[src] begins to improve the floor.</span>")
|
||||
if(do_after(src, 50))
|
||||
if(!F.floor_type)
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel(src)
|
||||
var/obj/item/stack/tile/steel/T = new /obj/item/stack/tile/steel(src)
|
||||
F.attackby(T, src)
|
||||
addTiles(-1)
|
||||
target = null
|
||||
repairing = 0
|
||||
update_icons()
|
||||
else if(istype(A, /obj/item/stack/tile/plasteel) && amount < maxAmount)
|
||||
var/obj/item/stack/tile/plasteel/T = A
|
||||
else if(istype(A, /obj/item/stack/tile/steel) && amount < maxAmount)
|
||||
var/obj/item/stack/tile/steel/T = A
|
||||
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
|
||||
repairing = 1
|
||||
update_icons()
|
||||
@@ -269,7 +271,7 @@
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel(Tsec)
|
||||
var/obj/item/stack/tile/steel/T = new /obj/item/stack/tile/steel(Tsec)
|
||||
T.amount = amount
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
@@ -285,8 +287,8 @@
|
||||
|
||||
/* Assembly */
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/plasteel/T, mob/user as mob)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/steel/T, mob/user as mob)
|
||||
if(!istype(T, /obj/item/stack/tile/steel))
|
||||
..()
|
||||
return
|
||||
if(contents.len >= 1)
|
||||
|
||||
@@ -219,8 +219,8 @@
|
||||
attack_hand(usr)
|
||||
return
|
||||
|
||||
/mob/living/bot/medbot/Emag(var/mob/user)
|
||||
..()
|
||||
/mob/living/bot/medbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
if(user)
|
||||
user << "<span class='warning'>You short out [src]'s reagent synthesis circuits.</span>"
|
||||
@@ -231,6 +231,7 @@
|
||||
emagged = 1
|
||||
on = 1
|
||||
update_icons()
|
||||
. = 1
|
||||
ignored |= user
|
||||
|
||||
/mob/living/bot/medbot/explode()
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/max_grown = 200
|
||||
var/time_of_birth
|
||||
var/language
|
||||
var/death_msg = "lets out a waning guttural screech, green blood bubbling from its maw."
|
||||
|
||||
/mob/living/carbon/alien/New()
|
||||
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
/mob/living/carbon/alien/attack_ui(slot_id)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/meteorhit(O as obj)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message(text("\red [] has been hit by []", src, O), 1)
|
||||
if (health > 0)
|
||||
adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
|
||||
adjustFireLoss(30)
|
||||
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/attack_hand(mob/living/carbon/M as mob)
|
||||
|
||||
..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/death(gibbed)
|
||||
if(!gibbed && dead_icon)
|
||||
icon_state = dead_icon
|
||||
return ..(gibbed,"lets out a waning guttural screech, green blood bubbling from its maw.")
|
||||
return ..(gibbed,death_msg)
|
||||
@@ -5,7 +5,7 @@
|
||||
speak_emote = list("chirrups")
|
||||
icon_state = "nymph"
|
||||
language = "Rootspeak"
|
||||
|
||||
death_msg = "expires with a pitiful chirrup..."
|
||||
universal_understand = 1
|
||||
universal_speak = 0 // Dionaea do not need to speak to people other than other dionaea.
|
||||
holder_type = /obj/item/weapon/holder/diona
|
||||
|
||||
@@ -4,39 +4,21 @@
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
|
||||
if (monkeyizing) return
|
||||
if (transforming) return
|
||||
if(!loc) return
|
||||
|
||||
..()
|
||||
|
||||
if (stat != DEAD) //still breathing
|
||||
|
||||
// GROW!
|
||||
update_progression()
|
||||
|
||||
// Radiation.
|
||||
handle_mutations_and_radiation()
|
||||
|
||||
// Chemicals in the body
|
||||
handle_chemicals_in_body()
|
||||
|
||||
blinded = null
|
||||
|
||||
if(loc)
|
||||
handle_environment(loc.return_air())
|
||||
|
||||
//Status updates, death etc.
|
||||
handle_regular_status_updates()
|
||||
update_canmove()
|
||||
update_icons()
|
||||
|
||||
if(client)
|
||||
handle_regular_hud_updates()
|
||||
|
||||
/mob/living/carbon/alien/proc/handle_chemicals_in_body()
|
||||
return // Nothing yet. Maybe check it out at a later date.
|
||||
|
||||
/mob/living/carbon/alien/proc/handle_mutations_and_radiation()
|
||||
/mob/living/carbon/alien/handle_mutations_and_radiation()
|
||||
|
||||
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
|
||||
// rad absorbtion here. This will need to be changed if other baby aliens are added.
|
||||
@@ -52,7 +34,7 @@
|
||||
adjustToxLoss(-(rads))
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/proc/handle_regular_status_updates()
|
||||
/mob/living/carbon/alien/handle_regular_status_updates()
|
||||
|
||||
if(status_flags & GODMODE) return 0
|
||||
|
||||
@@ -103,18 +85,11 @@
|
||||
else if(eye_blurry)
|
||||
eye_blurry = max(eye_blurry-1, 0)
|
||||
|
||||
//Ears
|
||||
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
|
||||
ear_deaf = max(ear_deaf, 1)
|
||||
else if(ear_deaf) //deafness, heals slowly over time
|
||||
ear_deaf = max(ear_deaf-1, 0)
|
||||
ear_damage = max(ear_damage-0.05, 0)
|
||||
|
||||
update_icons()
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/proc/handle_regular_hud_updates()
|
||||
/mob/living/carbon/alien/handle_regular_hud_updates()
|
||||
|
||||
if (stat == 2 || (XRAY in src.mutations))
|
||||
sight |= SEE_TURFS
|
||||
@@ -174,7 +149,7 @@
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/proc/handle_environment(var/datum/gas_mixture/environment)
|
||||
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
|
||||
// Both alien subtypes survive in vaccum and suffer in high temperatures,
|
||||
// so I'll just define this once, for both (see radiation comment above)
|
||||
if(!environment) return
|
||||
@@ -186,3 +161,9 @@
|
||||
src << "\red You feel a searing heat!"
|
||||
else
|
||||
if (fire) fire.icon_state = "fire0"
|
||||
|
||||
/mob/living/carbon/alien/handle_fire()
|
||||
if(..())
|
||||
return
|
||||
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
|
||||
return
|
||||
|
||||
@@ -1,268 +1,227 @@
|
||||
/mob/living/carbon/brain/Life()
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
..()
|
||||
/mob/living/carbon/brain/handle_breathing()
|
||||
return
|
||||
|
||||
if(stat != DEAD)
|
||||
//Mutations and radiation
|
||||
handle_mutations_and_radiation()
|
||||
/mob/living/carbon/brain/handle_mutations_and_radiation()
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
radiation = 100
|
||||
if(!container)//If it's not in an MMI
|
||||
src << "\red You feel weak."
|
||||
else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that
|
||||
src << "\red STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED."
|
||||
|
||||
//Chemicals in the body
|
||||
handle_chemicals_in_body()
|
||||
|
||||
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
|
||||
if(loc)
|
||||
environment = loc.return_air()
|
||||
|
||||
//Apparently, the person who wrote this code designed it so that
|
||||
//blinded get reset each cycle and then get activated later in the
|
||||
//code. Very ugly. I dont care. Moving this stuff here so its easy
|
||||
//to find it.
|
||||
blinded = null
|
||||
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
if(environment) // More error checking -- TLE
|
||||
handle_environment(environment)
|
||||
|
||||
//Status updates, death etc.
|
||||
handle_regular_status_updates()
|
||||
update_canmove()
|
||||
|
||||
if(client)
|
||||
handle_regular_hud_updates()
|
||||
|
||||
|
||||
/mob/living/carbon/brain/
|
||||
proc/handle_mutations_and_radiation()
|
||||
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
radiation = 100
|
||||
if(!container)//If it's not in an MMI
|
||||
src << "\red You feel weak."
|
||||
else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that
|
||||
src << "\red STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED."
|
||||
|
||||
switch(radiation)
|
||||
if(1 to 49)
|
||||
radiation--
|
||||
if(prob(25))
|
||||
adjustToxLoss(1)
|
||||
updatehealth()
|
||||
|
||||
if(50 to 74)
|
||||
radiation -= 2
|
||||
switch(radiation)
|
||||
if(1 to 49)
|
||||
radiation--
|
||||
if(prob(25))
|
||||
adjustToxLoss(1)
|
||||
if(prob(5))
|
||||
radiation -= 5
|
||||
if(!container)
|
||||
src << "\red You feel weak."
|
||||
else
|
||||
src << "\red STATUS: DANGEROUS LEVELS OF RADIATION DETECTED."
|
||||
updatehealth()
|
||||
|
||||
if(75 to 100)
|
||||
radiation -= 3
|
||||
adjustToxLoss(3)
|
||||
updatehealth()
|
||||
if(50 to 74)
|
||||
radiation -= 2
|
||||
adjustToxLoss(1)
|
||||
if(prob(5))
|
||||
radiation -= 5
|
||||
if(!container)
|
||||
src << "\red You feel weak."
|
||||
else
|
||||
src << "\red STATUS: DANGEROUS LEVELS OF RADIATION DETECTED."
|
||||
updatehealth()
|
||||
|
||||
if(75 to 100)
|
||||
radiation -= 3
|
||||
adjustToxLoss(3)
|
||||
updatehealth()
|
||||
|
||||
|
||||
proc/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
var/environment_heat_capacity = environment.heat_capacity()
|
||||
if(istype(get_turf(src), /turf/space))
|
||||
var/turf/heat_turf = get_turf(src)
|
||||
environment_heat_capacity = heat_turf.heat_capacity
|
||||
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
var/environment_heat_capacity = environment.heat_capacity()
|
||||
if(istype(get_turf(src), /turf/space))
|
||||
var/turf/heat_turf = get_turf(src)
|
||||
environment_heat_capacity = heat_turf.heat_capacity
|
||||
|
||||
if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
|
||||
var/transfer_coefficient = 1
|
||||
if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
|
||||
var/transfer_coefficient = 1
|
||||
|
||||
handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
|
||||
handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
|
||||
|
||||
if(stat==2)
|
||||
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
|
||||
if(stat==2)
|
||||
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
|
||||
|
||||
//Account for massive pressure differences
|
||||
//Account for massive pressure differences
|
||||
|
||||
return //TODO: DEFERRED
|
||||
return //TODO: DEFERRED
|
||||
|
||||
proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
|
||||
if(status_flags & GODMODE) return
|
||||
/mob/living/carbon/brain/proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
|
||||
if(status_flags & GODMODE) return
|
||||
|
||||
if(exposed_temperature > bodytemperature)
|
||||
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
|
||||
//adjustFireLoss(2.5*discomfort)
|
||||
//adjustFireLoss(5.0*discomfort)
|
||||
adjustFireLoss(20.0*discomfort)
|
||||
if(exposed_temperature > bodytemperature)
|
||||
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
|
||||
//adjustFireLoss(2.5*discomfort)
|
||||
//adjustFireLoss(5.0*discomfort)
|
||||
adjustFireLoss(20.0*discomfort)
|
||||
|
||||
else
|
||||
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
|
||||
//adjustFireLoss(2.5*discomfort)
|
||||
adjustFireLoss(5.0*discomfort)
|
||||
else
|
||||
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
|
||||
//adjustFireLoss(2.5*discomfort)
|
||||
adjustFireLoss(5.0*discomfort)
|
||||
|
||||
|
||||
/mob/living/carbon/brain/handle_chemicals_in_body()
|
||||
chem_effects.Cut()
|
||||
analgesic = 0
|
||||
|
||||
proc/handle_chemicals_in_body()
|
||||
if(touching) touching.metabolize()
|
||||
if(ingested) ingested.metabolize()
|
||||
if(bloodstr) bloodstr.metabolize()
|
||||
|
||||
chem_effects.Cut()
|
||||
analgesic = 0
|
||||
if(CE_PAINKILLER in chem_effects)
|
||||
analgesic = chem_effects[CE_PAINKILLER]
|
||||
|
||||
if(touching)
|
||||
touching.metabolize(0, CHEM_TOUCH)
|
||||
if(ingested)
|
||||
ingested.metabolize(0, CHEM_INGEST)
|
||||
if(reagents)
|
||||
reagents.metabolize(0, CHEM_BLOOD)
|
||||
confused = max(0, confused - 1)
|
||||
// decrement dizziness counter, clamped to 0
|
||||
if(resting)
|
||||
dizziness = max(0, dizziness - 5)
|
||||
else
|
||||
dizziness = max(0, dizziness - 1)
|
||||
|
||||
if(CE_PAINKILLER in chem_effects)
|
||||
analgesic = chem_effects[CE_PAINKILLER]
|
||||
updatehealth()
|
||||
|
||||
confused = max(0, confused - 1)
|
||||
// decrement dizziness counter, clamped to 0
|
||||
if(resting)
|
||||
dizziness = max(0, dizziness - 5)
|
||||
else
|
||||
dizziness = max(0, dizziness - 1)
|
||||
return //TODO: DEFERRED
|
||||
|
||||
updatehealth()
|
||||
/mob/living/carbon/brain/handle_regular_status_updates() //TODO: comment out the unused bits >_>
|
||||
updatehealth()
|
||||
|
||||
return //TODO: DEFERRED
|
||||
|
||||
|
||||
proc/handle_regular_status_updates() //TODO: comment out the unused bits >_>
|
||||
updatehealth()
|
||||
|
||||
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
|
||||
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
|
||||
blinded = 1
|
||||
silent = 0
|
||||
else //ALIVE. LIGHTS ARE ON
|
||||
if( !container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life)) )
|
||||
death()
|
||||
blinded = 1
|
||||
silent = 0
|
||||
else //ALIVE. LIGHTS ARE ON
|
||||
if( !container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life)) )
|
||||
death()
|
||||
blinded = 1
|
||||
silent = 0
|
||||
return 1
|
||||
return 1
|
||||
|
||||
//Handling EMP effect in the Life(), it's made VERY simply, and has some additional effects handled elsewhere
|
||||
if(emp_damage) //This is pretty much a damage type only used by MMIs, dished out by the emp_act
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
emp_damage = 0
|
||||
else
|
||||
emp_damage = round(emp_damage,1)//Let's have some nice numbers to work with
|
||||
switch(emp_damage)
|
||||
if(31 to INFINITY)
|
||||
emp_damage = 30//Let's not overdo it
|
||||
if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
|
||||
eye_blind = 1
|
||||
blinded = 1
|
||||
ear_deaf = 1
|
||||
silent = 1
|
||||
if(!alert)//Sounds an alarm, but only once per 'level'
|
||||
emote("alarm")
|
||||
src << "\red Major electrical distruption detected: System rebooting."
|
||||
alert = 1
|
||||
if(prob(75))
|
||||
emp_damage -= 1
|
||||
if(20)
|
||||
alert = 0
|
||||
blinded = 0
|
||||
eye_blind = 0
|
||||
ear_deaf = 0
|
||||
silent = 0
|
||||
emp_damage -= 1
|
||||
if(11 to 19)//Moderate level of EMP damage, resulting in nearsightedness and ear damage
|
||||
eye_blurry = 1
|
||||
ear_damage = 1
|
||||
if(!alert)
|
||||
emote("alert")
|
||||
src << "\red Primary systems are now online."
|
||||
alert = 1
|
||||
if(prob(50))
|
||||
emp_damage -= 1
|
||||
if(10)
|
||||
alert = 0
|
||||
eye_blurry = 0
|
||||
ear_damage = 0
|
||||
emp_damage -= 1
|
||||
if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere)
|
||||
if(!alert)
|
||||
emote("notice")
|
||||
src << "\red System reboot nearly complete."
|
||||
alert = 1
|
||||
if(prob(25))
|
||||
emp_damage -= 1
|
||||
if(1)
|
||||
alert = 0
|
||||
src << "\red All systems restored."
|
||||
emp_damage -= 1
|
||||
|
||||
//Other
|
||||
handle_statuses()
|
||||
return 1
|
||||
|
||||
|
||||
proc/handle_regular_hud_updates()
|
||||
|
||||
if (stat == 2 || (XRAY in src.mutations))
|
||||
sight |= SEE_TURFS
|
||||
sight |= SEE_MOBS
|
||||
sight |= SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else if (stat != 2)
|
||||
sight &= ~SEE_TURFS
|
||||
sight &= ~SEE_MOBS
|
||||
sight &= ~SEE_OBJS
|
||||
see_in_dark = 2
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if (healths)
|
||||
if (stat != 2)
|
||||
switch(health)
|
||||
if(100 to INFINITY)
|
||||
healths.icon_state = "health0"
|
||||
if(80 to 100)
|
||||
healths.icon_state = "health1"
|
||||
if(60 to 80)
|
||||
healths.icon_state = "health2"
|
||||
if(40 to 60)
|
||||
healths.icon_state = "health3"
|
||||
if(20 to 40)
|
||||
healths.icon_state = "health4"
|
||||
if(0 to 20)
|
||||
healths.icon_state = "health5"
|
||||
else
|
||||
healths.icon_state = "health6"
|
||||
//Handling EMP effect in the Life(), it's made VERY simply, and has some additional effects handled elsewhere
|
||||
if(emp_damage) //This is pretty much a damage type only used by MMIs, dished out by the emp_act
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
emp_damage = 0
|
||||
else
|
||||
healths.icon_state = "health7"
|
||||
emp_damage = round(emp_damage,1)//Let's have some nice numbers to work with
|
||||
switch(emp_damage)
|
||||
if(31 to INFINITY)
|
||||
emp_damage = 30//Let's not overdo it
|
||||
if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
|
||||
eye_blind = 1
|
||||
blinded = 1
|
||||
ear_deaf = 1
|
||||
silent = 1
|
||||
if(!alert)//Sounds an alarm, but only once per 'level'
|
||||
emote("alarm")
|
||||
src << "\red Major electrical distruption detected: System rebooting."
|
||||
alert = 1
|
||||
if(prob(75))
|
||||
emp_damage -= 1
|
||||
if(20)
|
||||
alert = 0
|
||||
blinded = 0
|
||||
eye_blind = 0
|
||||
ear_deaf = 0
|
||||
silent = 0
|
||||
emp_damage -= 1
|
||||
if(11 to 19)//Moderate level of EMP damage, resulting in nearsightedness and ear damage
|
||||
eye_blurry = 1
|
||||
ear_damage = 1
|
||||
if(!alert)
|
||||
emote("alert")
|
||||
src << "\red Primary systems are now online."
|
||||
alert = 1
|
||||
if(prob(50))
|
||||
emp_damage -= 1
|
||||
if(10)
|
||||
alert = 0
|
||||
eye_blurry = 0
|
||||
ear_damage = 0
|
||||
emp_damage -= 1
|
||||
if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere)
|
||||
if(!alert)
|
||||
emote("notice")
|
||||
src << "\red System reboot nearly complete."
|
||||
alert = 1
|
||||
if(prob(25))
|
||||
emp_damage -= 1
|
||||
if(1)
|
||||
alert = 0
|
||||
src << "\red All systems restored."
|
||||
emp_damage -= 1
|
||||
|
||||
if (client)
|
||||
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
|
||||
//Other
|
||||
handle_statuses()
|
||||
return 1
|
||||
|
||||
if ((blind && stat != 2))
|
||||
if ((blinded))
|
||||
blind.layer = 18
|
||||
else
|
||||
blind.layer = 0
|
||||
|
||||
if (disabilities & NEARSIGHTED)
|
||||
client.screen += global_hud.vimpaired
|
||||
|
||||
if (eye_blurry)
|
||||
client.screen += global_hud.blurry
|
||||
|
||||
if (druggy)
|
||||
client.screen += global_hud.druggy
|
||||
/mob/living/carbon/brain/handle_regular_hud_updates()
|
||||
if (stat == 2 || (XRAY in src.mutations))
|
||||
sight |= SEE_TURFS
|
||||
sight |= SEE_MOBS
|
||||
sight |= SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
else if (stat != 2)
|
||||
sight &= ~SEE_TURFS
|
||||
sight &= ~SEE_MOBS
|
||||
sight &= ~SEE_OBJS
|
||||
see_in_dark = 2
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if (healths)
|
||||
if (stat != 2)
|
||||
if (machine)
|
||||
if (!( machine.check_eye(src) ))
|
||||
reset_view(null)
|
||||
else
|
||||
if(client && !client.adminobs)
|
||||
reset_view(null)
|
||||
switch(health)
|
||||
if(100 to INFINITY)
|
||||
healths.icon_state = "health0"
|
||||
if(80 to 100)
|
||||
healths.icon_state = "health1"
|
||||
if(60 to 80)
|
||||
healths.icon_state = "health2"
|
||||
if(40 to 60)
|
||||
healths.icon_state = "health3"
|
||||
if(20 to 40)
|
||||
healths.icon_state = "health4"
|
||||
if(0 to 20)
|
||||
healths.icon_state = "health5"
|
||||
else
|
||||
healths.icon_state = "health6"
|
||||
else
|
||||
healths.icon_state = "health7"
|
||||
|
||||
return 1
|
||||
if (client)
|
||||
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
|
||||
|
||||
if ((blind && stat != 2))
|
||||
if ((blinded))
|
||||
blind.layer = 18
|
||||
else
|
||||
blind.layer = 0
|
||||
|
||||
if (disabilities & NEARSIGHTED)
|
||||
client.screen += global_hud.vimpaired
|
||||
|
||||
if (eye_blurry)
|
||||
client.screen += global_hud.blurry
|
||||
|
||||
if (druggy)
|
||||
client.screen += global_hud.druggy
|
||||
|
||||
if (stat != 2)
|
||||
if (machine)
|
||||
if (!( machine.check_eye(src) ))
|
||||
reset_view(null)
|
||||
else
|
||||
if(client && !client.adminobs)
|
||||
reset_view(null)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/*/mob/living/carbon/brain/emp_act(severity)
|
||||
|
||||
@@ -5,41 +5,47 @@
|
||||
icon_state = "posibrain"
|
||||
w_class = 3
|
||||
origin_tech = list(TECH_ENGINERING = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2, TECH_DATA = 4)
|
||||
var/searching = 0
|
||||
|
||||
construction_cost = list(DEFAULT_WALL_MATERIAL=500,"glass"=500,"silver"=200,"gold"=200,"phoron"=100,"diamond"=10)
|
||||
construction_time = 75
|
||||
var/searching = 0
|
||||
var/askDelay = 10 * 60 * 1
|
||||
req_access = list(access_robotics)
|
||||
locked = 0
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/New()
|
||||
..()
|
||||
brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
|
||||
brainmob.real_name = src.brainmob.name
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/attack_self(var/mob/user)
|
||||
if(brainmob && !brainmob.key && !searching)
|
||||
/obj/item/device/mmi/digital/posibrain/attack_self(mob/user as mob)
|
||||
if(brainmob && !brainmob.key && searching == 0)
|
||||
//Start the process of searching for a new user.
|
||||
user << "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
|
||||
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
|
||||
icon_state = "posibrain-searching"
|
||||
searching = 1
|
||||
var/datum/ghosttrap/G = get_ghost_trap("positronic brain")
|
||||
G.request_player(brainmob, "A [src.name] has been booted by \the [user] in [get_area(user)]. ")
|
||||
src.searching = 1
|
||||
src.request_player()
|
||||
spawn(600) reset_search()
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/attack_ghost(var/mob/dead/observer/user)
|
||||
var/datum/ghosttrap/G = get_ghost_trap("positronic brain")
|
||||
if(!G.assess_candidate(user))
|
||||
return
|
||||
var/response = alert(user, "Are you sure you want to play as a positronic brain?", "Positronic brain request", "Yes", "No")
|
||||
if(response == "Yes")
|
||||
if(G.transfer_personality(user, brainmob))
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='notice'>\The [src] chimes quietly.</span>")
|
||||
searching = 0
|
||||
name = "positronic brain ([brainmob.name])"
|
||||
icon_state = "posibrain-occupied"
|
||||
return
|
||||
/obj/item/device/mmi/digital/posibrain/proc/request_player()
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(!O.MayRespawn())
|
||||
continue
|
||||
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))
|
||||
continue
|
||||
if(O.client)
|
||||
if(O.client.prefs.be_special & BE_AI)
|
||||
question(O.client)
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/proc/question(var/client/C)
|
||||
spawn(0)
|
||||
if(!C) return
|
||||
var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
|
||||
if(response == "Yes")
|
||||
response = alert(C, "Are you sure you want to play as a positronic brain?", "Positronic brain request", "Yes", "No")
|
||||
if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
|
||||
if(response == "Yes")
|
||||
transfer_personality(C.mob)
|
||||
else if (response == "Never for this round")
|
||||
C.prefs.be_special ^= BE_AI
|
||||
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/transfer_identity(var/mob/living/carbon/H)
|
||||
..()
|
||||
@@ -49,19 +55,40 @@
|
||||
icon_state = "posibrain-occupied"
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/proc/reset_search()
|
||||
if(!searching || (src.brainmob && src.brainmob.key))
|
||||
return
|
||||
searching = 0
|
||||
/obj/item/device/mmi/digital/posibrain/proc/transfer_personality(var/mob/candidate)
|
||||
announce_ghost_joinleave(candidate, 0, "They are occupying a positronic brain now.")
|
||||
src.searching = 0
|
||||
src.brainmob.mind = candidate.mind
|
||||
src.brainmob.ckey = candidate.ckey
|
||||
src.brainmob.mind.reset()
|
||||
src.name = "positronic brain ([src.brainmob.name])"
|
||||
src.brainmob << "<b>You are a positronic brain, brought into existence on [station_name()].</b>"
|
||||
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
|
||||
src.brainmob << "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
|
||||
src.brainmob << "<b>Use say :b to speak to other artificial intelligences.</b>"
|
||||
src.brainmob.mind.assigned_role = "Positronic Brain"
|
||||
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message("\blue The positronic brain chimes quietly.")
|
||||
icon_state = "posibrain-occupied"
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
|
||||
|
||||
if(src.brainmob && src.brainmob.key) return
|
||||
|
||||
src.searching = 0
|
||||
icon_state = "posibrain"
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='notice'>\The [src] brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>")
|
||||
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/examine(mob/user)
|
||||
if(!..(user))
|
||||
return
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
var/msg = "<span class='info'>*---------*</span>\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
if(src.brainmob && src.brainmob.key)
|
||||
@@ -72,7 +99,7 @@
|
||||
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
|
||||
else
|
||||
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
|
||||
msg += "<span class='info'>*---------*</span>"
|
||||
msg += "</span><span class='info'>*---------*</span>"
|
||||
user << msg
|
||||
return
|
||||
|
||||
@@ -89,3 +116,7 @@
|
||||
src.brainmob.emp_damage += rand(0,10)
|
||||
..()
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/New()
|
||||
..()
|
||||
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
|
||||
src.brainmob.real_name = src.brainmob.name
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
//Common breathing procs
|
||||
|
||||
//Start of a breath chain, calls breathe()
|
||||
/mob/living/carbon/handle_breathing()
|
||||
if(air_master.current_cycle%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath
|
||||
breathe()
|
||||
|
||||
/mob/living/carbon/proc/breathe()
|
||||
//if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
if(species && (species.flags & NO_BREATHE)) return
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/mob/living/carbon/New()
|
||||
create_reagents(1000)
|
||||
var/datum/reagents/R1 = new/datum/reagents(1000)
|
||||
var/datum/reagents/R2 = new/datum/reagents(1000)
|
||||
ingested = R1
|
||||
touching = R2
|
||||
R1.my_atom = src
|
||||
R2.my_atom = src
|
||||
//setup reagent holders
|
||||
bloodstr = new/datum/reagents/metabolism(1000, src, CHEM_BLOOD)
|
||||
ingested = new/datum/reagents/metabolism(1000, src, CHEM_INGEST)
|
||||
touching = new/datum/reagents/metabolism(1000, src, CHEM_TOUCH)
|
||||
reagents = bloodstr
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/Life()
|
||||
@@ -210,32 +209,32 @@
|
||||
if(!org.is_usable())
|
||||
status += "dangling uselessly"
|
||||
if(status.len)
|
||||
src.show_message("My [org.name] is <span class='warning'> [english_list(status)].",1)
|
||||
src.show_message("My [org.name] is <span class='warning'> [english_list(status)].</span>",1)
|
||||
else
|
||||
src.show_message("My [org.name] is <span class='notice'> OK.",1)
|
||||
src.show_message("My [org.name] is <span class='notice'> OK.</span>",1)
|
||||
|
||||
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
||||
H.play_xylophone()
|
||||
else if (on_fire)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
if (M.on_fire)
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames, but to no avail!</span>", \
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames, but to no avail!</span>",
|
||||
"<span class='warning'>You try to pat out [src]'s flames, but to no avail! Put yourself out first!</span>")
|
||||
else
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames!</span>", \
|
||||
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames!</span>",
|
||||
"<span class='warning'>You try to pat out [src]'s flames! Hot!</span>")
|
||||
if(do_mob(M, src, 15))
|
||||
if (prob(10) && (M.fire_stacks <= 0))
|
||||
src.fire_stacks -= 2
|
||||
src.fire_stacks -= 0.5
|
||||
M.fire_stacks += 1
|
||||
M.IgniteMob()
|
||||
if (M.on_fire)
|
||||
M.visible_message("<span class='danger'>The fire spreads from [src] to [M]!</span>", \
|
||||
M.visible_message("<span class='danger'>The fire spreads from [src] to [M]!</span>",
|
||||
"<span class='danger'>The fire spreads to you as well!</span>")
|
||||
else
|
||||
src.fire_stacks -= 3 //Less effective than stop, drop, and roll
|
||||
src.fire_stacks -= 0.5 //Less effective than stop, drop, and roll - also accounting for the fact that it takes half as long.
|
||||
if (src.fire_stacks <= 0)
|
||||
M.visible_message("<span class='warning'>[M] successfully pats out [src]'s flames.</span>", \
|
||||
M.visible_message("<span class='warning'>[M] successfully pats out [src]'s flames.</span>",
|
||||
"<span class='warning'>You successfully pat out [src]'s flames.</span>")
|
||||
src.ExtinguishMob()
|
||||
src.fire_stacks = 0
|
||||
@@ -259,8 +258,8 @@
|
||||
src.sleeping = max(0,src.sleeping-5)
|
||||
if(src.sleeping == 0)
|
||||
src.resting = 0
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!", \
|
||||
"<span class='notice'>You shake [src] trying to wake [t_him] up!")
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to wake [t_him] up!</span>")
|
||||
else
|
||||
if(istype(H))
|
||||
H.species.hug(H,src)
|
||||
@@ -341,7 +340,7 @@
|
||||
|
||||
if (istype(item, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = item
|
||||
item = G.throw() //throw the person instead of the grab
|
||||
item = G.throw_held() //throw the person instead of the grab
|
||||
if(ismob(item))
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
@@ -382,7 +381,8 @@
|
||||
|
||||
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
bodytemperature = max(bodytemperature, BODYTEMP_HEAT_DAMAGE_LIMIT+10)
|
||||
var/temp_inc = max(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), 0)
|
||||
bodytemperature = min(bodytemperature + temp_inc, exposed_temperature)
|
||||
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
//Active emote/pose
|
||||
var/pose = null
|
||||
var/list/chem_effects = list()
|
||||
var/datum/reagents/ingested = null
|
||||
var/datum/reagents/touching = null
|
||||
var/datum/reagents/metabolism/bloodstr = null
|
||||
var/datum/reagents/metabolism/ingested = null
|
||||
var/datum/reagents/metabolism/touching = null
|
||||
|
||||
var/pulse = PULSE_NORM //current pulse level
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = default_state)
|
||||
var/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
AC.flags = flags
|
||||
AC.ui_interact(user, state = state)
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
..()
|
||||
|
||||
if(dna)
|
||||
dna.ready_dna(src)
|
||||
dna.real_name = real_name
|
||||
sync_organ_dna()
|
||||
make_blood()
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
@@ -177,22 +179,6 @@
|
||||
apply_damage(rand(30,40), BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/meteorhit(O as obj)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [src] has been hit by [O]", 1)
|
||||
if (health > 0)
|
||||
var/obj/item/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head"))
|
||||
if(!affecting) return
|
||||
if (istype(O, /obj/effect/immovablerod))
|
||||
if(affecting.take_damage(101, 0))
|
||||
UpdateDamageIcon()
|
||||
else
|
||||
if(affecting.take_damage((istype(O, /obj/effect/meteor/small) ? 10 : 25), 30))
|
||||
UpdateDamageIcon()
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/implant_loyalty(mob/living/carbon/human/M, override = FALSE) // Won't override by default.
|
||||
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
|
||||
|
||||
@@ -713,7 +699,7 @@
|
||||
if(species.has_fine_manipulation)
|
||||
return 1
|
||||
if(!silent)
|
||||
src << "<span class='warning'>You don't have the dexterity to use that!<span>"
|
||||
src << "<span class='warning'>You don't have the dexterity to use that!</span>"
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/abiotic(var/full_body = 0)
|
||||
@@ -960,7 +946,6 @@
|
||||
V.cure(src)
|
||||
|
||||
losebreath = 0
|
||||
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
|
||||
|
||||
..()
|
||||
|
||||
|
||||
@@ -438,4 +438,41 @@ emp_act
|
||||
if(!istype(wear_suit,/obj/item/clothing/suit/space)) return
|
||||
var/obj/item/clothing/suit/space/SS = wear_suit
|
||||
var/penetrated_dam = max(0,(damage - SS.breach_threshold))
|
||||
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
|
||||
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
|
||||
|
||||
/mob/living/carbon/human/reagent_permeability()
|
||||
var/perm = 0
|
||||
|
||||
var/list/perm_by_part = list(
|
||||
"head" = THERMAL_PROTECTION_HEAD,
|
||||
"upper_torso" = THERMAL_PROTECTION_UPPER_TORSO,
|
||||
"lower_torso" = THERMAL_PROTECTION_LOWER_TORSO,
|
||||
"legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT,
|
||||
"feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT,
|
||||
"arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT,
|
||||
"hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT
|
||||
)
|
||||
|
||||
for(var/obj/item/clothing/C in src.get_equipped_items())
|
||||
if(C.permeability_coefficient == 1 || !C.body_parts_covered)
|
||||
continue
|
||||
if(C.body_parts_covered & HEAD)
|
||||
perm_by_part["head"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & UPPER_TORSO)
|
||||
perm_by_part["upper_torso"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & LOWER_TORSO)
|
||||
perm_by_part["lower_torso"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & LEGS)
|
||||
perm_by_part["legs"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & FEET)
|
||||
perm_by_part["feet"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & ARMS)
|
||||
perm_by_part["arms"] *= C.permeability_coefficient
|
||||
if(C.body_parts_covered & HANDS)
|
||||
perm_by_part["hands"] *= C.permeability_coefficient
|
||||
|
||||
for(var/part in perm_by_part)
|
||||
perm += perm_by_part[part]
|
||||
|
||||
return perm
|
||||
|
||||
|
||||
@@ -71,8 +71,6 @@
|
||||
var/miming = null //Toggle for the mime's abilities.
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
|
||||
var/last_dam = -1 //Used for determining if we need to process all organs or just some or even none.
|
||||
var/list/bad_external_organs = list()// organs we check until they are good.
|
||||
|
||||
|
||||
@@ -171,4 +171,9 @@
|
||||
//New are added for reagents to random organs.
|
||||
for(var/datum/reagent/A in reagents.reagent_list)
|
||||
var/obj/item/organ/O = pick(organs)
|
||||
O.trace_chemicals[A.name] = 100
|
||||
O.trace_chemicals[A.name] = 100
|
||||
|
||||
/mob/living/carbon/human/proc/sync_organ_dna()
|
||||
var/list/all_bits = internal_organs|organs
|
||||
for(var/obj/item/organ/O in all_bits)
|
||||
O.set_dna(dna)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
remains_type = /obj/effect/decal/cleanable/ash
|
||||
death_message = "dissolves into ash..."
|
||||
|
||||
flags = IS_RESTRICTED | NO_BLOOD | NO_POISON | NO_SCAN | NO_SLIP | NO_POISON
|
||||
flags = IS_RESTRICTED | NO_BLOOD | NO_SCAN | NO_SLIP | NO_POISON
|
||||
|
||||
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
|
||||
spawn(1)
|
||||
|
||||
@@ -14,7 +14,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | AIRTIGHT
|
||||
body_parts_covered = FACE|EYES
|
||||
throw_range = 5
|
||||
|
||||
@@ -426,7 +426,7 @@ var/global/list/damage_icon_parts = list()
|
||||
//For legacy support.
|
||||
/mob/living/carbon/human/regenerate_icons()
|
||||
..()
|
||||
if(monkeyizing) return
|
||||
if(transforming) return
|
||||
|
||||
update_mutations(0)
|
||||
update_body(0)
|
||||
@@ -636,16 +636,23 @@ var/global/list/damage_icon_parts = list()
|
||||
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
|
||||
if(head)
|
||||
head.screen_loc = ui_head //TODO
|
||||
var/image/standing
|
||||
if(istype(head,/obj/item/clothing/head/kitty))
|
||||
standing = image("icon" = head:mob)
|
||||
else
|
||||
if(head.icon_override)
|
||||
standing = image("icon" = head.icon_override, "icon_state" = "[head.icon_state]")
|
||||
else if(head.sprite_sheets && head.sprite_sheets[species.name])
|
||||
standing = image("icon" = head.sprite_sheets[species.name], "icon_state" = "[head.icon_state]")
|
||||
else
|
||||
standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")
|
||||
|
||||
//Determine the icon to use
|
||||
var/t_icon = INV_HEAD_DEF_ICON
|
||||
if(head.icon_override)
|
||||
t_icon = head.icon_override
|
||||
else if(head.sprite_sheets && head.sprite_sheets[species.name])
|
||||
t_icon = head.sprite_sheets[species.name]
|
||||
|
||||
//Determine the state to use
|
||||
var/t_state = head.icon_state
|
||||
if(istype(head, /obj/item/weapon/paper))
|
||||
/* I don't like this, but bandaid to fix half the hats in the game
|
||||
being completely broken without re-breaking paper hats */
|
||||
t_state = "paper"
|
||||
|
||||
//Create the image
|
||||
var/image/standing = image(icon = t_icon, icon_state = t_state)
|
||||
|
||||
if(head.blood_DNA)
|
||||
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood")
|
||||
@@ -929,7 +936,7 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
tail_overlay = set_tail_state(t_state)
|
||||
if(tail_overlay)
|
||||
spawn(15)
|
||||
spawn(20)
|
||||
//check that the animation hasn't changed in the meantime
|
||||
if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == t_state)
|
||||
animate_tail_stop()
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
if(10)
|
||||
msg += "<span class='warning'><B>It is radiating with massive levels of electrical activity!</B></span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
msg += "*---------*"
|
||||
user << msg
|
||||
return
|
||||
@@ -1,2 +1,2 @@
|
||||
/mob/living/carbon/slime/regular_hud_updates()
|
||||
/mob/living/carbon/slime/handle_regular_hud_updates()
|
||||
return
|
||||
@@ -2,13 +2,12 @@
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
|
||||
if (src.monkeyizing)
|
||||
if (src.transforming)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_chemicals_in_body()
|
||||
handle_nutrition()
|
||||
|
||||
if (!client)
|
||||
@@ -18,18 +17,7 @@
|
||||
handle_AI()
|
||||
handle_speech_and_mood()
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(src.loc)
|
||||
environment = loc.return_air()
|
||||
|
||||
regular_hud_updates()
|
||||
|
||||
if(environment)
|
||||
handle_environment(environment) // Handle temperature/pressure differences between body and environment
|
||||
|
||||
handle_regular_status_updates() // Status updates, death etc.
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_environment(datum/gas_mixture/environment)
|
||||
/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
adjustToxLoss(rand(10,20))
|
||||
return
|
||||
@@ -81,16 +69,13 @@
|
||||
temp_change = (temperature - current)
|
||||
return temp_change
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_chemicals_in_body()
|
||||
/mob/living/carbon/slime/handle_chemicals_in_body()
|
||||
chem_effects.Cut()
|
||||
analgesic = 0
|
||||
|
||||
if(touching)
|
||||
touching.metabolize(0, CHEM_TOUCH)
|
||||
if(ingested)
|
||||
ingested.metabolize(0, CHEM_INGEST)
|
||||
if(reagents)
|
||||
reagents.metabolize(0, CHEM_BLOOD)
|
||||
if(touching) touching.metabolize()
|
||||
if(ingested) ingested.metabolize()
|
||||
if(bloodstr) bloodstr.metabolize()
|
||||
|
||||
if(CE_PAINKILLER in chem_effects)
|
||||
analgesic = chem_effects[CE_PAINKILLER]
|
||||
@@ -99,7 +84,7 @@
|
||||
|
||||
return //TODO: DEFERRED
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_regular_status_updates()
|
||||
/mob/living/carbon/slime/handle_regular_status_updates()
|
||||
|
||||
src.blinded = null
|
||||
|
||||
|
||||
@@ -220,15 +220,6 @@
|
||||
/mob/living/carbon/slime/attack_ui(slot)
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/meteorhit(O as obj)
|
||||
visible_message("<span class='warning'>[src] has been hit by [O]</span>")
|
||||
|
||||
adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
|
||||
adjustFireLoss(30)
|
||||
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob)
|
||||
|
||||
..()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
//drop && roll
|
||||
if(on_fire)
|
||||
fire_stacks -= 2 //reduced
|
||||
fire_stacks -= 1.2
|
||||
Weaken(3)
|
||||
spin(32,2)
|
||||
visible_message(
|
||||
@@ -19,17 +19,18 @@
|
||||
ExtinguishMob()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(handcuffed)
|
||||
spawn() escape_handcuffs()
|
||||
else if(legcuffed)
|
||||
spawn() escape_legcuffs()
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/proc/escape_handcuffs()
|
||||
if(!canClick())
|
||||
return
|
||||
/mob/living/carbon/proc/escape_handcuffs()
|
||||
//if(!(last_special <= world.time)) return
|
||||
|
||||
//These two lines represent a significant buff to grabs...
|
||||
if(!canClick()) return
|
||||
changeNextMove(100)
|
||||
|
||||
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/mob/living/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (transforming)
|
||||
return
|
||||
if(!loc)
|
||||
return
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Breathing, if applicable
|
||||
handle_breathing()
|
||||
|
||||
//Mutations and radiation
|
||||
handle_mutations_and_radiation()
|
||||
|
||||
//Chemicals in the body
|
||||
handle_chemicals_in_body()
|
||||
|
||||
//Blood
|
||||
handle_blood()
|
||||
|
||||
//Random events (vomiting etc)
|
||||
handle_random_events()
|
||||
|
||||
. = 1
|
||||
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
if(environment)
|
||||
handle_environment(environment)
|
||||
|
||||
//Check if we're on fire
|
||||
handle_fire()
|
||||
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
|
||||
update_pulling()
|
||||
|
||||
for(var/obj/item/weapon/grab/G in src)
|
||||
G.process()
|
||||
|
||||
if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc.
|
||||
handle_disabilities() // eye, ear, brain damages
|
||||
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
|
||||
|
||||
handle_actions()
|
||||
|
||||
update_canmove()
|
||||
|
||||
if(client)
|
||||
handle_regular_hud_updates()
|
||||
|
||||
/mob/living/proc/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_mutations_and_radiation()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_chemicals_in_body()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_blood()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_random_events()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_environment(var/datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_stomach()
|
||||
return
|
||||
|
||||
/mob/living/proc/update_pulling()
|
||||
if(pulling)
|
||||
if(incapacitated())
|
||||
stop_pulling()
|
||||
|
||||
//This updates the health and status of the mob (conscious, unconscious, dead)
|
||||
/mob/living/proc/handle_regular_status_updates()
|
||||
updatehealth()
|
||||
if(stat != DEAD)
|
||||
if(paralysis)
|
||||
stat = UNCONSCIOUS
|
||||
else if (status_flags & FAKEDEATH)
|
||||
stat = UNCONSCIOUS
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
return 1
|
||||
|
||||
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
|
||||
/mob/living/proc/handle_status_effects()
|
||||
if(paralysis)
|
||||
paralysis = max(paralysis-1,0)
|
||||
if(stunned)
|
||||
stunned = max(stunned-1,0)
|
||||
if(!stunned)
|
||||
update_icons()
|
||||
|
||||
if(weakened)
|
||||
weakened = max(weakened-1,0)
|
||||
if(!weakened)
|
||||
update_icons()
|
||||
|
||||
/mob/living/proc/handle_disabilities()
|
||||
//Eyes
|
||||
if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
|
||||
eye_blind = max(eye_blind, 1)
|
||||
else if(eye_blind) //blindness, heals slowly over time
|
||||
eye_blind = max(eye_blind-1,0)
|
||||
else if(eye_blurry) //blurry eyes heal slowly
|
||||
eye_blurry = max(eye_blurry-1, 0)
|
||||
|
||||
//Ears
|
||||
if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
|
||||
setEarDamage(-1, max(ear_deaf, 1))
|
||||
else
|
||||
// deafness heals slowly over time, unless ear_damage is over 100
|
||||
if(ear_damage < 100)
|
||||
adjustEarDamage(-0.05,-1)
|
||||
|
||||
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
||||
/mob/living/handle_regular_hud_updates()
|
||||
if(!client) return 0
|
||||
..()
|
||||
|
||||
handle_vision()
|
||||
handle_hud_icons()
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/proc/handle_vision()
|
||||
return
|
||||
|
||||
/mob/living/proc/update_sight()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_hud_icons()
|
||||
handle_hud_icons_health()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_hud_icons_health()
|
||||
return
|
||||
@@ -1,8 +1,3 @@
|
||||
/mob/living/Life()
|
||||
..()
|
||||
if(stat != DEAD)
|
||||
handle_actions()
|
||||
|
||||
//mob verbs are faster than object verbs. See mob/verb/examine.
|
||||
/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1))
|
||||
set name = "Pull"
|
||||
@@ -453,6 +448,9 @@ default behaviour is:
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
BITSET(hud_updateflag, STATUS_HUD)
|
||||
BITSET(hud_updateflag, LIFE_HUD)
|
||||
|
||||
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
|
||||
|
||||
return
|
||||
|
||||
/mob/living/proc/UpdateDamageIcon()
|
||||
@@ -797,3 +795,15 @@ default behaviour is:
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
//damage/heal the mob ears and adjust the deaf amount
|
||||
/mob/living/adjustEarDamage(var/damage, var/deaf)
|
||||
ear_damage = max(0, ear_damage + damage)
|
||||
ear_deaf = max(0, ear_deaf + deaf)
|
||||
|
||||
//pass a negative argument to skip one of the variable
|
||||
/mob/living/setEarDamage(var/damage, var/deaf)
|
||||
if(damage >= 0)
|
||||
ear_damage = damage
|
||||
if(deaf >= 0)
|
||||
ear_deaf = deaf
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
|
||||
/mob/living/proc/handle_fire()
|
||||
if(fire_stacks < 0)
|
||||
fire_stacks = max(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
fire_stacks = min(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
|
||||
if(!on_fire)
|
||||
return 1
|
||||
@@ -236,20 +236,27 @@
|
||||
location.hotspot_expose(fire_burn_temperature(), 50, 1)
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(0.5)
|
||||
adjust_fire_stacks(2)
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/proc/get_cold_protection()
|
||||
return 0
|
||||
|
||||
/mob/living/proc/get_heat_protection()
|
||||
return 0
|
||||
|
||||
//Finds the effective temperature that the mob is burning at.
|
||||
/mob/living/proc/fire_burn_temperature()
|
||||
if (fire_stacks <= 0)
|
||||
return 0
|
||||
|
||||
//Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot.
|
||||
return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2)
|
||||
//lower limit of 700 K, same as matches and roughly the temperature of a cool flame.
|
||||
return max(2.25*round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2), 700)
|
||||
|
||||
/mob/living/regular_hud_updates()
|
||||
..()
|
||||
update_action_buttons()
|
||||
/mob/living/proc/reagent_permeability()
|
||||
return 1
|
||||
return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2)
|
||||
|
||||
/mob/living/proc/handle_actions()
|
||||
//Pretty bad, i'd use picked/dropped instead but the parent calls in these are nonexistent
|
||||
@@ -324,50 +331,54 @@
|
||||
|
||||
//If simple_animals are ever moved under carbon, then this can probably be moved to carbon as well
|
||||
/mob/living/proc/attack_throat(obj/item/W, obj/item/weapon/grab/G, mob/user)
|
||||
|
||||
|
||||
// Knifing
|
||||
if(!W.edge || !W.force || W.damtype != BRUTE) return //unsuitable weapon
|
||||
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] begins to slit [src]'s throat with \the [W]!</span>")
|
||||
|
||||
|
||||
user.next_move = world.time + 20 //also should prevent user from triggering this repeatedly
|
||||
if(!do_after(user, 20))
|
||||
return
|
||||
if(!(G && G.assailant == user && G.affecting == src)) //check that we still have a grab
|
||||
return
|
||||
|
||||
|
||||
var/damage_mod = 1
|
||||
//presumably, if they are wearing a helmet that stops pressure effects, then it probably covers the throat as well
|
||||
var/obj/item/clothing/head/helmet = get_equipped_item(slot_head)
|
||||
if(istype(helmet) && (helmet.body_parts_covered & HEAD) && (helmet.flags & STOPPRESSUREDAMAGE))
|
||||
//we don't do an armor_check here because this is not an impact effect like a weapon swung with momentum, that either penetrates or glances off.
|
||||
damage_mod = 1.0 - (helmet.armor["melee"]/100)
|
||||
|
||||
|
||||
var/total_damage = 0
|
||||
for(var/i in 1 to 3)
|
||||
var/damage = min(W.force*1.5, 20)*damage_mod
|
||||
apply_damage(damage, W.damtype, "head", 0, sharp=W.sharp, edge=W.edge)
|
||||
total_damage += damage
|
||||
|
||||
|
||||
var/oxyloss = total_damage
|
||||
if(total_damage >= 40) //threshold to make someone pass out
|
||||
oxyloss = 60 // Brain lacks oxygen immediately, pass out
|
||||
|
||||
|
||||
adjustOxyLoss(min(oxyloss, 100 - getOxyLoss())) //don't put them over 100 oxyloss
|
||||
|
||||
|
||||
if(total_damage)
|
||||
if(oxyloss >= 40)
|
||||
user.visible_message("<span class='danger'>\The [user] slit [src]'s throat open with \the [W]!</span>")
|
||||
else
|
||||
user.visible_message("<span class='danger'>\The [user] cut [src]'s neck with \the [W]!</span>")
|
||||
|
||||
|
||||
if(W.hitsound)
|
||||
playsound(loc, W.hitsound, 50, 1, -1)
|
||||
|
||||
|
||||
G.last_action = world.time
|
||||
flick(G.hud.icon_state, G.hud)
|
||||
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Knifed [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])</font>"
|
||||
src.attack_log += "\[[time_stamp()]\]<font color='orange'> Got knifed by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])</font>"
|
||||
msg_admin_attack("[key_name(user)] knifed [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" )
|
||||
return
|
||||
|
||||
/mob/living/incapacitated()
|
||||
if(stat || paralysis || stunned || weakened || restrained())
|
||||
return 1
|
||||
|
||||
@@ -43,3 +43,6 @@
|
||||
var/on_fire = 0 //The "Are we on fire?" var
|
||||
var/fire_stacks
|
||||
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ var/list/ai_verbs_default = list(
|
||||
var/obj/item/device/pda/ai/aiPDA = null
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null
|
||||
var/custom_sprite = 0 //For our custom sprites
|
||||
var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through.
|
||||
var/datum/trackable/track = null
|
||||
var/last_announcement = ""
|
||||
@@ -80,6 +79,9 @@ var/list/ai_verbs_default = list(
|
||||
var/override_CPUStorage = 0 // Bonus/Penalty CPU Storage. For use by admins/testers.
|
||||
var/override_CPURate = 0 // Bonus/Penalty CPU generation rate. For use by admins/testers.
|
||||
|
||||
var/datum/ai_icon/selected_sprite // The selected icon set
|
||||
var/custom_sprite = 0 // Whether the selected icon is custom
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/add_ai_verbs()
|
||||
src.verbs |= ai_verbs_default
|
||||
@@ -196,12 +198,34 @@ var/list/ai_verbs_default = list(
|
||||
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
|
||||
|
||||
job = "AI"
|
||||
setup_icon()
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
ai_list -= src
|
||||
qdel(eyeobj)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/proc/setup_icon()
|
||||
var/file = file2text("config/custom_sprites.txt")
|
||||
var/lines = text2list(file, "\n")
|
||||
|
||||
for(var/line in lines)
|
||||
// split & clean up
|
||||
var/list/Entry = text2list(line, ":")
|
||||
for(var/i = 1 to Entry.len)
|
||||
Entry[i] = trim(Entry[i])
|
||||
|
||||
if(Entry.len < 2)
|
||||
continue;
|
||||
|
||||
if(Entry[1] == src.ckey && Entry[2] == src.real_name)
|
||||
icon = CUSTOM_ITEM_SYNTH
|
||||
custom_sprite = 1
|
||||
selected_sprite = new/datum/ai_icon("Custom", "[src.ckey]-ai", "4", "[ckey]-ai-crash", "#FFFFFF", "#FFFFFF", "#FFFFFF")
|
||||
else
|
||||
selected_sprite = default_ai_icon
|
||||
updateicon()
|
||||
|
||||
/mob/living/silicon/ai/pointed(atom/A as mob|obj|turf in view())
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
@@ -263,57 +287,11 @@ var/list/ai_verbs_default = list(
|
||||
set name = "Set AI Core Display"
|
||||
if(stat || aiRestorePowerRoutine)
|
||||
return
|
||||
if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
|
||||
var/file = file2text("config/custom_sprites.txt")
|
||||
var/lines = text2list(file, "\n")
|
||||
|
||||
for(var/line in lines)
|
||||
// split & clean up
|
||||
var/list/Entry = text2list(line, ":")
|
||||
for(var/i = 1 to Entry.len)
|
||||
Entry[i] = trim(Entry[i])
|
||||
|
||||
if(Entry.len < 2)
|
||||
continue;
|
||||
|
||||
if(Entry[1] == src.ckey && Entry[2] == src.real_name)
|
||||
custom_sprite = 1 //They're in the list? Custom sprite time
|
||||
icon = CUSTOM_ITEM_SYNTH
|
||||
|
||||
//if(icon_state == initial(icon_state))
|
||||
var/icontype = ""
|
||||
if (custom_sprite == 1) icontype = ("Custom")//automagically selects custom sprite if one is available
|
||||
else icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Rainbow", "Blue", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Soviet", "Trapped", "Heartline", "Chatterbox", "Helios", "Dug Too Deep", "Goon", "Database", "Glitchman", "Lonestar", "Nanotrasen")
|
||||
switch(icontype)
|
||||
if("Custom") icon_state = "[src.ckey]-ai"
|
||||
if("Rainbow") icon_state = "ai-clown"
|
||||
if("Monochrome") icon_state = "ai-mono"
|
||||
if("Inverted") icon_state = "ai-u"
|
||||
if("Firewall") icon_state = "ai-magma"
|
||||
if("Green") icon_state = "ai-wierd"
|
||||
if("Red") icon_state = "ai-red"
|
||||
if("Static") icon_state = "ai-static"
|
||||
if("Text") icon_state = "ai-text"
|
||||
if("Smiley") icon_state = "ai-smiley"
|
||||
if("Matrix") icon_state = "ai-matrix"
|
||||
if("Angry") icon_state = "ai-angryface"
|
||||
if("Dorf") icon_state = "ai-dorf"
|
||||
if("Bliss") icon_state = "ai-bliss"
|
||||
if("Triumvirate") icon_state = "ai-triumvirate"
|
||||
if("Triumvirate Static") icon_state = "ai-triumvirate-malf"
|
||||
if("Soviet") icon_state = "ai-redoctober"
|
||||
if("Trapped") icon_state = "ai-hades"
|
||||
if("Heartline") icon_state = "ai-heartline"
|
||||
if("Chatterbox") icon_state = "ai-president"
|
||||
if("Helios") icon_state = "ai-helios"
|
||||
if("Dug Too Deep") icon_state = "ai-toodeep"
|
||||
if("Goon") icon_state = "ai-goon"
|
||||
if("Database") icon_state = "ai-database"
|
||||
if("Glitchman") icon_state = "ai-glitchman"
|
||||
if("Lonestar") icon_state = "ai-lonestar"
|
||||
if("Nanotrasen") icon_state = "ai-nanotrasen"
|
||||
else icon_state = "ai"
|
||||
|
||||
if (!custom_sprite)
|
||||
var/new_sprite = input("Select an icon!", "AI", selected_sprite) as null|anything in ai_icons
|
||||
if(new_sprite) selected_sprite = new_sprite
|
||||
updateicon()
|
||||
|
||||
// this verb lets the ai see the stations manifest
|
||||
/mob/living/silicon/ai/proc/ai_roster()
|
||||
@@ -452,17 +430,6 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/meteorhit(obj/O as obj)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
M.show_message(text("\red [] has been hit by []", src, O), 1)
|
||||
//Foreach goto(19)
|
||||
if (health > 0)
|
||||
adjustBruteLoss(30)
|
||||
if ((O.icon_state == "flaming"))
|
||||
adjustFireLoss(40)
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/reset_view(atom/A)
|
||||
if(camera)
|
||||
camera.set_light(0)
|
||||
@@ -678,16 +645,20 @@ var/list/ai_verbs_default = list(
|
||||
set desc = "Augment visual feed with internal sensor overlays"
|
||||
toggle_sensor_mode()
|
||||
|
||||
/mob/living/silicon/ai/proc/check_unable(var/flags = 0)
|
||||
/mob/living/silicon/ai/proc/check_unable(var/flags = 0, var/feedback = 1)
|
||||
if(stat == DEAD)
|
||||
src << "<span class='warning'>You are dead!</span>"
|
||||
if(feedback) src << "<span class='warning'>You are dead!</span>"
|
||||
return 1
|
||||
|
||||
if(aiRestorePowerRoutine)
|
||||
if(feedback) src << "<span class='warning'>You lack power!</span>"
|
||||
return 1
|
||||
|
||||
if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
|
||||
src << "<span class='warning'>Wireless control is disabled!</span>"
|
||||
if(feedback) src << "<span class='warning'>Wireless control is disabled!</span>"
|
||||
return 1
|
||||
if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi)
|
||||
src << "<span class='warning'>System Error - Transceiver Disabled!</span>"
|
||||
if(feedback) src << "<span class='warning'>System Error - Transceiver Disabled!</span>"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -701,146 +672,18 @@ var/list/ai_verbs_default = list(
|
||||
return
|
||||
..()
|
||||
|
||||
// NEWMALF FUNCTIONS/PROCEDURES
|
||||
/mob/living/silicon/ai/updateicon()
|
||||
if(!selected_sprite) selected_sprite = default_ai_icon
|
||||
|
||||
// Sets up malfunction-related variables, research system and such.
|
||||
/mob/living/silicon/ai/proc/setup_for_malf()
|
||||
var/mob/living/silicon/ai/user = src
|
||||
// Setup Variables
|
||||
malfunctioning = 1
|
||||
research = new/datum/malf_research()
|
||||
research.owner = src
|
||||
hacked_apcs = list()
|
||||
recalc_cpu()
|
||||
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_select_hardware()
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_select_research()
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_help()
|
||||
|
||||
// And greet user with some OOC info.
|
||||
user << "You are malfunctioning, you do not have to follow any laws."
|
||||
user << "Use ai-help command to view relevant information about your abilities"
|
||||
|
||||
// Safely remove malfunction status, fixing hacked APCs and resetting variables.
|
||||
/mob/living/silicon/ai/proc/stop_malf()
|
||||
var/mob/living/silicon/ai/user = src
|
||||
// Generic variables
|
||||
malfunctioning = 0
|
||||
sleep(10)
|
||||
research = null
|
||||
// Fix hacked APCs
|
||||
if(hacked_apcs)
|
||||
for(var/obj/machinery/power/apc/A in hacked_apcs)
|
||||
A.hacker = null
|
||||
hacked_apcs = null
|
||||
// Reset our verbs
|
||||
src.verbs = null
|
||||
add_ai_verbs()
|
||||
// Let them know.
|
||||
user << "You are no longer malfunctioning. Your abilities have been removed."
|
||||
|
||||
// Called every tick. Checks if AI is malfunctioning. If yes calls Process on research datum which handles all logic.
|
||||
/mob/living/silicon/ai/proc/malf_process()
|
||||
if(!malfunctioning)
|
||||
return
|
||||
if(!research)
|
||||
if(!errored)
|
||||
errored = 1
|
||||
error("malf_process() called on AI without research datum. Report this.")
|
||||
message_admins("ERROR: malf_process() called on AI without research datum. If admin modified one of the AI's vars revert the change and don't modify variables directly, instead use ProcCall or admin panels.")
|
||||
spawn(1200)
|
||||
errored = 0
|
||||
return
|
||||
recalc_cpu()
|
||||
if(APU_power || aiRestorePowerRoutine != 0)
|
||||
research.process(1)
|
||||
if(stat == DEAD)
|
||||
icon_state = selected_sprite.dead_icon
|
||||
set_light(3, 1, selected_sprite.dead_light)
|
||||
else if(aiRestorePowerRoutine)
|
||||
icon_state = selected_sprite.nopower_icon
|
||||
set_light(1, 1, selected_sprite.nopower_light)
|
||||
else
|
||||
research.process(0)
|
||||
|
||||
// Recalculates CPU time gain and storage capacities.
|
||||
/mob/living/silicon/ai/proc/recalc_cpu()
|
||||
// AI Starts with these values.
|
||||
var/cpu_gain = 0.01
|
||||
var/cpu_storage = 10
|
||||
|
||||
// Off-Station APCs should not count towards CPU generation.
|
||||
for(var/obj/machinery/power/apc/A in hacked_apcs)
|
||||
if(A.z in config.station_levels)
|
||||
cpu_gain += 0.002
|
||||
cpu_storage += 10
|
||||
|
||||
research.max_cpu = cpu_storage + override_CPUStorage
|
||||
if(hardware && istype(hardware, /datum/malf_hardware/dual_ram))
|
||||
research.max_cpu = research.max_cpu * 1.5
|
||||
research.stored_cpu = min(research.stored_cpu, research.max_cpu)
|
||||
|
||||
research.cpu_increase_per_tick = cpu_gain + override_CPURate
|
||||
if(hardware && istype(hardware, /datum/malf_hardware/dual_cpu))
|
||||
research.cpu_increase_per_tick = research.cpu_increase_per_tick * 2
|
||||
|
||||
// Starts AI's APU generator
|
||||
/mob/living/silicon/ai/proc/start_apu(var/shutup = 0)
|
||||
if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
|
||||
if(!shutup)
|
||||
src << "You do not have an APU generator and you shouldn't have this verb. Report this."
|
||||
return
|
||||
if(hardware_integrity() < 50)
|
||||
if(!shutup)
|
||||
src << "<span class='notice'>Starting APU... <b>FAULT</b>(System Damaged)</span>"
|
||||
return
|
||||
if(!shutup)
|
||||
src << "Starting APU... ONLINE"
|
||||
APU_power = 1
|
||||
|
||||
// Stops AI's APU generator
|
||||
/mob/living/silicon/ai/proc/stop_apu(var/shutup = 0)
|
||||
if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
|
||||
return
|
||||
|
||||
if(APU_power)
|
||||
APU_power = 0
|
||||
if(!shutup)
|
||||
src << "Shutting down APU... DONE"
|
||||
|
||||
// Returns percentage of AI's remaining backup capacitor charge (maxhealth - oxyloss).
|
||||
/mob/living/silicon/ai/proc/backup_capacitor()
|
||||
return ((200 - getOxyLoss()) / 2)
|
||||
|
||||
// Returns percentage of AI's remaining hardware integrity (maxhealth - (bruteloss + fireloss))
|
||||
/mob/living/silicon/ai/proc/hardware_integrity()
|
||||
return (health-config.health_threshold_dead)/2
|
||||
|
||||
// Shows capacitor charge and hardware integrity information to the AI in Status tab.
|
||||
/mob/living/silicon/ai/show_system_integrity()
|
||||
if(!src.stat)
|
||||
stat(null, text("Hardware integrity: [hardware_integrity()]%"))
|
||||
stat(null, text("Internal capacitor: [backup_capacitor()]%"))
|
||||
else
|
||||
stat(null, text("Systems nonfunctional"))
|
||||
|
||||
// Shows AI Malfunction related information to the AI.
|
||||
/mob/living/silicon/ai/show_malf_ai()
|
||||
if(src.is_malf())
|
||||
if(src.hacked_apcs)
|
||||
stat(null, "Hacked APCs: [src.hacked_apcs.len]")
|
||||
stat(null, "System Status: [src.hacking ? "Busy" : "Stand-By"]")
|
||||
if(src.research)
|
||||
stat(null, "Available CPU: [src.research.stored_cpu] TFlops")
|
||||
stat(null, "Maximal CPU: [src.research.max_cpu] TFlops")
|
||||
stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick] TFlops/s")
|
||||
stat(null, "Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
|
||||
if(src.research.focus)
|
||||
stat(null, "Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
|
||||
if(system_override == 1)
|
||||
stat(null, "SYSTEM OVERRIDE INITIATED")
|
||||
else if(system_override == 2)
|
||||
stat(null, "SYSTEM OVERRIDE COMPLETED")
|
||||
|
||||
// Cleaner proc for creating powersupply for an AI.
|
||||
/mob/living/silicon/ai/proc/create_powersupply()
|
||||
if(psupply)
|
||||
del(psupply)
|
||||
psupply = new/obj/machinery/ai_powersupply(src)
|
||||
icon_state = selected_sprite.alive_icon
|
||||
set_light(1, 1, selected_sprite.alive_light)
|
||||
|
||||
#undef AI_CHECK_WIRELESS
|
||||
#undef AI_CHECK_RADIO
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
if (src.custom_sprite == 1)//check for custom AI sprite, defaulting to blue screen if no.
|
||||
icon_state = "[ckey]-ai-crash"
|
||||
else
|
||||
icon_state = "ai-crash"
|
||||
|
||||
if(src.eyeobj)
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
@@ -20,4 +15,5 @@
|
||||
var/obj/item/device/aicard/card = loc
|
||||
card.update_icon()
|
||||
|
||||
return ..(gibbed,"gives one shrill beep before falling lifeless.")
|
||||
. = ..(gibbed,"gives one shrill beep before falling lifeless.")
|
||||
density = 1
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if (src.stat == UNCONSCIOUS)
|
||||
msg += "It is non-responsive and displaying the text: \"RUNTIME: Sensory Overload, stack 26/3\".\n"
|
||||
msg += "</span>"
|
||||
msg += "*---------*</span>"
|
||||
msg += "*---------*"
|
||||
if(hardware && (hardware.owner == src))
|
||||
msg += "<br>"
|
||||
msg += hardware.get_examine_desc()
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
var/datum/ai_icon/default_ai_icon = new/datum/ai_icon/blue()
|
||||
var/list/datum/ai_icon/ai_icons
|
||||
|
||||
/datum/ai_icon
|
||||
var/name
|
||||
var/alive_icon
|
||||
var/alive_light = "#FFFFFF"
|
||||
var/nopower_icon = "4"
|
||||
var/nopower_light = "#FFFFFF"
|
||||
var/dead_icon = "ai-crash"
|
||||
var/dead_light = "#000099"
|
||||
|
||||
/datum/ai_icon/New(var/name, var/alive_icon, var/nopower_icon, var/dead_icon, var/alive_light, var/nopower_light, var/dead_light)
|
||||
if(name)
|
||||
src.name = name
|
||||
src.alive_icon = alive_icon
|
||||
src.nopower_icon = nopower_icon
|
||||
src.dead_icon = dead_icon
|
||||
src.alive_light = alive_light
|
||||
src.nopower_light = nopower_light
|
||||
src.dead_light = dead_light
|
||||
if(!ai_icons)
|
||||
ai_icons = list()
|
||||
init_subtypes(/datum/ai_icon, ai_icons)
|
||||
..()
|
||||
|
||||
/datum/ai_icon/red
|
||||
name = "Red"
|
||||
alive_icon = "ai-red"
|
||||
alive_light = "#F04848"
|
||||
|
||||
/datum/ai_icon/green
|
||||
name = "Green"
|
||||
alive_icon = "ai-wierd"
|
||||
alive_light = "#00FF99"
|
||||
|
||||
/datum/ai_icon/blue
|
||||
name = "Blue"
|
||||
alive_icon = "ai"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/angry
|
||||
name = "Angry"
|
||||
alive_icon = "ai-angryface"
|
||||
alive_light = "#FFFF33"
|
||||
|
||||
/datum/ai_icon/bliss
|
||||
name = "Bliss"
|
||||
alive_icon = "ai-bliss"
|
||||
alive_light = "#5C7A4A"
|
||||
|
||||
/datum/ai_icon/chatterbox
|
||||
name = "Chatterbox"
|
||||
alive_icon = "ai-president"
|
||||
alive_light = "#40666B"
|
||||
|
||||
/datum/ai_icon/database
|
||||
name = "Database"
|
||||
alive_icon = "ai-database"
|
||||
|
||||
/datum/ai_icon/dorf
|
||||
name = "Dorf"
|
||||
alive_icon = "ai-dorf"
|
||||
|
||||
/datum/ai_icon/dugtodeep
|
||||
name = "Dug Too Deep"
|
||||
alive_icon = "ai-toodeep"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/firewall
|
||||
name = "Firewall"
|
||||
alive_icon = "ai-magma"
|
||||
alive_light = "#FF4126"
|
||||
|
||||
/datum/ai_icon/glitchman
|
||||
name = "Glitchman"
|
||||
alive_icon = "ai-glitchman"
|
||||
|
||||
/datum/ai_icon/goon
|
||||
name = "Goon"
|
||||
alive_icon = "ai-goon"
|
||||
alive_light = "#3E5C80"
|
||||
|
||||
/datum/ai_icon/heartline
|
||||
name = "Heartline"
|
||||
alive_icon = "ai-heartline"
|
||||
dead_icon = "ai-heartline_dead"
|
||||
|
||||
/datum/ai_icon/helios
|
||||
name = "Helios"
|
||||
alive_icon = "ai-helios"
|
||||
alive_light = "#F2CF73"
|
||||
|
||||
/datum/ai_icon/inverted
|
||||
name = "Inverted"
|
||||
alive_icon = "ai-u"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/lonestar
|
||||
name = "Lonestar"
|
||||
alive_icon = "ai-lonestar"
|
||||
alive_light = "#58751C"
|
||||
|
||||
/datum/ai_icon/matrix
|
||||
name = "Matrix"
|
||||
alive_icon = "ai-matrix"
|
||||
alive_light = "#449944"
|
||||
|
||||
/datum/ai_icon/monochrome
|
||||
name = "Monochrome"
|
||||
alive_icon = "ai-mono"
|
||||
alive_light = "#585858"
|
||||
|
||||
/datum/ai_icon/nanotrasen
|
||||
name = "Nanotrasen"
|
||||
alive_icon = "ai-nanotrasen"
|
||||
alive_light = "#000029"
|
||||
|
||||
/datum/ai_icon/rainbow
|
||||
name = "Rainbow"
|
||||
alive_icon = "ai-clown"
|
||||
alive_light = "#E50213"
|
||||
|
||||
/datum/ai_icon/smiley
|
||||
name = "Smiley"
|
||||
alive_icon = "ai-smiley"
|
||||
alive_light = "#F3DD00"
|
||||
|
||||
/datum/ai_icon/soviet
|
||||
name = "Soviet"
|
||||
alive_icon = "ai-redoctober"
|
||||
alive_light = "#FF4307"
|
||||
|
||||
/datum/ai_icon/Static
|
||||
name = "Static"
|
||||
alive_icon = "ai-static"
|
||||
alive_light = "#4784C1"
|
||||
|
||||
/datum/ai_icon/text
|
||||
name = "Text"
|
||||
alive_icon = "ai-text"
|
||||
|
||||
/datum/ai_icon/trapped
|
||||
name = "Trapped"
|
||||
alive_icon = "ai-hades"
|
||||
|
||||
/datum/ai_icon/triumvirate_static
|
||||
name = "Triumvirate"
|
||||
alive_icon = "ai-triumvirate"
|
||||
alive_light = "#020B2B"
|
||||
|
||||
/datum/ai_icon/triumvirate_static
|
||||
name = "Triumvirate Static"
|
||||
alive_icon = "ai-static"
|
||||
alive_light = "#020B2B"
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/Life()
|
||||
if (src.stat == 2)
|
||||
if (src.stat == DEAD)
|
||||
return
|
||||
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
//Being dead doesn't mean your temperature never changes
|
||||
@@ -20,10 +20,6 @@
|
||||
if(!psupply)
|
||||
create_powersupply()
|
||||
|
||||
if (src.machine)
|
||||
if (!( src.machine.check_eye(src) ))
|
||||
src.reset_view(null)
|
||||
|
||||
// Handle power damage (oxy)
|
||||
if(aiRestorePowerRoutine != 0 && !APU_power)
|
||||
// Lose power
|
||||
@@ -33,8 +29,8 @@
|
||||
aiRestorePowerRoutine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
|
||||
adjustOxyLoss(-1)
|
||||
|
||||
// Handle EMP-stun
|
||||
handle_stunned()
|
||||
handle_stunned() // Handle EMP-stun
|
||||
lying = 0 // Handle lying down
|
||||
|
||||
malf_process()
|
||||
|
||||
@@ -61,15 +57,18 @@
|
||||
src << "Alert cancelled. Power has been restored without our assistance."
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else if (aiRestorePowerRoutine==3)
|
||||
src << "Alert cancelled. Power has been restored."
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else if (APU_power)
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else
|
||||
var/area/current_area = get_area(src)
|
||||
@@ -79,7 +78,7 @@
|
||||
aiRestorePowerRoutine = 1
|
||||
|
||||
//Blind the AI
|
||||
|
||||
updateicon()
|
||||
src.blind.screen_loc = "1,1 to 15,15"
|
||||
if (src.blind.layer!=18)
|
||||
src.blind.layer = 18
|
||||
@@ -147,11 +146,12 @@
|
||||
aiRestorePowerRoutine = 3
|
||||
src << "Here are your current laws:"
|
||||
show_laws()
|
||||
updateicon()
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
regular_hud_updates()
|
||||
handle_regular_hud_updates()
|
||||
switch(src.sensor_mode)
|
||||
if (SEC_HUD)
|
||||
process_sec_hud(src,0,src.eyeobj)
|
||||
@@ -176,3 +176,4 @@
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
..()
|
||||
add_ai_verbs(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
// NEWMALF FUNCTIONS/PROCEDURES
|
||||
|
||||
// Sets up malfunction-related variables, research system and such.
|
||||
/mob/living/silicon/ai/proc/setup_for_malf()
|
||||
var/mob/living/silicon/ai/user = src
|
||||
// Setup Variables
|
||||
malfunctioning = 1
|
||||
research = new/datum/malf_research()
|
||||
research.owner = src
|
||||
hacked_apcs = list()
|
||||
recalc_cpu()
|
||||
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_select_hardware()
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_select_research()
|
||||
verbs += new/datum/game_mode/malfunction/verb/ai_help()
|
||||
|
||||
// And greet user with some OOC info.
|
||||
user << "You are malfunctioning, you do not have to follow any laws."
|
||||
user << "Use ai-help command to view relevant information about your abilities"
|
||||
|
||||
// Safely remove malfunction status, fixing hacked APCs and resetting variables.
|
||||
/mob/living/silicon/ai/proc/stop_malf()
|
||||
var/mob/living/silicon/ai/user = src
|
||||
// Generic variables
|
||||
malfunctioning = 0
|
||||
sleep(10)
|
||||
research = null
|
||||
// Fix hacked APCs
|
||||
if(hacked_apcs)
|
||||
for(var/obj/machinery/power/apc/A in hacked_apcs)
|
||||
A.hacker = null
|
||||
hacked_apcs = null
|
||||
// Reset our verbs
|
||||
src.verbs = null
|
||||
add_ai_verbs()
|
||||
// Let them know.
|
||||
user << "You are no longer malfunctioning. Your abilities have been removed."
|
||||
|
||||
// Called every tick. Checks if AI is malfunctioning. If yes calls Process on research datum which handles all logic.
|
||||
/mob/living/silicon/ai/proc/malf_process()
|
||||
if(!malfunctioning)
|
||||
return
|
||||
if(!research)
|
||||
if(!errored)
|
||||
errored = 1
|
||||
error("malf_process() called on AI without research datum. Report this.")
|
||||
message_admins("ERROR: malf_process() called on AI without research datum. If admin modified one of the AI's vars revert the change and don't modify variables directly, instead use ProcCall or admin panels.")
|
||||
spawn(1200)
|
||||
errored = 0
|
||||
return
|
||||
recalc_cpu()
|
||||
if(APU_power || aiRestorePowerRoutine != 0)
|
||||
research.process(1)
|
||||
else
|
||||
research.process(0)
|
||||
|
||||
// Recalculates CPU time gain and storage capacities.
|
||||
/mob/living/silicon/ai/proc/recalc_cpu()
|
||||
// AI Starts with these values.
|
||||
var/cpu_gain = 0.01
|
||||
var/cpu_storage = 10
|
||||
|
||||
// Off-Station APCs should not count towards CPU generation.
|
||||
for(var/obj/machinery/power/apc/A in hacked_apcs)
|
||||
if(A.z in config.station_levels)
|
||||
cpu_gain += 0.002
|
||||
cpu_storage += 10
|
||||
|
||||
research.max_cpu = cpu_storage + override_CPUStorage
|
||||
if(hardware && istype(hardware, /datum/malf_hardware/dual_ram))
|
||||
research.max_cpu = research.max_cpu * 1.5
|
||||
research.stored_cpu = min(research.stored_cpu, research.max_cpu)
|
||||
|
||||
research.cpu_increase_per_tick = cpu_gain + override_CPURate
|
||||
if(hardware && istype(hardware, /datum/malf_hardware/dual_cpu))
|
||||
research.cpu_increase_per_tick = research.cpu_increase_per_tick * 2
|
||||
|
||||
// Starts AI's APU generator
|
||||
/mob/living/silicon/ai/proc/start_apu(var/shutup = 0)
|
||||
if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
|
||||
if(!shutup)
|
||||
src << "You do not have an APU generator and you shouldn't have this verb. Report this."
|
||||
return
|
||||
if(hardware_integrity() < 50)
|
||||
if(!shutup)
|
||||
src << "<span class='notice'>Starting APU... <b>FAULT</b>(System Damaged)</span>"
|
||||
return
|
||||
if(!shutup)
|
||||
src << "Starting APU... ONLINE"
|
||||
APU_power = 1
|
||||
|
||||
// Stops AI's APU generator
|
||||
/mob/living/silicon/ai/proc/stop_apu(var/shutup = 0)
|
||||
if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
|
||||
return
|
||||
|
||||
if(APU_power)
|
||||
APU_power = 0
|
||||
if(!shutup)
|
||||
src << "Shutting down APU... DONE"
|
||||
|
||||
// Returns percentage of AI's remaining backup capacitor charge (maxhealth - oxyloss).
|
||||
/mob/living/silicon/ai/proc/backup_capacitor()
|
||||
return ((200 - getOxyLoss()) / 2)
|
||||
|
||||
// Returns percentage of AI's remaining hardware integrity (maxhealth - (bruteloss + fireloss))
|
||||
/mob/living/silicon/ai/proc/hardware_integrity()
|
||||
return (health-config.health_threshold_dead)/2
|
||||
|
||||
// Shows capacitor charge and hardware integrity information to the AI in Status tab.
|
||||
/mob/living/silicon/ai/show_system_integrity()
|
||||
if(!src.stat)
|
||||
stat(null, text("Hardware integrity: [hardware_integrity()]%"))
|
||||
stat(null, text("Internal capacitor: [backup_capacitor()]%"))
|
||||
else
|
||||
stat(null, text("Systems nonfunctional"))
|
||||
|
||||
// Shows AI Malfunction related information to the AI.
|
||||
/mob/living/silicon/ai/show_malf_ai()
|
||||
if(src.is_malf())
|
||||
if(src.hacked_apcs)
|
||||
stat(null, "Hacked APCs: [src.hacked_apcs.len]")
|
||||
stat(null, "System Status: [src.hacking ? "Busy" : "Stand-By"]")
|
||||
if(src.research)
|
||||
stat(null, "Available CPU: [src.research.stored_cpu] TFlops")
|
||||
stat(null, "Maximal CPU: [src.research.max_cpu] TFlops")
|
||||
stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick] TFlops/s")
|
||||
stat(null, "Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
|
||||
if(src.research.focus)
|
||||
stat(null, "Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
|
||||
if(system_override == 1)
|
||||
stat(null, "SYSTEM OVERRIDE INITIATED")
|
||||
else if(system_override == 2)
|
||||
stat(null, "SYSTEM OVERRIDE COMPLETED")
|
||||
|
||||
// Cleaner proc for creating powersupply for an AI.
|
||||
/mob/living/silicon/ai/proc/create_powersupply()
|
||||
if(psupply)
|
||||
del(psupply)
|
||||
psupply = new/obj/machinery/ai_powersupply(src)
|
||||
@@ -7,7 +7,7 @@
|
||||
if(!src.client) msg += "\nIt appears to be in stand-by mode." //afk
|
||||
if(UNCONSCIOUS) msg += "\n<span class='warning'>It doesn't seem to be responding.</span>"
|
||||
if(DEAD) msg += "\n<span class='deadsay'>It looks completely unsalvageable.</span>"
|
||||
msg += "\n*---------*</span>"
|
||||
msg += "\n*---------*"
|
||||
|
||||
if(print_flavor_text()) msg += "\n[print_flavor_text()]\n"
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
|
||||
qdel(src.cable)
|
||||
|
||||
regular_hud_updates()
|
||||
handle_regular_hud_updates()
|
||||
|
||||
if(src.secHUD == 1)
|
||||
process_sec_hud(src, 1)
|
||||
|
||||
@@ -169,17 +169,6 @@
|
||||
if(3)
|
||||
src << "<font color=green>You feel an electric surge run through your circuitry and become acutely aware at how lucky you are that you can still feel at all.</font>"
|
||||
|
||||
// See software.dm for Topic()
|
||||
/mob/living/silicon/pai/meteorhit(obj/O as obj)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
M.show_message(text("\red [] has been hit by []", src, O), 1)
|
||||
if (src.health > 0)
|
||||
src.adjustBruteLoss(30)
|
||||
if ((O.icon_state == "flaming"))
|
||||
src.adjustFireLoss(40)
|
||||
src.updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C)
|
||||
if(istype(usr, /mob/living))
|
||||
var/mob/living/U = usr
|
||||
@@ -197,6 +186,19 @@
|
||||
src.reset_view(C)
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/pai/verb/reset_record_view()
|
||||
set category = "pAI Commands"
|
||||
set name = "Reset Records Software"
|
||||
|
||||
securityActive1 = null
|
||||
securityActive2 = null
|
||||
security_cannotfind = 0
|
||||
medicalActive1 = null
|
||||
medicalActive2 = null
|
||||
medical_cannotfind = 0
|
||||
nanomanager.update_uis(src)
|
||||
usr << "<span class='notice'>You reset your record-viewing software.</span>"
|
||||
|
||||
/mob/living/silicon/pai/cancel_camera()
|
||||
set category = "pAI Commands"
|
||||
set name = "Cancel Camera View"
|
||||
@@ -269,9 +271,10 @@
|
||||
if(ishuman(holder))
|
||||
var/mob/living/carbon/human/H = holder
|
||||
for(var/obj/item/organ/external/affecting in H.organs)
|
||||
if(affecting.hidden == card)
|
||||
if(card in affecting.implants)
|
||||
affecting.take_damage(rand(30,50))
|
||||
H.visible_message("<span class='danger'>\The [src] explodes out of \the [H]'s [affecting.name][(affecting.status & ORGAN_ROBOT) ? " in a shower of gore" : ""]!</span>")
|
||||
affecting.implants -= card
|
||||
H.visible_message("<span class='danger'>\The [src] explodes out of \the [H]'s [affecting.name] in shower of gore!</span>")
|
||||
break
|
||||
holder.drop_from_inventory(card)
|
||||
else if(istype(card.loc,/obj/item/device/pda))
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
user << "\red You can't analyze non-robotic things!"
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>\The [user] has analyzed [M]'s components.","<span class='notice'>You have analyzed [M]'s components.")
|
||||
user.visible_message("<span class='notice'>\The [user] has analyzed [M]'s components.</span>","<span class='notice'>You have analyzed [M]'s components.</span>")
|
||||
switch(scan_type)
|
||||
if("robot")
|
||||
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user