mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-20 19:44:46 +01:00
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:
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
@@ -177,6 +177,10 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/toggledebuglogs,
|
||||
/client/proc/SDQL_query,
|
||||
/client/proc/SDQL2_query,
|
||||
/client/proc/Jump,
|
||||
/client/proc/jumptomob,
|
||||
/client/proc/jumptocoord,
|
||||
/client/proc/dsay
|
||||
)
|
||||
|
||||
var/list/admin_verbs_paranoid_debug = list(
|
||||
@@ -735,7 +739,7 @@ var/list/admin_verbs_mentor = list(
|
||||
var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in silicon_mob_list
|
||||
if(!S) return
|
||||
|
||||
var/obj/nano_module/law_manager/L = new(S)
|
||||
var/datum/nano_module/law_manager/L = new(S)
|
||||
L.ui_interact(usr, state = admin_state)
|
||||
admin_log_and_message_admins("has opened [S]'s law manager.")
|
||||
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -27,26 +27,6 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
|
||||
return
|
||||
|
||||
|
||||
//handles adding notes to the end of a ckey's buffer
|
||||
//originally had seperate entries such as var/by to record who left the note and when
|
||||
//but the current bansystem is a heap of dung.
|
||||
/proc/notes_add(var/ckey, var/note)
|
||||
if(!ckey)
|
||||
ckey = ckey(input(usr,"Who would you like to add notes for?","Enter a ckey",null) as text|null)
|
||||
if(!ckey) return
|
||||
|
||||
if(!note)
|
||||
note = html_encode(input(usr,"Enter your note:","Enter some text",null) as message|null)
|
||||
if(!note) return
|
||||
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
if(!notesfile) return
|
||||
notesfile.cd = "/[ckey]"
|
||||
notesfile.eof = 1 //move to the end of the buffer
|
||||
notesfile << "[time2text(world.realtime,"DD-MMM-YYYY")] | [note][(usr && usr.ckey)?" ~[usr.ckey]":""]"
|
||||
return
|
||||
|
||||
//handles removing entries from the buffer, or removing the entire directory if no start_index is given
|
||||
/proc/notes_remove(var/ckey, var/start_index, var/end_index)
|
||||
var/savefile/notesfile = new(NOTESFILE)
|
||||
@@ -85,7 +65,7 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
|
||||
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
|
||||
|
||||
/proc/notes_add(var/key, var/note, var/mob/usr)
|
||||
/proc/notes_add(var/key, var/note, var/mob/user)
|
||||
if (!key || !note)
|
||||
return
|
||||
|
||||
@@ -111,9 +91,9 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
|
||||
|
||||
var/datum/player_info/P = new
|
||||
if (usr)
|
||||
P.author = usr.key
|
||||
P.rank = usr.client.holder.rank
|
||||
if (user)
|
||||
P.author = user.key
|
||||
P.rank = user.client.holder.rank
|
||||
else
|
||||
P.author = "Adminbot"
|
||||
P.rank = "Friendly Robot"
|
||||
@@ -123,8 +103,8 @@ datum/admins/proc/notes_gethtml(var/ckey)
|
||||
infos += P
|
||||
info << infos
|
||||
|
||||
message_admins("\blue [key_name_admin(usr)] has edited [key]'s notes.")
|
||||
log_admin("[key_name(usr)] has edited [key]'s notes.")
|
||||
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
|
||||
log_admin("[key_name(user)] has edited [key]'s notes.")
|
||||
|
||||
qdel(info)
|
||||
|
||||
|
||||
@@ -410,43 +410,11 @@
|
||||
dat += "Launching now..."
|
||||
|
||||
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
|
||||
|
||||
//todo
|
||||
|
||||
dat += "<hr>"
|
||||
for(var/antag_type in all_antag_types)
|
||||
var/datum/antagonist/A = all_antag_types[antag_type]
|
||||
dat += A.get_check_antag_output(src)
|
||||
dat += "</body></html>"
|
||||
usr << browse(dat, "window=roundstatus;size=400x500")
|
||||
else
|
||||
alert("The game hasn't started yet!")
|
||||
|
||||
/proc/check_role_table(name, list/members, admins, show_objectives=1)
|
||||
var/txt = "<br><table cellspacing=5><tr><td><b>[name]</b></td><td></td></tr>"
|
||||
for(var/datum/mind/M in members)
|
||||
txt += check_role_table_row(M.current, admins, show_objectives)
|
||||
txt += "</table>"
|
||||
return txt
|
||||
|
||||
/proc/check_role_table_row(mob/M, admins=src, show_objectives)
|
||||
if (!istype(M))
|
||||
return "<tr><td><i>Not found!</i></td></tr>"
|
||||
|
||||
var/txt = {"
|
||||
<tr>
|
||||
<td>
|
||||
<a href='?src=\ref[admins];adminplayeropts=\ref[M]'>[M.real_name]</a>
|
||||
[M.client ? "" : " <i>(logged out)</i>"]
|
||||
[M.is_dead() ? " <b><font color='red'>(DEAD)</font></b>" : ""]
|
||||
</td>
|
||||
<td>
|
||||
<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>
|
||||
</td>
|
||||
"}
|
||||
|
||||
if (show_objectives)
|
||||
txt += {"
|
||||
<td>
|
||||
<a href='?src=\ref[admins];traitor=\ref[M]'>Show Objective</a>
|
||||
</td>
|
||||
"}
|
||||
|
||||
txt += "</tr>"
|
||||
return txt
|
||||
|
||||
+32
-25
@@ -85,6 +85,7 @@
|
||||
banreason = "[banreason] (CUSTOM CID)"
|
||||
else
|
||||
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob")
|
||||
notes_add(playermob.ckey,banreason,usr)
|
||||
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
|
||||
|
||||
@@ -671,7 +672,7 @@
|
||||
msg = job
|
||||
else
|
||||
msg += ", [job]"
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]")
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
|
||||
message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes", 1)
|
||||
M << "\red<BIG><B>You have been jobbanned by [usr.client.ckey] from: [msg].</B></BIG>"
|
||||
M << "\red <B>The reason is: [reason]</B>"
|
||||
@@ -692,7 +693,7 @@
|
||||
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
|
||||
if(!msg) msg = job
|
||||
else msg += ", [job]"
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]")
|
||||
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
|
||||
message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
|
||||
M << "\red<BIG><B>You have been jobbanned by [usr.client.ckey] from: [msg].</B></BIG>"
|
||||
M << "\red <B>The reason is: [reason]</B>"
|
||||
@@ -746,25 +747,7 @@
|
||||
message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1)
|
||||
//M.client = null
|
||||
qdel(M.client)
|
||||
/*
|
||||
//Player Notes
|
||||
else if(href_list["notes"])
|
||||
var/ckey = href_list["ckey"]
|
||||
if(!ckey)
|
||||
var/mob/M = locate(href_list["mob"])
|
||||
if(ismob(M))
|
||||
ckey = M.ckey
|
||||
|
||||
switch(href_list["notes"])
|
||||
if("show")
|
||||
notes_show(ckey)
|
||||
if("add")
|
||||
notes_add(ckey,href_list["text"])
|
||||
notes_show(ckey)
|
||||
if("remove")
|
||||
notes_remove(ckey,text2num(href_list["from"]),text2num(href_list["to"]))
|
||||
notes_show(ckey)
|
||||
*/
|
||||
else if(href_list["removejobban"])
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
@@ -799,6 +782,7 @@
|
||||
return
|
||||
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
|
||||
ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.")
|
||||
notes_add(M.ckey,"[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.",usr)
|
||||
M << "\red<BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG>"
|
||||
M << "\red This is a temporary ban, it will be removed in [mins] minutes."
|
||||
feedback_inc("ban_tmp",1)
|
||||
@@ -831,6 +815,7 @@
|
||||
else
|
||||
M << "\red No ban appeals URL has been set."
|
||||
ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
|
||||
notes_add(M.ckey,"[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.",usr)
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
feedback_inc("ban_perma",1)
|
||||
@@ -1247,7 +1232,7 @@
|
||||
src.owner << "Name = <b>[M.name]</b>; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = <b>[M.key]</b>;"
|
||||
src.owner << "Location = [location_description];"
|
||||
src.owner << "[special_role_description]"
|
||||
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) (<A HREF='?src=\ref[src];adminplayerobservejump=\ref[M]'>JMP</A>) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
|
||||
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
|
||||
|
||||
else if(href_list["adminspawncookie"])
|
||||
if(!check_rights(R_ADMIN|R_FUN)) return
|
||||
@@ -1749,13 +1734,13 @@
|
||||
feedback_add_details("admin_secrets_fun_used","Aliens")
|
||||
log_admin("[key_name(usr)] spawned an alien infestation", 1)
|
||||
message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1)
|
||||
xenomorphs.random_spawn()
|
||||
xenomorphs.attempt_random_spawn()
|
||||
if("borers")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","Borers")
|
||||
log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1)
|
||||
message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1)
|
||||
borers.random_spawn()
|
||||
borers.attempt_random_spawn()
|
||||
|
||||
if("power")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
@@ -2061,7 +2046,7 @@
|
||||
if("aliens")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","AL")
|
||||
if(xenomorphs.random_spawn())
|
||||
if(xenomorphs.attempt_random_spawn())
|
||||
message_admins("[key_name_admin(usr)] has spawned aliens", 1)
|
||||
if("spiders")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
@@ -2659,4 +2644,26 @@ mob/living/carbon/human/can_centcom_reply()
|
||||
return istype(l_ear, /obj/item/device/radio/headset) || istype(r_ear, /obj/item/device/radio/headset)
|
||||
|
||||
mob/living/silicon/ai/can_centcom_reply()
|
||||
return common_radio != null && !check_unable(2)
|
||||
return common_radio != null && !check_unable(2)
|
||||
|
||||
/atom/proc/extra_admin_link()
|
||||
return
|
||||
|
||||
/mob/extra_admin_link(var/source)
|
||||
if(client && eyeobj)
|
||||
return "|<A HREF='?[source];adminplayerobservejump=\ref[eyeobj]'>EYE</A>"
|
||||
|
||||
/mob/dead/observer/extra_admin_link(var/source)
|
||||
if(mind && mind.current)
|
||||
return "|<A HREF='?[source];adminplayerobservejump=\ref[mind.current]'>BDY</A>"
|
||||
|
||||
/proc/admin_jump_link(var/atom/target, var/source)
|
||||
if(!target) return
|
||||
// The way admin jump links handle their src is weirdly inconsistent...
|
||||
if(istype(source, /datum/admins))
|
||||
source = "src=\ref[source]"
|
||||
else
|
||||
source = "_src_=holder"
|
||||
|
||||
. = "<A HREF='?[source];adminplayerobservejump=\ref[target]'>JMP</A>"
|
||||
. += target.extra_admin_link(source)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
/mob/proc/on_mob_jump()
|
||||
return
|
||||
|
||||
/mob/dead/observer/on_mob_jump()
|
||||
following = null
|
||||
|
||||
/client/proc/Jump(var/area/A in return_sorted_areas())
|
||||
set name = "Jump to Area"
|
||||
set desc = "Area to jump to"
|
||||
set category = "Admin"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = pick(get_area_turfs(A))
|
||||
|
||||
log_admin("[key_name(usr)] jumped to [A]")
|
||||
@@ -18,12 +24,12 @@
|
||||
/client/proc/jumptoturf(var/turf/T in world)
|
||||
set name = "Jump to Turf"
|
||||
set category = "Admin"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
if(config.allow_admin_jump)
|
||||
log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]", 1)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = T
|
||||
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -34,8 +40,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Mob"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -46,6 +51,7 @@
|
||||
var/turf/T = get_turf(M)
|
||||
if(T && isturf(T))
|
||||
feedback_add_details("admin_verb","JM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
A.on_mob_jump()
|
||||
A.loc = T
|
||||
else
|
||||
A << "This mob is not located in the game world."
|
||||
@@ -56,13 +62,13 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Coordinate"
|
||||
|
||||
if (!holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if (config.allow_admin_jump)
|
||||
if(src.mob)
|
||||
var/mob/A = src.mob
|
||||
A.on_mob_jump()
|
||||
A.x = tx
|
||||
A.y = ty
|
||||
A.z = tz
|
||||
@@ -76,8 +82,7 @@
|
||||
set category = "Admin"
|
||||
set name = "Jump to Key"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -91,6 +96,7 @@
|
||||
var/mob/M = selection:mob
|
||||
log_admin("[key_name(usr)] jumped to [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
usr.on_mob_jump()
|
||||
usr.loc = M.loc
|
||||
feedback_add_details("admin_verb","JK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -100,12 +106,12 @@
|
||||
set category = "Admin"
|
||||
set name = "Get Mob"
|
||||
set desc = "Mob to teleport"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
if(config.allow_admin_jump)
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -116,8 +122,7 @@
|
||||
set name = "Get Key"
|
||||
set desc = "Key to teleport"
|
||||
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
|
||||
if(config.allow_admin_jump)
|
||||
@@ -134,6 +139,7 @@
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1)
|
||||
if(M)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
feedback_add_details("admin_verb","GK") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
else
|
||||
@@ -142,16 +148,16 @@
|
||||
/client/proc/sendmob(var/mob/M in sortmobs())
|
||||
set category = "Admin"
|
||||
set name = "Send Mob"
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
var/area/A = input(usr, "Pick an area.", "Pick an area") in return_sorted_areas()
|
||||
if(A)
|
||||
if(config.allow_admin_jump)
|
||||
M.on_mob_jump()
|
||||
M.loc = pick(get_area_turfs(A))
|
||||
feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]", 1)
|
||||
else
|
||||
alert("Admin jumping disabled")
|
||||
alert("Admin jumping disabled")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
if(check_rights(R_ADMIN,0))
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>(<a href='?_src_=holder;adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
|
||||
C << "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>([admin_jump_link(mob, src)]): <span class='message'>[msg]</span></span>"
|
||||
|
||||
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
sender_name = "<span class='admin'>[sender_name]</span>"
|
||||
for(var/client/C in admins)
|
||||
C << "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>(<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
|
||||
C << "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>"
|
||||
|
||||
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -18,16 +18,7 @@
|
||||
if (src.handle_spam_prevention(msg,MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
var/stafftype = null
|
||||
|
||||
if (src.holder.rights & R_MOD)
|
||||
stafftype = "MOD"
|
||||
|
||||
if (src.holder.rights & R_MENTOR)
|
||||
stafftype = "MENTOR"
|
||||
|
||||
if (src.holder.rights & R_ADMIN)
|
||||
stafftype = "ADMIN"
|
||||
var/stafftype = uppertext(holder.rank)
|
||||
|
||||
msg = sanitize(msg)
|
||||
log_admin("[key_name(src)] : [msg]")
|
||||
|
||||
@@ -111,11 +111,10 @@ proc/Icarus_FireCannon(var/turf/target)
|
||||
target = locate(x, y, target.z)
|
||||
|
||||
// Finally fire the fucker.
|
||||
var/obj/effect/meteor/small/projectile = new (start)
|
||||
var/obj/effect/meteor/projectile = new (start)
|
||||
projectile.dest = target
|
||||
projectile.name = "main gun projectile" // stealthy
|
||||
projectile.hits = 6
|
||||
projectile.detonation_chance = 99 // it's a missile/cannon round thing!
|
||||
|
||||
// Make sure it travels
|
||||
spawn(0)
|
||||
|
||||
@@ -4,6 +4,10 @@ var/list/forbidden_varedit_object_types = list(
|
||||
/datum/feedback_variable //Prevents people messing with feedback gathering
|
||||
)
|
||||
|
||||
var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "bound_x", "bound_y", "step_x", "step_y", "force_ending")
|
||||
var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays")
|
||||
var/list/VVckey_edit = list("key", "ckey")
|
||||
|
||||
/*
|
||||
/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world)
|
||||
set category = "Debug"
|
||||
@@ -44,7 +48,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("text")
|
||||
var_value = input("Enter new text:","Text") as null|text//todo: sanitize ???
|
||||
var_value = input("Enter new text:","Text") as null|text
|
||||
|
||||
if("num")
|
||||
var_value = input("Enter new number:","Num") as null|num
|
||||
@@ -72,7 +76,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
return var_value
|
||||
|
||||
|
||||
/client/proc/mod_list_add(var/list/L)
|
||||
/client/proc/mod_list_add(var/list/L, atom/O, original_name, objectvar)
|
||||
|
||||
var/class = "text"
|
||||
if(src.holder && src.holder.marked_datum)
|
||||
@@ -93,7 +97,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("text")
|
||||
var_value = input("Enter new text:","Text") as text//todo: sanitize ???
|
||||
var_value = input("Enter new text:","Text") as text
|
||||
|
||||
if("num")
|
||||
var_value = input("Enter new number:","Num") as num
|
||||
@@ -124,30 +128,58 @@ var/list/forbidden_varedit_object_types = list(
|
||||
L[var_value] = mod_list_add_ass() //haha
|
||||
if("No")
|
||||
L += var_value
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: ADDED=[var_value]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
|
||||
/client/proc/mod_list(var/list/L)
|
||||
/client/proc/mod_list(var/list/L, atom/O, original_name, objectvar)
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
if(!istype(L,/list)) src << "Not a List."
|
||||
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state")
|
||||
var/list/names = sortList(L)
|
||||
if(L.len > 1000)
|
||||
var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort")
|
||||
if(confirm != "Continue")
|
||||
return
|
||||
|
||||
var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)"
|
||||
var/assoc = 0
|
||||
if(L.len > 0)
|
||||
var/a = L[1]
|
||||
if(istext(a) && L[a] != null)
|
||||
assoc = 1 //This is pretty weak test but i can't think of anything else
|
||||
usr << "List appears to be associative."
|
||||
|
||||
var/list/names = null
|
||||
if(!assoc)
|
||||
names = sortList(L)
|
||||
|
||||
var/variable
|
||||
var/assoc_key
|
||||
if(assoc)
|
||||
variable = input("Which var?","Var") as null|anything in L + "(ADD VAR)"
|
||||
else
|
||||
variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)"
|
||||
|
||||
if(variable == "(ADD VAR)")
|
||||
mod_list_add(L)
|
||||
mod_list_add(L, O, original_name, objectvar)
|
||||
return
|
||||
|
||||
if(!variable)
|
||||
if(assoc)
|
||||
assoc_key = variable
|
||||
variable = L[assoc_key]
|
||||
|
||||
if(!assoc && !variable || assoc && !assoc_key)
|
||||
return
|
||||
|
||||
var/default
|
||||
|
||||
var/dir
|
||||
|
||||
if(variable in locked)
|
||||
if(variable in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(variable in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
if(isnull(variable))
|
||||
usr << "Unable to determine variable type."
|
||||
@@ -212,14 +244,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
usr << "If a direction, direction is: [dir]"
|
||||
|
||||
var/class = "text"
|
||||
var/list/choices = list("text","num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
|
||||
if(src.holder && src.holder.marked_datum)
|
||||
choices += "marked datum ([holder.marked_datum.type])"
|
||||
if(!isnull(default) && default != "num")
|
||||
choices += "edit associated variable"
|
||||
choices += "DELETE FROM LIST"
|
||||
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in choices
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
|
||||
"num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST")
|
||||
else
|
||||
class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
|
||||
"num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST")
|
||||
|
||||
if(!class)
|
||||
return
|
||||
@@ -227,61 +257,107 @@ var/list/forbidden_varedit_object_types = list(
|
||||
if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
|
||||
class = "marked datum"
|
||||
|
||||
var/original_var
|
||||
if(assoc)
|
||||
original_var = L[assoc_key]
|
||||
else
|
||||
original_var = L[L.Find(variable)]
|
||||
|
||||
var/new_var
|
||||
switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet.
|
||||
|
||||
if("list")
|
||||
mod_list(variable)
|
||||
mod_list(variable, O, original_name, objectvar)
|
||||
|
||||
if("restore to default")
|
||||
L[L.Find(variable)]=initial(variable)
|
||||
new_var = initial(variable)
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("edit referenced object")
|
||||
modify_variables(variable)
|
||||
|
||||
if("DELETE FROM LIST")
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[variable]")]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]")
|
||||
L -= variable
|
||||
return
|
||||
|
||||
if("text")
|
||||
L[L.Find(variable)] = input("Enter new text:","Text") as text//todo: sanitize ???
|
||||
new_var = input("Enter new text:","Text") as text
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("num")
|
||||
L[L.Find(variable)] = input("Enter new number:","Num") as num
|
||||
new_var = input("Enter new number:","Num") as num
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("type")
|
||||
L[L.Find(variable)] = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
|
||||
new_var = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("reference")
|
||||
L[L.Find(variable)] = input("Select reference:","Reference") as mob|obj|turf|area in world
|
||||
new_var = input("Select reference:","Reference") as mob|obj|turf|area in world
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("mob reference")
|
||||
L[L.Find(variable)] = input("Select reference:","Reference") as mob in world
|
||||
new_var = input("Select reference:","Reference") as mob in world
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("file")
|
||||
L[L.Find(variable)] = input("Pick file:","File") as file
|
||||
new_var = input("Pick file:","File") as file
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("icon")
|
||||
L[L.Find(variable)] = input("Pick icon:","Icon") as icon
|
||||
new_var = input("Pick icon:","Icon") as icon
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
if("marked datum")
|
||||
L[L.Find(variable)] = holder.marked_datum
|
||||
|
||||
if("edit associated variable")
|
||||
var/temp_var = mod_list_add_ass()
|
||||
if(temp_var)
|
||||
L[variable] = temp_var
|
||||
new_var = holder.marked_datum
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[L.Find(variable)] = new_var
|
||||
|
||||
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: [original_var]=[new_var]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
|
||||
|
||||
/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state")
|
||||
|
||||
for(var/p in forbidden_varedit_object_types)
|
||||
if( istype(O,p) )
|
||||
usr << "\red It is forbidden to edit this object's variables."
|
||||
usr << "<span class='danger'>It is forbidden to edit this object's variables.</span>"
|
||||
return
|
||||
|
||||
if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key"))
|
||||
usr << "<span class='danger'>You cannot edit ckeys on client objects.</span>"
|
||||
return
|
||||
|
||||
var/class
|
||||
var/variable
|
||||
var/var_value
|
||||
@@ -291,8 +367,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])"
|
||||
return
|
||||
|
||||
if(param_var_name == "holder" || (param_var_name in locked))
|
||||
if(param_var_name in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(param_var_name in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(param_var_name in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
variable = param_var_name
|
||||
|
||||
@@ -349,8 +429,12 @@ var/list/forbidden_varedit_object_types = list(
|
||||
if(!variable) return
|
||||
var_value = O.vars[variable]
|
||||
|
||||
if(variable == "holder" || (variable in locked))
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVlocked)
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(variable in VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG)) return
|
||||
if(variable in VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG)) return
|
||||
|
||||
if(!autodetect_class)
|
||||
|
||||
@@ -440,7 +524,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
switch(class)
|
||||
|
||||
if("list")
|
||||
mod_list(O.vars[variable])
|
||||
mod_list(O.vars[variable], O, original_name, variable)
|
||||
return
|
||||
|
||||
if("restore to default")
|
||||
@@ -450,7 +534,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
return .(O.vars[variable])
|
||||
|
||||
if("text")
|
||||
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text//todo: sanitize ???
|
||||
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text
|
||||
if(var_new==null) return
|
||||
O.vars[variable] = var_new
|
||||
|
||||
@@ -504,5 +588,4 @@ var/list/forbidden_varedit_object_types = list(
|
||||
|
||||
world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1)
|
||||
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return
|
||||
|
||||
var/image/cross = image('icons/obj/storage.dmi',"bible")
|
||||
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
|
||||
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
@@ -29,13 +29,13 @@
|
||||
//log_admin("HELP: [key_name(src)]: [msg]")
|
||||
|
||||
/proc/Centcomm_announce(var/msg, var/mob/Sender, var/iamessage)
|
||||
msg = "\blue <b><font color=orange>CENTCOMM[iamessage ? " IA" : ""]:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
msg = "\blue <b><font color=orange>CENTCOMM[iamessage ? " IA" : ""]:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << msg
|
||||
|
||||
/proc/Syndicate_announce(var/msg, var/mob/Sender)
|
||||
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
C << msg
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
|
||||
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
|
||||
src << "<span class='info'>You have unread updates in the changelog.</span>"
|
||||
winset(src, "rpane.changelogb", "background-color=#eaeaea;font-style=bold")
|
||||
winset(src, "rpane.changelog", "background-color=#eaeaea;font-style=bold")
|
||||
if(config.aggressive_changelog)
|
||||
src.changes()
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -370,7 +370,7 @@
|
||||
if(sealing)
|
||||
fail_msg = "<span class='warning'>The hardsuit is in the process of adjusting seals and cannot be activated.</span>"
|
||||
else if(!fail_msg && ((use_unconcious && user.stat > 1) || (!use_unconcious && user.stat)))
|
||||
fail_msg = "<span class='warning'>You are in no fit state to do that."
|
||||
fail_msg = "<span class='warning'>You are in no fit state to do that.</span>"
|
||||
else if(!cell)
|
||||
fail_msg = "<span class='warning'>There is no cell installed in the suit.</span>"
|
||||
else if(cost && cell.charge < cost * 10) //TODO: Cellrate?
|
||||
@@ -754,7 +754,7 @@
|
||||
|
||||
if(wearer)
|
||||
if(dam_module.damage >= 2)
|
||||
wearer << "<span class='danger'>The [source] has disabled your [dam_module.interface_name]!"
|
||||
wearer << "<span class='danger'>The [source] has disabled your [dam_module.interface_name]!</span>"
|
||||
else
|
||||
wearer << "<span class='warning'>The [source] has damaged your [dam_module.interface_name]!"
|
||||
dam_module.deactivate()
|
||||
|
||||
@@ -11,20 +11,11 @@
|
||||
return chest.attackby(W,user)
|
||||
|
||||
// Lock or unlock the access panel.
|
||||
if(istype(W, /obj/item/weapon/card) || istype(W, /obj/item/device/pda))
|
||||
|
||||
if(W.GetID())
|
||||
if(subverted)
|
||||
locked = 0
|
||||
user << "<span class='danger'>It looks like the locking system has been shorted out.</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
locked_dna = null
|
||||
req_access.Cut()
|
||||
req_one_access.Cut()
|
||||
locked = 0
|
||||
subverted = 1
|
||||
user << "<span class='danger'>You short out the access protocol for the suit.</span>"
|
||||
return
|
||||
|
||||
if((!req_access || !req_access.len) && (!req_one_access || !req_one_access.len))
|
||||
locked = 0
|
||||
@@ -193,4 +184,14 @@
|
||||
if(electrified != 0)
|
||||
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/rig/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!subverted)
|
||||
locked_dna = null
|
||||
req_access.Cut()
|
||||
req_one_access.Cut()
|
||||
locked = 0
|
||||
subverted = 1
|
||||
user << "<span class='danger'>You short out the access protocol for the suit.</span>"
|
||||
return 1
|
||||
|
||||
@@ -19,6 +19,42 @@
|
||||
light_overlay = "helmet_light_dual"
|
||||
camera_networks = list("Security")
|
||||
|
||||
/obj/item/weapon/rig/internalaffairs
|
||||
name = "augmented tie"
|
||||
suit_type = "augmented suit"
|
||||
desc = "Prepare for paperwork."
|
||||
icon_state = "internalaffairs_rig"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.9
|
||||
slowdown = 0
|
||||
offline_slowdown = 0
|
||||
offline_vision_restriction = 0
|
||||
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/briefcase,/obj/item/weapon/storage/secure/briefcase)
|
||||
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
|
||||
glove_type = null
|
||||
helm_type = null
|
||||
boot_type = null
|
||||
|
||||
/obj/item/weapon/rig/internalaffairs/equipped
|
||||
|
||||
req_access = list(access_lawyer)
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
/obj/item/rig_module/device/flash,
|
||||
/obj/item/rig_module/device/paperdispenser,
|
||||
/obj/item/rig_module/device/pen,
|
||||
/obj/item/rig_module/device/stamp
|
||||
)
|
||||
|
||||
glove_type = null
|
||||
helm_type = null
|
||||
boot_type = null
|
||||
|
||||
/obj/item/weapon/rig/industrial
|
||||
name = "industrial suit control module"
|
||||
suit_type = "industrial hardsuit"
|
||||
|
||||
@@ -83,6 +83,10 @@
|
||||
if(H.wear_suit != src)
|
||||
return
|
||||
|
||||
if(boots)
|
||||
if (H.equip_to_slot_if_possible(boots, slot_shoes))
|
||||
boots.canremove = 0
|
||||
|
||||
if(helmet)
|
||||
if(H.head)
|
||||
M << "You are unable to deploy your suit's helmet as \the [H.head] is in the way."
|
||||
@@ -90,10 +94,6 @@
|
||||
M << "Your suit's helmet deploys with a hiss."
|
||||
helmet.canremove = 0
|
||||
|
||||
if(boots)
|
||||
if (H.equip_to_slot_if_possible(boots, slot_shoes))
|
||||
boots.canremove = 0
|
||||
|
||||
if(tank)
|
||||
if(H.s_store) //In case someone finds a way.
|
||||
M << "Alarmingly, the valve on your suit's installed tank fails to engage."
|
||||
@@ -101,6 +101,7 @@
|
||||
M << "The valve on your suit's installed tank safely engages."
|
||||
tank.canremove = 0
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/void/dropped()
|
||||
..()
|
||||
|
||||
@@ -151,7 +152,7 @@
|
||||
helmet.loc = src
|
||||
else
|
||||
if(H.head)
|
||||
H << "<span class='danger'>You cannot deploy your helmet while wearing another helmet.</span>"
|
||||
H << "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>"
|
||||
return
|
||||
if(H.equip_to_slot_if_possible(helmet, slot_head))
|
||||
helmet.pickup(H)
|
||||
@@ -161,7 +162,7 @@
|
||||
|
||||
/obj/item/clothing/suit/space/void/verb/eject_tank()
|
||||
|
||||
set name = "Eject Tank"
|
||||
set name = "Eject Voidsuit Tank"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
@@ -187,22 +188,26 @@
|
||||
if(!istype(user,/mob/living)) return
|
||||
|
||||
if(istype(src.loc,/mob/living))
|
||||
user << "<span class='danger'>How do you propose to modify a hardsuit while it is being worn?</span>"
|
||||
user << "<span class='danger'>How do you propose to modify a voidsuit while it is being worn?</span>"
|
||||
return
|
||||
|
||||
if(istype(W,/obj/item/weapon/screwdriver))
|
||||
if(tank)
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
src.tank = null
|
||||
else if(helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
src.helmet = null
|
||||
else if (boots)
|
||||
user << "You detatch \the [boots] from \the [src]'s boot mounts."
|
||||
boots.loc = get_turf(src)
|
||||
src.boots = null
|
||||
if(helmet || boots || tank)
|
||||
var/choice = input("What component would you like to remove?") as null|anything in list(helmet,boots,tank)
|
||||
if(!choice) return
|
||||
|
||||
if(choice == tank) //No, a switch doesn't work here. Sorry. ~Techhead
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
src.tank = null
|
||||
else if(choice == helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
src.helmet = null
|
||||
else if(choice == boots)
|
||||
user << "You detatch \the [boots] from \the [src]'s boot mounts."
|
||||
boots.loc = get_turf(src)
|
||||
src.boots = null
|
||||
else
|
||||
user << "\The [src] does not have anything installed."
|
||||
return
|
||||
|
||||
@@ -72,12 +72,12 @@
|
||||
|
||||
if(icon_state == icon_badge)
|
||||
icon_state = icon_nobadge
|
||||
usr << "You unclip the badge from the vest."
|
||||
usr << "You conceal \the [src]'s badge."
|
||||
else if(icon_state == icon_nobadge)
|
||||
icon_state = icon_badge
|
||||
usr << "You clip the badge to the vest."
|
||||
usr << "You reveal \the [src]'s badge."
|
||||
else
|
||||
usr << "You can't find a badge for [src]."
|
||||
usr << "\The [src] does not have a vest badge."
|
||||
return
|
||||
update_clothing_icon()
|
||||
|
||||
|
||||
@@ -55,19 +55,18 @@
|
||||
user << "Waving around a holobadge before swiping an ID would be pretty pointless."
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/badge/holo/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (emagged)
|
||||
user << "<span class='danger'>\The [src] is already cracked.</span>"
|
||||
return
|
||||
else
|
||||
emagged = 1
|
||||
user << "<span class='danger'>You crack the holobadge security checks.</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/accessory/badge/holo/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
|
||||
if (istype(O, /obj/item/weapon/card/emag))
|
||||
if (emagged)
|
||||
user << "<span class='danger'>[src] is already cracked.</span>"
|
||||
return
|
||||
else
|
||||
emagged = 1
|
||||
user << "<span class='danger'>You swipe [O] and crack the holobadge security checks.</span>"
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
|
||||
if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda))
|
||||
|
||||
var/obj/item/weapon/card/id/id_card = null
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
else
|
||||
if(user.a_intent == I_HURT)
|
||||
usr.visible_message(
|
||||
"\red [user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='danger'>[user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='warning'>You draw \the [holstered], ready to shoot!</span>"
|
||||
)
|
||||
else
|
||||
|
||||
@@ -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()
|
||||
@@ -119,6 +119,7 @@
|
||||
item_state = "paper"
|
||||
throwforce = 1
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_EARS
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
F.add_fingerprint(M)
|
||||
F.icon_state = "fingerprint1"
|
||||
F.name = text("FPrintC- '[M.name]'")
|
||||
user << "<span class='notice'>Done printing."
|
||||
user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]"
|
||||
user << "<span class='notice'>Done printing.</span>"
|
||||
user << "<span class='notice'>[M]'s Fingerprints: [md5(M.dna.uni_identity)]</span>"
|
||||
if ( M.blood_DNA && M.blood_DNA.len )
|
||||
user << "<span class='notice'>Blood found on [M]. Analysing...</span>"
|
||||
spawn(15)
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
screen = "details"
|
||||
current = files[href_list["identifier"]]
|
||||
else
|
||||
usr << "<spawn class='warning'>No record found.</span>"
|
||||
usr << "<span class='warning'>No record found.</span>"
|
||||
if("delete")
|
||||
if(href_list["identifier"])
|
||||
if(alert("Are you sure you want to delete this record?","Record deletion", "Yes", "No") == "Yes")
|
||||
@@ -265,7 +265,7 @@
|
||||
M.drop_item()
|
||||
I.loc = src
|
||||
else
|
||||
usr << "<spawn class='warning'>Invalid object, rejected.</span>"
|
||||
usr << "<span class='warning'>Invalid object, rejected.</span>"
|
||||
if("scan")
|
||||
if(scanning)
|
||||
scan_progress = 10
|
||||
@@ -279,7 +279,7 @@
|
||||
M.drop_item()
|
||||
qdel(I)
|
||||
else
|
||||
usr << "<spawn class='warning'>Invalid fingerprint card, rejected.</span>"
|
||||
usr << "<span class='warning'>Invalid fingerprint card, rejected.</span>"
|
||||
if("print")
|
||||
if(current)
|
||||
var/obj/item/weapon/paper/P = new(loc)
|
||||
|
||||
+17
-10
@@ -62,6 +62,22 @@ log transactions
|
||||
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
|
||||
break
|
||||
|
||||
/obj/machinery/atm/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!emagged)
|
||||
return
|
||||
|
||||
//short out the machine, shoot sparks, spew money!
|
||||
emagged = 1
|
||||
spark_system.start()
|
||||
spawn_money(rand(100,500),src.loc)
|
||||
//we don't want to grief people by locking their id in an emagged ATM
|
||||
release_held_id(user)
|
||||
|
||||
//display a message to the user
|
||||
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
|
||||
user << "<span class='warning'>\icon[src] The [src] beeps: \"[response]\"</span>"
|
||||
return 1
|
||||
|
||||
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/card))
|
||||
if(emagged > 0)
|
||||
@@ -69,16 +85,7 @@ log transactions
|
||||
user << "\red \icon[src] CARD READER ERROR. This system has been compromised!"
|
||||
return
|
||||
else if(istype(I,/obj/item/weapon/card/emag))
|
||||
//short out the machine, shoot sparks, spew money!
|
||||
emagged = 1
|
||||
spark_system.start()
|
||||
spawn_money(rand(100,500),src.loc)
|
||||
//we don't want to grief people by locking their id in an emagged ATM
|
||||
release_held_id(user)
|
||||
|
||||
//display a message to the user
|
||||
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
|
||||
user << "\red \icon[src] The [src] beeps: \"[response]\""
|
||||
I.resolve_attackby(src, user)
|
||||
return
|
||||
|
||||
var/obj/item/weapon/card/id/idcard = I
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "aiupload"
|
||||
density = 1
|
||||
req_one_access = list(access_hop, access_captain, access_cent_captain)
|
||||
anchored = 1
|
||||
var/receipt_num
|
||||
var/machine_id = ""
|
||||
var/obj/item/weapon/card/id/held_card
|
||||
|
||||
@@ -153,7 +153,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_SCIENTIST = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
|
||||
@@ -168,13 +168,13 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
/datum/event_container/major
|
||||
severity = EVENT_LEVEL_MAJOR
|
||||
available_events = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station,0,list(ASSIGNMENT_ANY = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ var/list/event_last_fired = list()
|
||||
possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"]
|
||||
if(minutes_passed >= 30) // Give engineers time to set up engine
|
||||
possibleEvents[/datum/event/meteor_wave] = 10 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/meteor_shower] = 20 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/blob] = 10 * active_with_role["Engineer"]
|
||||
|
||||
if(active_with_role["Medical"] > 0)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in world)
|
||||
if(prob(botEmagChance))
|
||||
bot.Emag()
|
||||
bot.emag_act(1)
|
||||
|
||||
/datum/event/ionstorm/end()
|
||||
spawn(rand(5000,8000))
|
||||
|
||||
@@ -1,44 +1,39 @@
|
||||
//meteor storms are much heavier
|
||||
/datum/event/meteor_wave
|
||||
startWhen = 6
|
||||
endWhen = 33
|
||||
|
||||
/datum/event/meteor_wave/setup()
|
||||
endWhen = rand(15,30) * 3
|
||||
|
||||
/datum/event/meteor_wave/announce()
|
||||
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
|
||||
/datum/event/meteor_wave/tick()
|
||||
if(IsMultiple(activeFor, 3))
|
||||
meteor_wave(rand(2,5))
|
||||
|
||||
/datum/event/meteor_wave/end()
|
||||
command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert")
|
||||
|
||||
//
|
||||
/datum/event/meteor_shower
|
||||
startWhen = 5
|
||||
endWhen = 7
|
||||
var/next_meteor = 6
|
||||
var/waves = 1
|
||||
|
||||
/datum/event/meteor_shower/setup()
|
||||
waves = rand(2,5)
|
||||
/datum/event/meteor_wave/setup()
|
||||
waves = severity * rand(1,3)
|
||||
|
||||
/datum/event/meteor_shower/announce()
|
||||
command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert")
|
||||
/datum/event/meteor_wave/announce()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
else
|
||||
command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert")
|
||||
|
||||
//meteor showers are lighter and more common,
|
||||
/datum/event/meteor_shower/tick()
|
||||
if(activeFor >= next_meteor)
|
||||
meteor_wave(rand(1,4))
|
||||
next_meteor += rand(20,100)
|
||||
/datum/event/meteor_wave/tick()
|
||||
if(waves && activeFor >= next_meteor)
|
||||
spawn() spawn_meteors(severity * rand(1,2), get_meteors())
|
||||
next_meteor += rand(15, 30) / severity
|
||||
waves--
|
||||
if(waves <= 0)
|
||||
endWhen = activeFor + 1
|
||||
else
|
||||
endWhen = next_meteor + 1
|
||||
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
|
||||
|
||||
/datum/event/meteor_shower/end()
|
||||
command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert")
|
||||
/datum/event/meteor_wave/end()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert")
|
||||
else
|
||||
command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert")
|
||||
|
||||
/datum/event/meteor_wave/proc/get_meteors()
|
||||
switch(severity)
|
||||
if(EVENT_LEVEL_MAJOR)
|
||||
return meteors_catastrophic
|
||||
if(EVENT_LEVEL_MODERATE)
|
||||
return meteors_threatening
|
||||
else
|
||||
return meteors_normal
|
||||
|
||||
@@ -44,27 +44,12 @@
|
||||
for(var/area/A in world)
|
||||
if(is_type_in_list(A,areaType) && !is_type_in_list(A,areaNotType))
|
||||
areas += A
|
||||
|
||||
if(areas && areas.len > 0)
|
||||
var/pass = 0
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
var/rc_message = "An unknown malicious program has been detected in the [english_list(areaName)] lighting and airlock control systems at [worldtime2text()]. Systems will be fully compromised within approximately three minutes. Direct intervention is required immediately.<br>"
|
||||
for(var/obj/machinery/message_server/MS in world)
|
||||
MS.send_rc_message("Engineering", my_department, rc_message, "", "", 2)
|
||||
pass = 1
|
||||
if(pass) //This entire block should be handled by send_rc_message(). I'm not rewriting it.
|
||||
var/sending = rc_message + "<font color='blue'><b>Message dispatched by [my_department].</b></font>"
|
||||
for (var/obj/machinery/requests_console/Console in allConsoles)
|
||||
var/keyed_department = ckey(Console.department)
|
||||
if(keyed_department == ckey("Engineering"))
|
||||
if(Console.newmessagepriority < 2)
|
||||
Console.newmessagepriority = 2
|
||||
Console.icon_state = "req_comp2"
|
||||
if(!Console.silent)
|
||||
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(5, Console.loc))
|
||||
O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [my_department]'"))
|
||||
Console.messages += "<B><FONT color='red'>High Priority message from [my_department]</FONT></B><BR>[sending]"
|
||||
|
||||
for(var/mob/living/silicon/ai/A in player_list)
|
||||
A << "<span class='danger'>Malicious program detected in the [english_list(areaName)] lighting and airlock control systems by [my_department].</span>"
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
valid_types |= antag
|
||||
if(valid_types.len)
|
||||
var/datum/antagonist/antag = pick(valid_types)
|
||||
antag.random_spawn()
|
||||
antag.attempt_random_spawn()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
/proc/send2irc(var/channel, var/msg)
|
||||
if(config.use_irc_bot && config.irc_bot_host)
|
||||
if(config.use_lib_nudge)
|
||||
var/nudge_lib
|
||||
if(world.system_type == MS_WINDOWS)
|
||||
nudge_lib = "lib\\nudge.dll"
|
||||
else
|
||||
nudge_lib = "lib/nudge.so"
|
||||
|
||||
spawn(0)
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
if(config.irc_bot_export)
|
||||
world.Export("http://[config.irc_bot_host]:45678?[list2params(list(pwd=config.comms_password, chan=channel, mesg=msg))]")
|
||||
else
|
||||
spawn(0)
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
if(config.use_lib_nudge)
|
||||
var/nudge_lib
|
||||
if(world.system_type == MS_WINDOWS)
|
||||
nudge_lib = "lib\\nudge.dll"
|
||||
else
|
||||
nudge_lib = "lib/nudge.so"
|
||||
|
||||
spawn(0)
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
else
|
||||
spawn(0)
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
return
|
||||
|
||||
/proc/send2mainirc(var/msg)
|
||||
@@ -26,6 +29,6 @@
|
||||
|
||||
|
||||
/hook/startup/proc/ircNotify()
|
||||
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
|
||||
send2mainirc("Server starting up on byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -109,6 +109,6 @@ proc/populate_ghost_traps()
|
||||
/datum/ghosttrap/plant/welcome_candidate(var/mob/target)
|
||||
target << "<span class='alium><B>You awaken slowly, stirring into sluggish motion as the air caresses you.</B></span>"
|
||||
// This is a hack, replace with some kind of species blurb proc.
|
||||
if(istype(host,/mob/living/carbon/alien/diona))
|
||||
if(istype(target,/mob/living/carbon/alien/diona))
|
||||
target << "<B>You are \a [target], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
|
||||
target << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
|
||||
@@ -120,17 +120,17 @@
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
if(istype(D, /obj/item/weapon/card/emag))
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
last_to_emag = user //emag again to change the owner
|
||||
if (!emagged)
|
||||
emagged = 1
|
||||
safety_disabled = 1
|
||||
update_projections()
|
||||
user << "<span class='notice'>You vastly increase projector power and override the safety and security protocols.</span>"
|
||||
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
|
||||
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
|
||||
/obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
last_to_emag = user //emag again to change the owner
|
||||
if (!emagged)
|
||||
emagged = 1
|
||||
safety_disabled = 1
|
||||
update_projections()
|
||||
user << "<span class='notice'>You vastly increase projector power and override the safety and security protocols.</span>"
|
||||
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
|
||||
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
|
||||
return 1
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
@@ -158,16 +158,6 @@
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/meteorhit(var/obj/O as obj)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/emp_act(severity)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/ex_act(severity)
|
||||
emergencyShutdown()
|
||||
..()
|
||||
|
||||
@@ -55,4 +55,5 @@
|
||||
#define TRAIT_PRODUCT_COLOUR 35
|
||||
#define TRAIT_BIOLUM 36
|
||||
#define TRAIT_BIOLUM_COLOUR 37
|
||||
#define TRAIT_IMMUTABLE 38
|
||||
#define TRAIT_IMMUTABLE 38
|
||||
#define TRAIT_FLESH_COLOUR 39
|
||||
@@ -167,8 +167,8 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(seed) seed.thrown_at(src,hit_atom)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
|
||||
@@ -194,9 +194,11 @@
|
||||
else if(seed.chems)
|
||||
if(istype(W,/obj/item/weapon/material/hatchet) && !isnull(seed.chems["woodpulp"]))
|
||||
user.show_message("<span class='notice'>You make planks out of \the [src]!</span>", 1)
|
||||
var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
for(var/i=0,i<2,i++)
|
||||
var/obj/item/stack/material/wood/NG = new (user.loc)
|
||||
NG.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) NG.color = flesh_colour
|
||||
for (var/obj/item/stack/material/wood/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
@@ -221,6 +223,15 @@
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
else if(seed.get_trait(TRAIT_FLESH_COLOUR))
|
||||
user << "You slice up \the [src]."
|
||||
var/slices = rand(3,5)
|
||||
var/reagents_to_transfer = round(reagents.total_volume/slices)
|
||||
for(var/i=i;i<=slices;i++)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/F = new(get_turf(src),seed)
|
||||
if(reagents_to_transfer) reagents.trans_to_obj(F,reagents_to_transfer)
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone)
|
||||
@@ -301,9 +312,11 @@
|
||||
|
||||
if(seed.kitchen_tag == "grass")
|
||||
user.show_message("<span class='notice'>You make a grass tile out of \the [src]!</span>", 1)
|
||||
var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
for(var/i=0,i<2,i++)
|
||||
var/obj/item/stack/tile/grass/G = new (user.loc)
|
||||
G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) G.color = flesh_colour
|
||||
for (var/obj/item/stack/tile/grass/NG in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
@@ -358,3 +371,35 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris
|
||||
plantname = "ambrosia"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/fruit_slice
|
||||
name = "fruit slice"
|
||||
desc = "A slice of some tasty fruit."
|
||||
icon = 'icons/obj/hydroponics_misc.dmi'
|
||||
icon_state = ""
|
||||
|
||||
var/list/fruit_icon_cache = list()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/New(var/newloc, var/datum/seed/S)
|
||||
..(newloc)
|
||||
// Need to go through and make a general image caching controller. Todo.
|
||||
if(!istype(S))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
name = "[S.seed_name] slice"
|
||||
desc = "A slice of \a [S.seed_name]. Tasty, probably."
|
||||
|
||||
var/rind_colour = S.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
var/flesh_colour = S.get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = rind_colour
|
||||
if(!fruit_icon_cache["rind-[rind_colour]"])
|
||||
var/image/I = image(icon,"fruit_rind")
|
||||
I.color = rind_colour
|
||||
fruit_icon_cache["rind-[rind_colour]"] = I
|
||||
overlays |= fruit_icon_cache["rind-[rind_colour]"]
|
||||
if(!fruit_icon_cache["slice-[rind_colour]"])
|
||||
var/image/I = image(icon,"fruit_slice")
|
||||
I.color = flesh_colour
|
||||
fruit_icon_cache["slice-[rind_colour]"] = I
|
||||
overlays |= fruit_icon_cache["slice-[rind_colour]"]
|
||||
|
||||
@@ -169,8 +169,9 @@
|
||||
if(get_trait(TRAIT_BIOLUM_COLOUR))
|
||||
clr = get_trait(TRAIT_BIOLUM_COLOUR)
|
||||
splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
|
||||
if(get_trait(TRAIT_PRODUCT_COLOUR))
|
||||
splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
var/flesh_colour = get_trait(TRAIT_FLESH_COLOUR)
|
||||
if(!flesh_colour) flesh_colour = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
if(flesh_colour) splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
|
||||
if(chems)
|
||||
for(var/mob/living/M in T.contents)
|
||||
@@ -229,7 +230,8 @@
|
||||
for(var/mob/living/M in T.contents)
|
||||
apply_special_effect(M)
|
||||
splatter(T,thrown)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] explodes!</span>")
|
||||
if(origin_turf)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] explodes!</span>")
|
||||
qdel(thrown)
|
||||
return
|
||||
|
||||
@@ -242,7 +244,8 @@
|
||||
|
||||
if(get_trait(TRAIT_JUICY) && splatted)
|
||||
splatter(origin_turf,thrown)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] splatters against [target]!</span>")
|
||||
if(origin_turf)
|
||||
origin_turf.visible_message("<span class='danger'>The [thrown.name] splatters against [target]!</span>")
|
||||
qdel(thrown)
|
||||
|
||||
/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only)
|
||||
@@ -637,7 +640,7 @@
|
||||
if(GENE_STRUCTURE)
|
||||
traits_to_copy = list(TRAIT_PLANT_ICON,TRAIT_PRODUCT_ICON,TRAIT_HARVEST_REPEAT)
|
||||
if(GENE_FRUIT)
|
||||
traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_JUICY)
|
||||
traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_FLESH_COLOUR,TRAIT_JUICY)
|
||||
if(GENE_SPECIAL)
|
||||
traits_to_copy = list(TRAIT_TELEPORTING)
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@
|
||||
set_trait(TRAIT_PRODUCT_ICON,"apple")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#FF540A")
|
||||
set_trait(TRAIT_PLANT_ICON,"tree2")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#E8E39B")
|
||||
|
||||
/datum/seed/apple/poison
|
||||
name = "poisonapple"
|
||||
@@ -804,6 +805,7 @@
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#326B30")
|
||||
set_trait(TRAIT_PLANT_COLOUR,"#257522")
|
||||
set_trait(TRAIT_PLANT_ICON,"vine2")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#F22C2C")
|
||||
|
||||
/datum/seed/pumpkin
|
||||
name = "pumpkin"
|
||||
@@ -842,6 +844,7 @@
|
||||
set_trait(TRAIT_PRODUCT_ICON,"treefruit")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#3AF026")
|
||||
set_trait(TRAIT_PLANT_ICON,"tree")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#3AF026")
|
||||
|
||||
/datum/seed/citrus/lemon
|
||||
name = "lemon"
|
||||
@@ -854,6 +857,7 @@
|
||||
..()
|
||||
set_trait(TRAIT_PRODUCES_POWER,1)
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#F0E226")
|
||||
|
||||
/datum/seed/citrus/orange
|
||||
name = "orange"
|
||||
@@ -865,6 +869,7 @@
|
||||
/datum/seed/citrus/orange/New()
|
||||
..()
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#FFC20A")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#FFC20A")
|
||||
|
||||
/datum/seed/grass
|
||||
name = "grass"
|
||||
|
||||
@@ -196,16 +196,19 @@
|
||||
layer = 3
|
||||
density = 0
|
||||
|
||||
/obj/effect/plant/proc/calc_dir(turf/location = loc)
|
||||
/obj/effect/plant/proc/calc_dir()
|
||||
set background = 1
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
|
||||
var/direction = 16
|
||||
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/newTurf = get_step(location,wallDir)
|
||||
var/turf/newTurf = get_step(T,wallDir)
|
||||
if(newTurf.density)
|
||||
direction |= wallDir
|
||||
|
||||
for(var/obj/effect/plant/shroom in location)
|
||||
for(var/obj/effect/plant/shroom in T.contents)
|
||||
if(shroom == src)
|
||||
continue
|
||||
if(shroom.floor) //special
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
recipes += new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade)
|
||||
recipes += new/datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2)
|
||||
recipes += new/datum/stack_recipe("small light fixture frame", /obj/item/frame/light/small, 1)
|
||||
recipes += new/datum/stack_recipe("apc frame", /obj/item/apc_frame, 2)
|
||||
recipes += new/datum/stack_recipe("apc frame", /obj/item/frame/apc, 2)
|
||||
recipes += new/datum/stack_recipe("air alarm frame", /obj/item/frame/air_alarm, 2)
|
||||
recipes += new/datum/stack_recipe("fire alarm frame", /obj/item/frame/fire_alarm, 2)
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
desc = "A stack of sheets of [material.display_name]."
|
||||
recipes = material.get_recipes()
|
||||
stacktype = material.stack_type
|
||||
origin_tech = material.stack_origin_tech.Copy()
|
||||
if(islist(material.stack_origin_tech))
|
||||
origin_tech = material.stack_origin_tech.Copy()
|
||||
perunit = SHEET_MATERIAL_AMOUNT
|
||||
|
||||
if(apply_colour)
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
|
||||
@@ -171,12 +171,14 @@
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (locked)
|
||||
user << "<span class='notice'>The crate unlocks!</span>"
|
||||
locked = 0
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(locked)
|
||||
if (istype(W, /obj/item/weapon/card/emag))
|
||||
user << "<span class='notice'>The crate unlocks!</span>"
|
||||
locked = 0
|
||||
if (istype(W, /obj/item/device/multitool)) // Greetings Urist McProfessor, how about a nice game of cows and bulls?
|
||||
user << "<span class='notice'>DECA-CODE LOCK REPORT:</span>"
|
||||
if (attempts == 1)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
force = 0.0
|
||||
throwforce = 0.0
|
||||
w_class = 1.0
|
||||
slot_flags = SLOT_EARS
|
||||
var/string_attached
|
||||
var/sides = 2
|
||||
|
||||
|
||||
@@ -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,7 +2,7 @@
|
||||
//added different sort of gibs and animations. N
|
||||
/mob/proc/gib(anim="gibbed-m",do_gibs)
|
||||
death(1)
|
||||
monkeyizing = 1
|
||||
transforming = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
@@ -28,7 +28,7 @@
|
||||
/mob/proc/dust(anim="dust-m",remains=/obj/effect/decal/cleanable/ash)
|
||||
death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
monkeyizing = 1
|
||||
transforming = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/death(gibbed, deathmessage="seizes up and falls limp...")
|
||||
if(..())
|
||||
if(..(gibbed, deathmessage))
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cultnet.updateVisibility(src)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
return
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "(<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>) "
|
||||
track = "([ghost_follow_link(speaker, src)]) "
|
||||
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
|
||||
message = "<b>[message]</b>"
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
if(istype(src, /mob/dead/observer))
|
||||
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "[speaker_name] (<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>)"
|
||||
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
|
||||
|
||||
var/formatted
|
||||
if(language)
|
||||
@@ -197,18 +197,18 @@
|
||||
return "<span class='say_quote'>\[[worldtime2text()]\]</span>"
|
||||
|
||||
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
src << "[part_a][speaker_name][part_b][formatted]</span></span>"
|
||||
src << "[part_a][speaker_name][part_b][formatted]"
|
||||
|
||||
/mob/dead/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
src << "[part_a][track][part_b][formatted]</span></span>"
|
||||
src << "[part_a][track][part_b][formatted]"
|
||||
|
||||
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
var/time = say_timestamp()
|
||||
src << "[time][part_a][speaker_name][part_b][formatted]</span></span>"
|
||||
src << "[time][part_a][speaker_name][part_b][formatted]"
|
||||
|
||||
/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
var/time = say_timestamp()
|
||||
src << "[time][part_a][track][part_b][formatted]</span></span>"
|
||||
src << "[time][part_a][track][part_b][formatted]"
|
||||
|
||||
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
|
||||
if(!client)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/flags = 0 // Various language flags.
|
||||
var/native // If set, non-native speakers will have trouble speaking.
|
||||
var/list/syllables // Used when scrambling text for a non-speaker.
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string.
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
|
||||
|
||||
/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4)
|
||||
if(!syllables || !syllables.len)
|
||||
@@ -101,11 +101,22 @@
|
||||
log_say("[key_name(speaker)] : ([name]) [message]")
|
||||
|
||||
if(!speaker_mask) speaker_mask = speaker.name
|
||||
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [format_message(message, get_spoken_verb(message))]</span></i>"
|
||||
|
||||
for(var/mob/player in player_list)
|
||||
if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
|
||||
player << msg
|
||||
player.hear_broadcast(src, speaker, speaker_mask, format_message(message, get_spoken_verb(message)))
|
||||
|
||||
/mob/proc/hear_broadcast(var/datum/language/language, var/speaker, var/message)
|
||||
if((language in languages) && language.check_special_condition(src))
|
||||
var/msg = "<i><span class='game say'>[language.name], <span class='name'>[speaker]</span> [message]</span></i>"
|
||||
src << msg
|
||||
|
||||
/mob/new_player/hear_broadcast()
|
||||
return
|
||||
|
||||
/mob/dead/observer/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
|
||||
if(speaker.name == speaker_name || antagHUD)
|
||||
src << "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> ([ghost_follow_link(speaker, src)]) [message]</span></i>"
|
||||
else
|
||||
src << "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> [message]</span></i>"
|
||||
|
||||
/datum/language/proc/check_special_condition(var/mob/other)
|
||||
return 1
|
||||
|
||||
@@ -41,18 +41,18 @@
|
||||
colour = "tajaran"
|
||||
key = "j"
|
||||
flags = WHITELISTED
|
||||
syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \
|
||||
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \
|
||||
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \
|
||||
"hal","ket","jurl","mah","tul","cresh","azu","ragh", "mro", "mra")
|
||||
syllables = list("mrr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr",
|
||||
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r",
|
||||
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
|
||||
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
|
||||
|
||||
/datum/language/tajaran/get_random_name(var/gender)
|
||||
|
||||
var/new_name = ..(gender,1)
|
||||
if(prob(80))
|
||||
new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]"
|
||||
if(prob(50))
|
||||
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
|
||||
else
|
||||
new_name += ..(gender,1)
|
||||
new_name += " [..(gender,1)]"
|
||||
return new_name
|
||||
|
||||
/datum/language/skrell
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
for (var/mob/M in dead_mob_list)
|
||||
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
|
||||
M.show_message("[message_start] [message_body]", 2)
|
||||
M.show_message("[message_start] ([ghost_follow_link(speaker, M)]) [message_body]", 2)
|
||||
|
||||
for (var/mob/living/S in living_mob_list)
|
||||
|
||||
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
|
||||
continue
|
||||
else if(istype(S , /mob/living/silicon/ai))
|
||||
message_start = "<i><span class='game say'>[name], <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[speaker];trackname=[html_encode(speaker.name)]'><span class='name'>[speaker.name]</span></a>"
|
||||
message_start = "<i><span class='game say'>[name], <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[speaker];trackname=[html_encode(speaker.name)]'><span class='name'>[speaker.name]</span></a></span>"
|
||||
else if (!S.binarycheck())
|
||||
continue
|
||||
|
||||
|
||||
@@ -80,9 +80,6 @@
|
||||
else
|
||||
user << "<span class='notice'>[src] does not need a repair.</span>"
|
||||
return
|
||||
else if (istype(O, /obj/item/weapon/card/emag) && !emagged)
|
||||
Emag(user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -102,9 +99,8 @@
|
||||
if(!istype(D, /obj/machinery/door/firedoor) && !istype(D, /obj/machinery/door/blast) && D.check_access(botcard))
|
||||
D.open()
|
||||
|
||||
/mob/living/bot/proc/Emag(var/mob/user)
|
||||
log_and_message_admins("emagged [src]")
|
||||
return
|
||||
/mob/living/bot/emag_act(var/remaining_charges, var/mob/user)
|
||||
return 0
|
||||
|
||||
/mob/living/bot/proc/turn_on()
|
||||
if(stat)
|
||||
|
||||
@@ -232,12 +232,14 @@
|
||||
usr << "<span class='notice'>You press the weird button.</span>"
|
||||
attack_hand(usr)
|
||||
|
||||
/mob/living/bot/cleanbot/Emag(var/mob/user)
|
||||
..()
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
/mob/living/bot/cleanbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!screwloose || !oddbutton)
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/cleanbot/proc/get_targets()
|
||||
target_types = list()
|
||||
|
||||
@@ -64,13 +64,15 @@
|
||||
onclose(user, "autofarm")
|
||||
return
|
||||
|
||||
/mob/living/bot/farmbot/Emag(var/mob/user)
|
||||
..()
|
||||
if(user)
|
||||
user << "<span class='notice'>You short out [src]'s plant identifier circuits.</span>"
|
||||
spawn(rand(30, 50))
|
||||
visible_message("<span class='warning'>[src] buzzes oddly.</span>")
|
||||
emagged = 1
|
||||
/mob/living/bot/farmbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
if(user)
|
||||
user << "<span class='notice'>You short out [src]'s plant identifier circuits.</span>"
|
||||
spawn(rand(30, 50))
|
||||
visible_message("<span class='warning'>[src] buzzes oddly.</span>")
|
||||
emagged = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/farmbot/Topic(href, href_list)
|
||||
if(..())
|
||||
|
||||
@@ -47,11 +47,13 @@
|
||||
onclose(user, "autorepair")
|
||||
return
|
||||
|
||||
/mob/living/bot/floorbot/Emag(var/mob/user)
|
||||
..()
|
||||
emagged = 1
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
/mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
if(user)
|
||||
user << "<span class='notice'>The [src] buzzes and beeps.</span>"
|
||||
return 1
|
||||
|
||||
/mob/living/bot/floorbot/Topic(href, href_list)
|
||||
if(..())
|
||||
|
||||
@@ -219,8 +219,8 @@
|
||||
attack_hand(usr)
|
||||
return
|
||||
|
||||
/mob/living/bot/medbot/Emag(var/mob/user)
|
||||
..()
|
||||
/mob/living/bot/medbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
if(user)
|
||||
user << "<span class='warning'>You short out [src]'s reagent synthesis circuits.</span>"
|
||||
@@ -231,6 +231,7 @@
|
||||
emagged = 1
|
||||
on = 1
|
||||
update_icons()
|
||||
. = 1
|
||||
ignored |= user
|
||||
|
||||
/mob/living/bot/medbot/explode()
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/max_grown = 200
|
||||
var/time_of_birth
|
||||
var/language
|
||||
var/death_msg = "lets out a waning guttural screech, green blood bubbling from its maw."
|
||||
|
||||
/mob/living/carbon/alien/New()
|
||||
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
/mob/living/carbon/alien/attack_ui(slot_id)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/meteorhit(O as obj)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message(text("\red [] has been hit by []", src, O), 1)
|
||||
if (health > 0)
|
||||
adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
|
||||
adjustFireLoss(30)
|
||||
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/attack_hand(mob/living/carbon/M as mob)
|
||||
|
||||
..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/death(gibbed)
|
||||
if(!gibbed && dead_icon)
|
||||
icon_state = dead_icon
|
||||
return ..(gibbed,"lets out a waning guttural screech, green blood bubbling from its maw.")
|
||||
return ..(gibbed,death_msg)
|
||||
@@ -5,7 +5,7 @@
|
||||
speak_emote = list("chirrups")
|
||||
icon_state = "nymph"
|
||||
language = "Rootspeak"
|
||||
|
||||
death_msg = "expires with a pitiful chirrup..."
|
||||
universal_understand = 1
|
||||
universal_speak = 0 // Dionaea do not need to speak to people other than other dionaea.
|
||||
holder_type = /obj/item/weapon/holder/diona
|
||||
|
||||
@@ -4,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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,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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
if (src.custom_sprite == 1)//check for custom AI sprite, defaulting to blue screen if no.
|
||||
icon_state = "[ckey]-ai-crash"
|
||||
else
|
||||
icon_state = "ai-crash"
|
||||
|
||||
if(src.eyeobj)
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
@@ -20,4 +15,5 @@
|
||||
var/obj/item/device/aicard/card = loc
|
||||
card.update_icon()
|
||||
|
||||
return ..(gibbed,"gives one shrill beep before falling lifeless.")
|
||||
. = ..(gibbed,"gives one shrill beep before falling lifeless.")
|
||||
density = 1
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if (src.stat == UNCONSCIOUS)
|
||||
msg += "It is non-responsive and displaying the text: \"RUNTIME: Sensory Overload, stack 26/3\".\n"
|
||||
msg += "</span>"
|
||||
msg += "*---------*</span>"
|
||||
msg += "*---------*"
|
||||
if(hardware && (hardware.owner == src))
|
||||
msg += "<br>"
|
||||
msg += hardware.get_examine_desc()
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
var/datum/ai_icon/default_ai_icon = new/datum/ai_icon/blue()
|
||||
var/list/datum/ai_icon/ai_icons
|
||||
|
||||
/datum/ai_icon
|
||||
var/name
|
||||
var/alive_icon
|
||||
var/alive_light = "#FFFFFF"
|
||||
var/nopower_icon = "4"
|
||||
var/nopower_light = "#FFFFFF"
|
||||
var/dead_icon = "ai-crash"
|
||||
var/dead_light = "#000099"
|
||||
|
||||
/datum/ai_icon/New(var/name, var/alive_icon, var/nopower_icon, var/dead_icon, var/alive_light, var/nopower_light, var/dead_light)
|
||||
if(name)
|
||||
src.name = name
|
||||
src.alive_icon = alive_icon
|
||||
src.nopower_icon = nopower_icon
|
||||
src.dead_icon = dead_icon
|
||||
src.alive_light = alive_light
|
||||
src.nopower_light = nopower_light
|
||||
src.dead_light = dead_light
|
||||
if(!ai_icons)
|
||||
ai_icons = list()
|
||||
init_subtypes(/datum/ai_icon, ai_icons)
|
||||
..()
|
||||
|
||||
/datum/ai_icon/red
|
||||
name = "Red"
|
||||
alive_icon = "ai-red"
|
||||
alive_light = "#F04848"
|
||||
|
||||
/datum/ai_icon/green
|
||||
name = "Green"
|
||||
alive_icon = "ai-wierd"
|
||||
alive_light = "#00FF99"
|
||||
|
||||
/datum/ai_icon/blue
|
||||
name = "Blue"
|
||||
alive_icon = "ai"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/angry
|
||||
name = "Angry"
|
||||
alive_icon = "ai-angryface"
|
||||
alive_light = "#FFFF33"
|
||||
|
||||
/datum/ai_icon/bliss
|
||||
name = "Bliss"
|
||||
alive_icon = "ai-bliss"
|
||||
alive_light = "#5C7A4A"
|
||||
|
||||
/datum/ai_icon/chatterbox
|
||||
name = "Chatterbox"
|
||||
alive_icon = "ai-president"
|
||||
alive_light = "#40666B"
|
||||
|
||||
/datum/ai_icon/database
|
||||
name = "Database"
|
||||
alive_icon = "ai-database"
|
||||
|
||||
/datum/ai_icon/dorf
|
||||
name = "Dorf"
|
||||
alive_icon = "ai-dorf"
|
||||
|
||||
/datum/ai_icon/dugtodeep
|
||||
name = "Dug Too Deep"
|
||||
alive_icon = "ai-toodeep"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/firewall
|
||||
name = "Firewall"
|
||||
alive_icon = "ai-magma"
|
||||
alive_light = "#FF4126"
|
||||
|
||||
/datum/ai_icon/glitchman
|
||||
name = "Glitchman"
|
||||
alive_icon = "ai-glitchman"
|
||||
|
||||
/datum/ai_icon/goon
|
||||
name = "Goon"
|
||||
alive_icon = "ai-goon"
|
||||
alive_light = "#3E5C80"
|
||||
|
||||
/datum/ai_icon/heartline
|
||||
name = "Heartline"
|
||||
alive_icon = "ai-heartline"
|
||||
dead_icon = "ai-heartline_dead"
|
||||
|
||||
/datum/ai_icon/helios
|
||||
name = "Helios"
|
||||
alive_icon = "ai-helios"
|
||||
alive_light = "#F2CF73"
|
||||
|
||||
/datum/ai_icon/inverted
|
||||
name = "Inverted"
|
||||
alive_icon = "ai-u"
|
||||
alive_light = "#81DDFF"
|
||||
|
||||
/datum/ai_icon/lonestar
|
||||
name = "Lonestar"
|
||||
alive_icon = "ai-lonestar"
|
||||
alive_light = "#58751C"
|
||||
|
||||
/datum/ai_icon/matrix
|
||||
name = "Matrix"
|
||||
alive_icon = "ai-matrix"
|
||||
alive_light = "#449944"
|
||||
|
||||
/datum/ai_icon/monochrome
|
||||
name = "Monochrome"
|
||||
alive_icon = "ai-mono"
|
||||
alive_light = "#585858"
|
||||
|
||||
/datum/ai_icon/nanotrasen
|
||||
name = "Nanotrasen"
|
||||
alive_icon = "ai-nanotrasen"
|
||||
alive_light = "#000029"
|
||||
|
||||
/datum/ai_icon/rainbow
|
||||
name = "Rainbow"
|
||||
alive_icon = "ai-clown"
|
||||
alive_light = "#E50213"
|
||||
|
||||
/datum/ai_icon/smiley
|
||||
name = "Smiley"
|
||||
alive_icon = "ai-smiley"
|
||||
alive_light = "#F3DD00"
|
||||
|
||||
/datum/ai_icon/soviet
|
||||
name = "Soviet"
|
||||
alive_icon = "ai-redoctober"
|
||||
alive_light = "#FF4307"
|
||||
|
||||
/datum/ai_icon/Static
|
||||
name = "Static"
|
||||
alive_icon = "ai-static"
|
||||
alive_light = "#4784C1"
|
||||
|
||||
/datum/ai_icon/text
|
||||
name = "Text"
|
||||
alive_icon = "ai-text"
|
||||
|
||||
/datum/ai_icon/trapped
|
||||
name = "Trapped"
|
||||
alive_icon = "ai-hades"
|
||||
|
||||
/datum/ai_icon/triumvirate_static
|
||||
name = "Triumvirate"
|
||||
alive_icon = "ai-triumvirate"
|
||||
alive_light = "#020B2B"
|
||||
|
||||
/datum/ai_icon/triumvirate_static
|
||||
name = "Triumvirate Static"
|
||||
alive_icon = "ai-static"
|
||||
alive_light = "#020B2B"
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/Life()
|
||||
if (src.stat == 2)
|
||||
if (src.stat == DEAD)
|
||||
return
|
||||
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
//Being dead doesn't mean your temperature never changes
|
||||
@@ -20,10 +20,6 @@
|
||||
if(!psupply)
|
||||
create_powersupply()
|
||||
|
||||
if (src.machine)
|
||||
if (!( src.machine.check_eye(src) ))
|
||||
src.reset_view(null)
|
||||
|
||||
// Handle power damage (oxy)
|
||||
if(aiRestorePowerRoutine != 0 && !APU_power)
|
||||
// Lose power
|
||||
@@ -33,8 +29,8 @@
|
||||
aiRestorePowerRoutine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
|
||||
adjustOxyLoss(-1)
|
||||
|
||||
// Handle EMP-stun
|
||||
handle_stunned()
|
||||
handle_stunned() // Handle EMP-stun
|
||||
lying = 0 // Handle lying down
|
||||
|
||||
malf_process()
|
||||
|
||||
@@ -61,15 +57,18 @@
|
||||
src << "Alert cancelled. Power has been restored without our assistance."
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else if (aiRestorePowerRoutine==3)
|
||||
src << "Alert cancelled. Power has been restored."
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else if (APU_power)
|
||||
aiRestorePowerRoutine = 0
|
||||
src.blind.layer = 0
|
||||
updateicon()
|
||||
return
|
||||
else
|
||||
var/area/current_area = get_area(src)
|
||||
@@ -79,7 +78,7 @@
|
||||
aiRestorePowerRoutine = 1
|
||||
|
||||
//Blind the AI
|
||||
|
||||
updateicon()
|
||||
src.blind.screen_loc = "1,1 to 15,15"
|
||||
if (src.blind.layer!=18)
|
||||
src.blind.layer = 18
|
||||
@@ -147,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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user