Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into 6/25/2015_bay_sync

Conflicts:
	.travis.yml
	code/modules/clothing/spacesuits/rig/modules/combat.dm
	code/modules/clothing/spacesuits/rig/modules/utility.dm
	code/modules/mob/living/silicon/ai/ai.dm
	icons/mob/rig_back.dmi
	polaris.dme
This commit is contained in:
Neerti
2015-06-25 18:50:18 -04:00
426 changed files with 8890 additions and 7959 deletions
+9 -5
View File
@@ -20,6 +20,10 @@ var/global/floorIsLava = 0
var/msg = rendered
C << msg
proc/admin_notice(var/message, var/rights)
for(var/mob/M in mob_list)
if(check_rights(rights, 0, M))
M << message
///////////////////////////////////////////////////////////////////////////////////////////////Panels
@@ -54,7 +58,7 @@ var/global/floorIsLava = 0
<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> |
@@ -1160,7 +1164,7 @@ var/global/floorIsLava = 0
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/>"
@@ -1302,15 +1306,15 @@ var/global/floorIsLava = 0
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)
+48
View File
@@ -0,0 +1,48 @@
/mob/var/lastattacker = null
/mob/var/lastattacked = null
/mob/var/attack_log = list( )
proc/log_and_message_admins(var/message as text, var/mob/user = usr)
log_admin(user ? "[key_name(user)] [message]" : "EVENT [message]")
message_admins(user ? "[key_name(user)] [message]" : "EVENT [message]")
proc/log_and_message_admins_many(var/list/mob/users, var/message)
if(!users || !users.len)
return
var/list/user_keys = list()
for(var/mob/user in users)
user_keys += key_name(user)
log_admin("[english_list(user_keys)] [message]")
message_admins("[english_list(user_keys)] [message]")
proc/admin_log_and_message_admins(var/message as text)
log_admin(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]")
message_admins(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]", 1)
proc/admin_attack_log(var/mob/attacker, var/mob/victim, var/attacker_message, var/victim_message, var/admin_message)
if(victim)
victim.attack_log += text("\[[time_stamp()]\] <font color='orange'>[key_name(attacker)] - [victim_message]</font>")
if(attacker)
attacker.attack_log += text("\[[time_stamp()]\] <font color='red'>[key_name(victim)] - [attacker_message]</font>")
msg_admin_attack("[key_name(attacker)] [admin_message] [key_name(victim)] (INTENT: [attacker? uppertext(attacker.a_intent) : "N/A"]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[attacker.x];Y=[attacker.y];Z=[attacker.z]'>JMP</a>)")
proc/admin_attacker_log_many_victims(var/mob/attacker, var/list/mob/victims, var/attacker_message, var/victim_message, var/admin_message)
if(!victims || !victims.len)
return
for(var/mob/victim in victims)
admin_attack_log(attacker, victim, attacker_message, victim_message, admin_message)
proc/admin_inject_log(mob/attacker, mob/victim, obj/item/weapon, reagents, amount_transferred, violent=0)
if(violent)
violent = "violently "
else
violent = ""
admin_attack_log(attacker,
victim,
"used \the [weapon] to [violent]inject - [reagents] - [amount_transferred]u transferred",
"was [violent]injected with \the [weapon] - [reagents] - [amount_transferred]u transferred",
"used \the [weapon] to [violent]inject [reagents] ([amount_transferred]u transferred) into")
+5 -1
View File
@@ -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!
+6 -26
View File
@@ -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)
+4 -36
View File
@@ -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
View File
@@ -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)
+23 -17
View File
@@ -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")
+2 -2
View File
@@ -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!
+1 -10
View File
@@ -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]")
+1 -2
View File
@@ -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)
+126 -43
View File
@@ -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]]")
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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()
+410
View File
@@ -0,0 +1,410 @@
//*****************
//**Cham Jumpsuit**
//*****************
/obj/item/proc/disguise(var/newtype)
//this is necessary, unfortunately, as initial() does not play well with list vars
var/obj/item/copy = new newtype(null) //so that it is GCed once we exit
desc = copy.desc
name = copy.name
icon_state = copy.icon_state
item_state = copy.item_state
body_parts_covered = copy.body_parts_covered
item_icons = copy.item_icons.Copy()
item_state_slots = copy.item_state_slots.Copy()
sprite_sheets = copy.sprite_sheets.Copy()
//copying sprite_sheets_obj should be unnecessary as chameleon items are not refittable.
return copy //for inheritance
/proc/generate_chameleon_choices(var/basetype, var/blacklist=list())
. = list()
var/i = 1 //in case there is a collision with both name AND icon_state
for(var/typepath in typesof(basetype) - blacklist)
var/obj/O = typepath
if(initial(O.icon) && initial(O.icon_state))
var/name = initial(O.name)
if(name in .)
name += " ([initial(O.icon_state)])"
if(name in .)
name += " \[[i++]\]"
.[name] = typepath
/obj/item/clothing/under/chameleon
//starts off as black
name = "black jumpsuit"
icon_state = "black"
item_state = "bl_suit"
worn_state = "black"
desc = "It's a plain jumpsuit. It seems to have a small dial on the wrist."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/clothing/under/chameleon/New()
..()
if(!clothing_choices)
var/blocked = list(src.type, /obj/item/clothing/under/cloud, /obj/item/clothing/under/gimmick)//Prevent infinite loops and bad jumpsuits.
clothing_choices = generate_chameleon_choices(/obj/item/clothing/under, blocked)
/obj/item/clothing/under/chameleon/emp_act(severity)
name = "psychedelic"
desc = "Groovy!"
icon_state = "psyche"
item_state_slots[slot_w_uniform_str] = "psyche"
update_icon()
update_clothing_icon()
/obj/item/clothing/under/chameleon/verb/change(picked in clothing_choices)
set name = "Change Jumpsuit Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Hat**
//*****************
/obj/item/clothing/head/chameleon
name = "grey cap"
icon_state = "greysoft"
item_state = "greysoft"
desc = "It looks like a plain hat, but upon closer inspection, there's an advanced holographic array installed inside. It seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
body_parts_covered = 0
var/global/list/clothing_choices
/obj/item/clothing/head/chameleon/New()
..()
if(!clothing_choices)
var/blocked = list(src.type, /obj/item/clothing/head/justice,)//Prevent infinite loops and bad hats.
clothing_choices = generate_chameleon_choices(/obj/item/clothing/head, blocked)
/obj/item/clothing/head/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
update_icon()
update_clothing_icon()
/obj/item/clothing/head/chameleon/verb/change(picked in clothing_choices)
set name = "Change Hat/Helmet Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Suit**
//******************
/obj/item/clothing/suit/chameleon
name = "armor"
icon_state = "armor"
item_state = "armor"
desc = "It appears to be a vest of standard armor, except this is embedded with a hidden holographic cloaker, allowing it to change it's appearance, but offering no protection.. It seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/clothing/suit/chameleon/New()
..()
if(!clothing_choices)
var/blocked = list(src.type, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice, /obj/item/clothing/suit/greatcoat)
clothing_choices = generate_chameleon_choices(/obj/item/clothing/suit, blocked)
/obj/item/clothing/suit/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "armor"
desc = "An armored vest that protects against some damage."
icon_state = "armor"
update_icon()
update_clothing_icon()
/obj/item/clothing/suit/chameleon/verb/change(picked in clothing_choices)
set name = "Change Oversuit Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//*******************
//**Chameleon Shoes**
//*******************
/obj/item/clothing/shoes/chameleon
name = "black shoes"
icon_state = "black"
item_state = "black"
desc = "They're comfy black shoes, with clever cloaking technology built in. It seems to have a small dial on the back of each shoe."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/clothing/shoes/chameleon/New()
..()
if(!clothing_choices)
var/blocked = list(src.type, /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/shoes/cyborg)//prevent infinite loops and bad shoes.
clothing_choices = generate_chameleon_choices(/obj/item/clothing/shoes, blocked)
/obj/item/clothing/shoes/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black shoes"
desc = "A pair of black shoes."
icon_state = "black"
item_state = "black"
update_icon()
update_clothing_icon()
/obj/item/clothing/shoes/chameleon/verb/change(picked in clothing_choices)
set name = "Change Footwear Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//**********************
//**Chameleon Backpack**
//**********************
/obj/item/weapon/storage/backpack/chameleon
name = "backpack"
icon_state = "backpack"
item_state = "backpack"
desc = "A backpack outfitted with cloaking tech. It seems to have a small dial inside, kept away from the storage."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/weapon/storage/backpack/chameleon/New()
..()
if(!clothing_choices)
var/blocked = list(src.type, /obj/item/weapon/storage/backpack/satchel/withwallet)
clothing_choices = generate_chameleon_choices(/obj/item/weapon/storage/backpack, blocked)
/obj/item/weapon/storage/backpack/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "backpack"
desc = "You wear this on your back and put items into it."
icon_state = "backpack"
item_state = "backpack"
update_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
/obj/item/weapon/storage/backpack/chameleon/verb/change(picked in clothing_choices)
set name = "Change Backpack Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
//********************
//**Chameleon Gloves**
//********************
/obj/item/clothing/gloves/chameleon
name = "black gloves"
icon_state = "black"
item_state = "bgloves"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/clothing/gloves/chameleon/New()
..()
if(!clothing_choices)
clothing_choices = generate_chameleon_choices(/obj/item/clothing/gloves, list(src.type))
/obj/item/clothing/gloves/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black gloves"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
icon_state = "black"
update_icon()
update_clothing_icon()
/obj/item/clothing/gloves/chameleon/verb/change(picked in clothing_choices)
set name = "Change Gloves Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Mask**
//******************
/obj/item/clothing/mask/chameleon
name = "gas mask"
icon_state = "gas_alt"
item_state = "gas_alt"
desc = "It looks like a plain gask mask, but on closer inspection, it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/global/list/clothing_choices
/obj/item/clothing/mask/chameleon/New()
..()
if(!clothing_choices)
clothing_choices = generate_chameleon_choices(/obj/item/clothing/mask, list(src.type))
/obj/item/clothing/mask/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "gas mask"
desc = "It's a gas mask."
icon_state = "gas_alt"
update_icon()
update_clothing_icon()
/obj/item/clothing/mask/chameleon/verb/change(picked in clothing_choices)
set name = "Change Mask Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//*********************
//**Chameleon Glasses**
//*********************
/obj/item/clothing/glasses/chameleon
name = "Optical Meson Scanner"
icon_state = "meson"
item_state = "glasses"
desc = "It looks like a plain set of mesons, but on closer inspection, it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/glasses/chameleon/New()
..()
if(!clothing_choices)
clothing_choices = generate_chameleon_choices(/obj/item/clothing/glasses, list(src.type))
/obj/item/clothing/glasses/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "Optical Meson Scanner"
desc = "It's a set of mesons."
icon_state = "meson"
update_icon()
update_clothing_icon()
/obj/item/clothing/glasses/chameleon/verb/change(picked in clothing_choices)
set name = "Change Glasses Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(clothing_choices[picked]))
return
disguise(clothing_choices[picked])
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Gun**
//*****************
/obj/item/weapon/gun/energy/chameleon
name = "desert eagle"
desc = "A hologram projector in the shape of a gun. There is a dial on the side to change the gun's disguise."
icon_state = "deagle"
w_class = 3
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
matter = list()
fire_sound = 'sound/weapons/Gunshot.ogg'
projectile_type = /obj/item/projectile/chameleon
charge_meter = 0
charge_cost = 20 //uses next to no power, since it's just holograms
max_shots = 50
var/obj/item/projectile/copy_projectile
var/global/list/gun_choices
/obj/item/weapon/gun/energy/chameleon/New()
..()
if(!gun_choices)
gun_choices = list()
for(var/gun_type in typesof(/obj/item/weapon/gun/) - src.type)
var/obj/item/weapon/gun/G = gun_type
src.gun_choices[initial(G.name)] = gun_type
return
/obj/item/weapon/gun/energy/chameleon/consume_next_projectile()
var/obj/item/projectile/P = ..()
if(P && ispath(copy_projectile))
P.name = initial(copy_projectile.name)
P.icon = initial(copy_projectile.icon)
P.icon_state = initial(copy_projectile.icon_state)
P.pass_flags = initial(copy_projectile.pass_flags)
P.hitscan = initial(copy_projectile.hitscan)
P.step_delay = initial(copy_projectile.step_delay)
P.muzzle_type = initial(copy_projectile.muzzle_type)
P.tracer_type = initial(copy_projectile.tracer_type)
P.impact_type = initial(copy_projectile.impact_type)
return P
/obj/item/weapon/gun/energy/chameleon/emp_act(severity)
name = "desert eagle"
desc = "It's a desert eagle."
icon_state = "deagle"
update_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
/obj/item/weapon/gun/energy/chameleon/disguise(var/newtype)
var/obj/item/weapon/gun/copy = ..()
flags_inv = copy.flags_inv
fire_sound = copy.fire_sound
fire_sound_text = copy.fire_sound_text
var/obj/item/weapon/gun/energy/E = copy
if(istype(E))
copy_projectile = E.projectile_type
//charge_meter = E.charge_meter //does not work very well with icon_state changes, ATM
else
copy_projectile = null
//charge_meter = 0
/obj/item/weapon/gun/energy/chameleon/verb/change(picked in gun_choices)
set name = "Change Gun Appearance"
set category = "Chameleon Items"
set src in usr
if(!ispath(gun_choices[picked]))
return
disguise(gun_choices[picked])
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
+5 -2
View File
@@ -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()
@@ -6,7 +6,15 @@
* /obj/item/rig_module/shield
* /obj/item/rig_module/fabricator
* /obj/item/rig_module/mounted/energy_blade
*/
* /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
@@ -77,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)
@@ -231,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,9 +12,10 @@
* /obj/item/rig_module/chem_dispenser
* /obj/item/rig_module/chem_dispenser/injector
* /obj/item/rig_module/voice
* /obj/item/rig_module/mounted/mop
* /obj/item/rig_module/cleaner_launcher
*/
* /obj/item/rig_module/device/paperdispenser
* /obj/item/rig_module/device/pen
* /obj/item/rig_module/device/stamp * /obj/item/rig_module/mounted/mop
* /obj/item/rig_module/cleaner_launcher */
/obj/item/rig_module/device
name = "mounted device"
@@ -96,7 +97,6 @@
if(device_type) device = new device_type(src)
/obj/item/rig_module/device/engage(atom/target)
if(!..() || !device)
return 0
@@ -529,4 +529,4 @@
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]!")
new_grenade.activate(H)
new_grenade.throw_at(target,fire_force,fire_distance)
new_grenade.throw_at(target,fire_force,fire_distance)
+2 -2
View File
@@ -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"
+24 -19
View File
@@ -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
+3 -3
View File
@@ -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
-456
View File
@@ -1,456 +0,0 @@
//*****************
//**Cham Jumpsuit**
//*****************
/obj/item/clothing/under/chameleon
//starts off as black
name = "black jumpsuit"
icon_state = "black"
item_state = "bl_suit"
worn_state = "black"
desc = "It's a plain jumpsuit. It seems to have a small dial on the wrist."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/under/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/under/chameleon, /obj/item/clothing/under/cloud, /obj/item/clothing/under/gimmick)//Prevent infinite loops and bad jumpsuits.
for(var/U in typesof(/obj/item/clothing/under)-blocked)
var/obj/item/clothing/under/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/under/chameleon/emp_act(severity)
name = "psychedelic"
desc = "Groovy!"
icon_state = "psyche"
item_state_slots[slot_w_uniform_str] = "psyche"
update_icon()
update_clothing_icon()
/obj/item/clothing/under/chameleon/verb/change()
set name = "Change Jumpsuit Appearance"
set category = "Object"
set src in usr
var/picked = input("Select jumpsuit to change it to", "Chameleon Jumpsuit")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/under/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
item_state_slots = A.item_state_slots
worn_state = A.worn_state
body_parts_covered = A.body_parts_covered
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Hat**
//*****************
/obj/item/clothing/head/chameleon
name = "grey cap"
icon_state = "greysoft"
item_state = "greysoft"
desc = "It looks like a plain hat, but upon closer inspection, there's an advanced holographic array installed inside. It seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
body_parts_covered = 0
var/list/clothing_choices = list()
/obj/item/clothing/head/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/head/chameleon,/obj/item/clothing/head/justice,)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/head)-blocked)
var/obj/item/clothing/head/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/head/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "grey cap"
desc = "It's a baseball hat in a tasteful grey colour."
icon_state = "greysoft"
update_icon()
update_clothing_icon()
/obj/item/clothing/head/chameleon/verb/change()
set name = "Change Hat/Helmet Appearance"
set category = "Object"
set src in usr
var/picked = input("Select headwear to change it to", "Chameleon Hat")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Suit**
//******************
/obj/item/clothing/suit/chameleon
name = "armor"
icon_state = "armor"
item_state = "armor"
desc = "It appears to be a vest of standard armor, except this is embedded with a hidden holographic cloaker, allowing it to change it's appearance, but offering no protection.. It seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/suit/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice,
/obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits.
for(var/U in typesof(/obj/item/clothing/suit)-blocked)
var/obj/item/clothing/suit/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/suit/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "armor"
desc = "An armored vest that protects against some damage."
icon_state = "armor"
update_icon()
update_clothing_icon()
/obj/item/clothing/suit/chameleon/verb/change()
set name = "Change Exosuit Appearance"
set category = "Object"
set src in usr
var/picked = input("Select exosuit to change it to", "Chameleon Exosuit")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
update_clothing_icon() //so our overlays update.
//*******************
//**Chameleon Shoes**
//*******************
/obj/item/clothing/shoes/chameleon
name = "black shoes"
icon_state = "black"
item_state = "black"
desc = "They're comfy black shoes, with clever cloaking technology built in. It seems to have a small dial on the back of each shoe."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/shoes/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/shoes/chameleon, /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/shoes/cyborg)//prevent infinite loops and bad shoes.
for(var/U in typesof(/obj/item/clothing/shoes)-blocked)
var/obj/item/clothing/shoes/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/shoes/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black shoes"
desc = "A pair of black shoes."
icon_state = "black"
item_state = "black"
update_icon()
update_clothing_icon()
/obj/item/clothing/shoes/chameleon/verb/change()
set name = "Change Footwear Appearance"
set category = "Object"
set src in usr
var/picked = input("Select shoes to change it to", "Chameleon Shoes")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
update_clothing_icon() //so our overlays update.
//**********************
//**Chameleon Backpack**
//**********************
/obj/item/weapon/storage/backpack/chameleon
name = "backpack"
icon_state = "backpack"
item_state = "backpack"
desc = "A backpack outfitted with cloaking tech. It seems to have a small dial inside, kept away from the storage."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/weapon/storage/backpack/chameleon/New()
..()
var/blocked = list(/obj/item/weapon/storage/backpack/chameleon, /obj/item/weapon/storage/backpack/satchel/withwallet)
for(var/U in typesof(/obj/item/weapon/storage/backpack)-blocked)//Prevent infinite loops and bad backpacks.
var/obj/item/weapon/storage/backpack/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/weapon/storage/backpack/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "backpack"
desc = "You wear this on your back and put items into it."
icon_state = "backpack"
item_state = "backpack"
update_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
/obj/item/weapon/storage/backpack/chameleon/verb/change()
set name = "Change Backpack Appearance"
set category = "Object"
set src in usr
var/picked = input("Select backpack to change it to", "Chameleon Backpack")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/weapon/storage/backpack/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
//********************
//**Chameleon Gloves**
//********************
/obj/item/clothing/gloves/chameleon
name = "black gloves"
icon_state = "black"
item_state = "bgloves"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/gloves/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/gloves/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/gloves)-blocked)
var/obj/item/clothing/gloves/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/gloves/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "black gloves"
desc = "It looks like a pair of gloves, but it seems to have a small dial inside."
icon_state = "black"
update_icon()
update_clothing_icon()
/obj/item/clothing/gloves/chameleon/verb/change()
set name = "Change Gloves Appearance"
set category = "Object"
set src in usr
var/picked = input("Select gloves to change it to", "Chameleon Gloves")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Mask**
//******************
/obj/item/clothing/mask/chameleon
name = "gas mask"
icon_state = "gas_alt"
item_state = "gas_alt"
desc = "It looks like a plain gask mask, but on closer inspection, it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/mask/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/mask/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/mask)-blocked)
var/obj/item/clothing/mask/V = new U
if(V)
src.clothing_choices[V.name] = U
return
/obj/item/clothing/mask/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "gas mask"
desc = "It's a gas mask."
icon_state = "gas_alt"
update_icon()
update_clothing_icon()
/obj/item/clothing/mask/chameleon/verb/change()
set name = "Change Mask Appearance"
set category = "Object"
set src in usr
var/picked = input("Select mask to change it to", "Chameleon Mask")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
update_clothing_icon() //so our overlays update.
//*********************
//**Chameleon Glasses**
//*********************
/obj/item/clothing/glasses/chameleon
name = "Optical Meson Scanner"
icon_state = "meson"
item_state = "glasses"
desc = "It looks like a plain set of mesons, but on closer inspection, it seems to have a small dial inside."
origin_tech = list(TECH_ILLEGAL = 3)
var/list/clothing_choices = list()
/obj/item/clothing/glasses/chameleon/New()
..()
var/blocked = list(/obj/item/clothing/glasses/chameleon)//Prevent infinite loops and bad hats.
for(var/U in typesof(/obj/item/clothing/glasses)-blocked)
var/obj/item/clothing/glasses/V = new U
src.clothing_choices[V.name] = U
return
/obj/item/clothing/glasses/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown.
name = "Optical Meson Scanner"
desc = "It's a set of mesons."
icon_state = "meson"
update_icon()
update_clothing_icon()
/obj/item/clothing/glasses/chameleon/verb/change()
set name = "Change Glasses Appearance"
set category = "Object"
set src in usr
var/picked = input("Select glasses to change it to", "Chameleon Glasses")as null|anything in clothing_choices
if(!picked || !clothing_choices[picked])
return
var/newtype = clothing_choices[picked]
var/obj/item/clothing/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Gun**
//*****************
/obj/item/weapon/gun/projectile/chameleon
name = "desert eagle"
desc = "A fake Desert Eagle with a dial on the side to change the gun's disguise."
icon_state = "deagle"
w_class = 3.0
max_shells = 7
caliber = ".45"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
ammo_type = "/obj/item/ammo_casing/chameleon"
matter = list()
var/list/gun_choices = list()
/obj/item/weapon/gun/projectile/chameleon/New()
..()
var/blocked = list(/obj/item/weapon/gun/projectile/chameleon)
for(var/U in typesof(/obj/item/weapon/gun/)-blocked)
var/obj/item/weapon/gun/V = new U
src.gun_choices[V.name] = U
return
/obj/item/weapon/gun/projectile/chameleon/emp_act(severity)
name = "desert eagle"
desc = "It's a desert eagle."
icon_state = "deagle"
update_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
/obj/item/weapon/gun/projectile/chameleon/verb/change(picked in gun_choices)
set name = "Change Gun Appearance"
set category = "Object"
set src in usr
if(!picked || !gun_choices[picked])
return
var/newtype = gun_choices[picked]
var/obj/item/weapon/gun/A = new newtype
desc = null
permeability_coefficient = 0.90
desc = A.desc
name = A.name
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
+1
View File
@@ -119,6 +119,7 @@
item_state = "paper"
throwforce = 1
w_class = 1.0
slot_flags = SLOT_EARS
throw_speed = 3
throw_range = 5
+2 -2
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+8 -8
View File
@@ -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),
)
-1
View File
@@ -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)
+1 -1
View File
@@ -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))
+28 -33
View File
@@ -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
+1 -16
View File
@@ -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>"
+1 -1
View File
@@ -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()
+5 -4
View File
@@ -53,12 +53,13 @@
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropiate ammo. The description \
will tell you what caliber you need."
/obj/item/weapon/gun/projectile/chameleon
/obj/item/weapon/gun/energy/chameleon
description_info = null //The chameleon gun adopts the description_info of the weapon it is impersonating as, to make meta-ing harder.
description_antag = "This gun can alter its appearance to mimick other weapons. To change the appearance, use the appropriate verb in the object tab. \
The ammo loaded by default makes the gun useless for actual combat."
description_antag = "This gun is actually a hologram projector that can alter its appearance to mimick other weapons. To change the appearance, use \
the appropriate verb in the chameleon items tab. Any beams or projectiles fired from this gun are actually holograms and useless for actual combat. \
Projecting these holograms over distance uses a little bit of charge."
/obj/item/weapon/gun/projectile/chameleon/change(picked in gun_choices) //Making the gun change its help text to match the weapon's help text.
/obj/item/weapon/gun/energy/chameleon/change(picked in gun_choices) //Making the gun change its help text to match the weapon's help text.
..(picked)
var/obj/O = gun_choices[picked]
description_info = initial(O.description_info)
+15 -12
View File
@@ -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
+1 -1
View File
@@ -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>"
+11 -21
View File
@@ -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()
..()
+2 -1
View File
@@ -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
+48 -3
View File
@@ -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]"]
+8 -5
View File
@@ -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)
+5
View File
@@ -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
+1 -1
View File
@@ -575,7 +575,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
+5 -2
View File
@@ -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
+1 -1
View File
@@ -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)
+41 -9
View File
@@ -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)
@@ -38,13 +39,7 @@
if(material.conductive)
flags |= CONDUCT
if(!islist(matter))
matter = list()
if(material.composite_material)
for(var/material_string in material.composite_material)
matter[material_string] = material.composite_material[material_string]
else
matter[material.name] = SHEET_MATERIAL_AMOUNT
matter = material.get_matter()
return 1
/obj/item/stack/material/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified)
@@ -53,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"
@@ -81,7 +89,7 @@
default_type = "phoron"
/obj/item/stack/material/plastic
name = "Plastic"
name = "plastic"
icon_state = "sheet-plastic"
default_type = "plastic"
@@ -157,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"
+6
View File
@@ -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)
+167 -16
View File
@@ -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,10 +136,24 @@ 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
// Return the matter comprising this material.
/material/proc/get_matter()
var/list/temp_matter = list()
if(islist(composite_material))
for(var/material_string in composite_material)
temp_matter[material_string] = composite_material[material_string]
else if(SHEET_MATERIAL_AMOUNT)
temp_matter[name] = SHEET_MATERIAL_AMOUNT
return temp_matter
// As above.
/material/proc/get_edge_damage()
return hardness //todo
@@ -192,7 +243,7 @@ var/list/name_to_material
weight = 22
hardness = 50
stack_origin_tech = list(TECH_MATERIAL = 3)
/material/phoron
name = "phoron"
stack_type = /obj/item/stack/material/phoron
@@ -204,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
@@ -217,6 +270,7 @@ var/list/name_to_material
spawn (0)
target_tile.hotspot_expose(temperature, 400)
return round(totalPhoron/100)
*/
/material/stone
name = "sandstone"
@@ -239,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"
@@ -252,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"
@@ -261,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"
@@ -276,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"
@@ -303,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 = 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"
@@ -317,6 +461,12 @@ var/list/name_to_material
weight = 12
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
@@ -386,6 +536,7 @@ var/list/name_to_material
name = "cardboard"
stack_type = /obj/item/stack/material/cardboard
flags = MATERIAL_BRITTLE
integrity = 10
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#AAAAAA"
+5 -3
View File
@@ -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)
+1
View File
@@ -8,6 +8,7 @@
force = 0.0
throwforce = 0.0
w_class = 1.0
slot_flags = SLOT_EARS
var/string_attached
var/sides = 2
+18 -2
View File
@@ -670,9 +670,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images -= ghostimage //remove ourself
mob/dead/observer/MayRespawn(var/feedback = 0)
if(!client || !mind)
if(!client)
return 0
if(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 -2
View File
@@ -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)
+6 -6
View File
@@ -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)
+16 -5
View File
@@ -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
+7 -7
View File
@@ -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
+2 -2
View File
@@ -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
+2 -6
View File
@@ -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)
+8 -6
View File
@@ -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()
+9 -7
View File
@@ -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(..())
+7 -5
View File
@@ -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(..())
+3 -2
View File
@@ -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
+3 -9
View File
@@ -4,7 +4,7 @@
set invisibility = 0
set background = 1
if (monkeyizing) return
if (transforming) return
if(!loc) return
..()
@@ -14,17 +14,11 @@
// 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()
@@ -36,7 +30,7 @@
/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.
@@ -174,7 +168,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
+192 -211
View File
@@ -1,29 +1,21 @@
/mob/living/carbon/brain/handle_breathing()
return
/mob/living/carbon/brain/Life()
set invisibility = 0
set background = 1
..()
if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
//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()
@@ -31,238 +23,227 @@
if(client)
handle_regular_hud_updates()
/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."
/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/proc/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/proc/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/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)
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
+17 -18
View File
@@ -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)
@@ -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)
+3 -18
View File
@@ -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)
@@ -929,7 +929,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
+5 -15
View File
@@ -2,7 +2,7 @@
set invisibility = 0
set background = 1
if (src.monkeyizing)
if (src.transforming)
return
..()
@@ -18,18 +18,11 @@
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
@@ -85,12 +78,9 @@
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]
@@ -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 -3
View File
@@ -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,13 +19,13 @@
ExtinguishMob()
return
..()
if(handcuffed)
spawn() escape_handcuffs()
else if(legcuffed)
spawn() escape_legcuffs()
..()
/mob/living/carbon/proc/escape_handcuffs()
if(!(last_special <= world.time)) return
+31
View File
@@ -0,0 +1,31 @@
/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()
. = 1
//Handle temperature/pressure differences between body and environment
if(environment)
handle_environment(environment)
/mob/living/proc/handle_breathing()
return
/mob/living/proc/handle_mutations_and_radiation()
return
/mob/living/proc/handle_environment(var/datum/gas_mixture/environment)
return
+3
View File
@@ -453,6 +453,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()
+6 -1
View File
@@ -236,7 +236,7 @@
location.hotspot_expose(fire_burn_temperature(), 50, 1)
/mob/living/fire_act()
adjust_fire_stacks(0.5)
adjust_fire_stacks(2)
IgniteMob()
//Finds the effective temperature that the mob is burning at.
@@ -245,6 +245,11 @@
return 0
//Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot.
//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/proc/reagent_permeability()
return 1
return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2)
/mob/living/regular_hud_updates()
@@ -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.
+47 -205
View File
@@ -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()
@@ -428,17 +406,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)
@@ -663,16 +630,19 @@ var/list/ai_verbs_default = list(
usr << "Your hologram will [hologram_follow ? "follow" : "no longer follow"] you now."
/mob/living/silicon/ai/proc/check_unable(var/flags = 0)
if(stat == DEAD)
src << "<span class='warning'>You are dead!</span>"
/mob/living/silicon/ai/proc/check_unable(var/flags = 0) if(stat == DEAD)
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
@@ -686,146 +656,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
+2 -6
View File
@@ -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()
+155
View File
@@ -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"
+9 -8
View File
@@ -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,6 +146,7 @@
aiRestorePowerRoutine = 3
src << "Here are your current laws:"
show_laws()
updateicon()
sleep(50)
theAPC = null
@@ -176,3 +176,4 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
+140
View File
@@ -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"
+13 -11
View File
@@ -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"

Some files were not shown because too many files have changed in this diff Show More