Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into russian_roulette

This commit is contained in:
Chinsky
2015-08-14 05:57:00 +03:00
347 changed files with 7165 additions and 5184 deletions
+1 -1
View File
@@ -1097,7 +1097,7 @@ proc/admin_notice(var/message, var/rights)
else
new chosen(usr.loc)
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
log_and_message_admins("spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+4 -1
View File
@@ -83,10 +83,13 @@ var/list/admin_verbs_admin = list(
/client/proc/allow_character_respawn, /* Allows a ghost to respawn */
/client/proc/event_manager_panel,
/client/proc/empty_ai_core_toggle_latejoin,
/client/proc/empty_ai_core_toggle_latejoin,
/client/proc/aooc,
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
/client/proc/change_security_level
/client/proc/change_security_level,
/client/proc/view_chemical_reaction_logs,
/client/proc/makePAI
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
+141 -141
View File
@@ -1,147 +1,147 @@
//This stuff was originally intended to be integrated into the ban-system I was working on
//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
//enjoy ~Carn
/*
#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
datum/admins/proc/notes_show(var/ckey)
usr << browse("<head><title>Player Notes</title></head><body>[notes_gethtml(ckey)]</body>","window=player_notes;size=700x400")
datum/admins/proc/notes_gethtml(var/ckey)
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile) return "<font color='red'>Error: Cannot access [NOTESFILE]</font>"
if(ckey)
. = "<b>Notes for <a href='?src=\ref[src];notes=show'>[ckey]</a>:</b> <a href='?src=\ref[src];notes=add;ckey=[ckey]'>\[+\]</a> <a href='?src=\ref[src];notes=remove;ckey=[ckey]'>\[-\]</a><br>"
notesfile.cd = "/[ckey]"
var/index = 1
while( !notesfile.eof )
var/note
notesfile >> note
. += "[note] <a href='?src=\ref[src];notes=remove;ckey=[ckey];from=[index]'>\[-\]</a><br>"
index++
else
. = "<b>All Notes:</b> <a href='?src=\ref[src];notes=add'>\[+\]</a> <a href='?src=\ref[src];notes=remove'>\[-\]</a><br>"
notesfile.cd = "/"
for(var/dir in notesfile.dir)
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
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)
if(!notesfile) return
if(!ckey)
notesfile.cd = "/"
ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
if(!ckey) return
if(start_index)
notesfile.cd = "/[ckey]"
var/list/noteslist = list()
if(!end_index) end_index = start_index
var/index = 0
while( !notesfile.eof )
index++
var/temp
notesfile >> temp
if( (start_index <= index) && (index <= end_index) )
continue
noteslist += temp
notesfile.eof = -2 //Move to the start of the buffer and then erase.
for( var/note in noteslist )
notesfile << note
else
notesfile.cd = "/"
if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
notesfile.dir.Remove(ckey)
return
#undef NOTESFILE
*/
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
//This stuff was originally intended to be integrated into the ban-system I was working on
//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
//enjoy ~Carn
/*
#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
datum/admins/proc/notes_show(var/ckey)
usr << browse("<head><title>Player Notes</title></head><body>[notes_gethtml(ckey)]</body>","window=player_notes;size=700x400")
datum/admins/proc/notes_gethtml(var/ckey)
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile) return "<font color='red'>Error: Cannot access [NOTESFILE]</font>"
if(ckey)
. = "<b>Notes for <a href='?src=\ref[src];notes=show'>[ckey]</a>:</b> <a href='?src=\ref[src];notes=add;ckey=[ckey]'>\[+\]</a> <a href='?src=\ref[src];notes=remove;ckey=[ckey]'>\[-\]</a><br>"
notesfile.cd = "/[ckey]"
var/index = 1
while( !notesfile.eof )
var/note
notesfile >> note
. += "[note] <a href='?src=\ref[src];notes=remove;ckey=[ckey];from=[index]'>\[-\]</a><br>"
index++
else
. = "<b>All Notes:</b> <a href='?src=\ref[src];notes=add'>\[+\]</a> <a href='?src=\ref[src];notes=remove'>\[-\]</a><br>"
notesfile.cd = "/"
for(var/dir in notesfile.dir)
. += "<a href='?src=\ref[src];notes=show;ckey=[dir]'>[dir]</a><br>"
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)
if(!notesfile) return
if(!ckey)
notesfile.cd = "/"
ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
if(!ckey) return
if(start_index)
notesfile.cd = "/[ckey]"
var/list/noteslist = list()
if(!end_index) end_index = start_index
var/index = 0
while( !notesfile.eof )
index++
var/temp
notesfile >> temp
if( (start_index <= index) && (index <= end_index) )
continue
noteslist += temp
notesfile.eof = -2 //Move to the start of the buffer and then erase.
for( var/note in noteslist )
notesfile << note
else
notesfile.cd = "/"
if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
notesfile.dir.Remove(ckey)
return
#undef NOTESFILE
*/
//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/user)
if (!key || !note)
return
//Loading list of notes for this key
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos) infos = list()
//Overly complex timestamp creation
var/modifyer = "th"
switch(time2text(world.timeofday, "DD"))
if("01","21","31")
modifyer = "st"
if("02","22",)
modifyer = "nd"
if("03","23")
modifyer = "rd"
var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
if(copytext(day_string,1,2) == "0")
day_string = copytext(day_string,2)
var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
var/datum/player_info/P = new
if (!key || !note)
return
//Loading list of notes for this key
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos) infos = list()
//Overly complex timestamp creation
var/modifyer = "th"
switch(time2text(world.timeofday, "DD"))
if("01","21","31")
modifyer = "st"
if("02","22",)
modifyer = "nd"
if("03","23")
modifyer = "rd"
var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
if(copytext(day_string,1,2) == "0")
day_string = copytext(day_string,2)
var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
var/datum/player_info/P = new
if (user)
P.author = user.key
P.rank = user.client.holder.rank
else
P.author = "Adminbot"
P.rank = "Friendly Robot"
P.content = note
P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
infos += P
info << infos
else
P.author = "Adminbot"
P.rank = "Friendly Robot"
P.content = note
P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
infos += P
info << infos
message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
log_admin("[key_name(user)] has edited [key]'s notes.")
qdel(info)
//Updating list of keys with notes on them
var/savefile/note_list = new("data/player_notes.sav")
var/list/note_keys
note_list >> note_keys
if(!note_keys) note_keys = list()
if(!note_keys.Find(key)) note_keys += key
note_list << note_keys
qdel(note_list)
/proc/notes_del(var/key, var/index)
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos || infos.len < index) return
var/datum/player_info/item = infos[index]
infos.Remove(item)
info << infos
message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
qdel(info)
/proc/show_player_info_irc(var/key as text)
var/dat = " Info on [key]%0D%0A"
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos)
dat = "No information found on the given key."
else
for(var/datum/player_info/I in infos)
dat += "[I.content]%0D%0Aby [I.author] ([I.rank]) on [I.timestamp]%0D%0A%0D%0A"
return dat
qdel(info)
//Updating list of keys with notes on them
var/savefile/note_list = new("data/player_notes.sav")
var/list/note_keys
note_list >> note_keys
if(!note_keys) note_keys = list()
if(!note_keys.Find(key)) note_keys += key
note_list << note_keys
qdel(note_list)
/proc/notes_del(var/key, var/index)
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos || infos.len < index) return
var/datum/player_info/item = infos[index]
infos.Remove(item)
info << infos
message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
log_admin("[key_name(usr)] deleted one of [key]'s notes.")
qdel(info)
/proc/show_player_info_irc(var/key as text)
var/dat = " Info on [key]\n"
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos
if(!infos)
dat = "No information found on the given key."
else
for(var/datum/player_info/I in infos)
dat += "[I.content]\nby [I.author] ([I.rank]) on [I.timestamp]\n\n"
return list2params(list(dat))
+1 -1
View File
@@ -358,7 +358,7 @@
dat += "<td>NA</td>"
dat += {"<td>[(M.client ? "[M.client]" : "No client")]</td>
dat += {"<td>[M.key ? (M.client ? M.key : "[M.key] (DC)") : "No key"]</td>
<td align=center><A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>X</A></td>
<td align=center><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>
"}
+1 -12
View File
@@ -1651,18 +1651,7 @@
var/mob/M = O
M.real_name = obj_name
if (number == 1)
log_admin("[key_name(usr)] created a [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1)
break
else
log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
for(var/path in paths)
if(ispath(path, /mob))
message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1)
break
log_and_message_admins("created [number] [english_list(paths)]")
return
else if(href_list["secretsfun"])
+19
View File
@@ -42,6 +42,12 @@
icon = 'icons/misc/buildmode.dmi'
var/obj/effect/bmode/buildholder/master = null
/obj/effect/bmode/Destroy()
if(master && master.cl)
master.cl.screen -= src
master = null
return ..()
/obj/effect/bmode/builddir
icon_state = "build"
screen_loc = "NORTH,WEST"
@@ -117,6 +123,19 @@
var/obj/effect/bmode/buildquit/buildquit = null
var/atom/movable/throw_atom = null
/obj/effect/bmode/buildholder/Destroy()
qdel(builddir)
builddir = null
qdel(buildhelp)
buildhelp = null
qdel(buildmode)
buildmode = null
qdel(buildquit)
buildquit = null
throw_atom = null
cl = null
return ..()
/obj/effect/bmode/buildmode
icon_state = "buildmode1"
screen_loc = "NORTH,WEST+2"
+23 -5
View File
@@ -64,6 +64,28 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname) return
if(targetselected)
if(!target)
usr << "<span class='danger'>Your target no longer exists.</span>"
return
if(!hascall(target,procname))
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
return
else
if(copytext(procname, 1, 7) == "/proc/")
// nothing
else if(copytext(procname, 1, 6) == "proc/")
procname = "/[procname]"
else if(copytext(procname, 1, 2) == "/")
procname = "/proc[procname]"
else
procname = "/proc/[procname]"
// Procs have the strange property that text2path will return non-null, but ispath() will return false.
var/path = text2path(procname)
if(!path || ispath(path))
usr << "<span class='danger'>Invalid proc [procname]</span>"
return
var/argnum = input("Number of arguments","Number:",0) as num|null
if(!argnum && (argnum!=0)) return
@@ -117,13 +139,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!target)
usr << "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>"
return
if(!hascall(target,procname))
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
return
log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc
else
//this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
returnval = call(procname)(arglist(lst)) // Pass the lst as an argument list to the proc
@@ -200,7 +218,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!choice)
return 0
if(!istype(choice, /mob/dead/observer))
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
var/obj/item/device/paicard/card = new(T)
+1 -1
View File
@@ -52,4 +52,4 @@ var/const/commandos_possible = 6 //if more Commandos are needed in the future
usr << "Looks like someone beat you to it."
return
team.attempt_spawn(1)
team.attempt_random_spawn()
+7
View File
@@ -153,6 +153,13 @@
add_admin_verbs()
admin_memo_show()
// Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays.
// (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise)
spawn(5) // And wait a half-second, since it sounds like you can do this too fast.
if(src)
winset(src, null, "command=\".configure graphics-hwmode off\"")
winset(src, null, "command=\".configure graphics-hwmode on\"")
log_client_to_db()
send_resources()
+72 -35
View File
@@ -75,7 +75,7 @@ datum/preferences
var/b_eyes = 0 //Eye color
var/species = "Human" //Species datum to use.
var/species_preview //Used for the species selection window.
var/language = "None" //Secondary language
var/list/alternate_languages = list() //Secondary language(s)
var/list/gear //Custom/fluff item loadout.
//Some faction information.
@@ -85,7 +85,6 @@ datum/preferences
var/religion = "None" //Religious association.
//Mob preview
var/mob/living/carbon/human/dummy //the mannequin
var/icon/preview_icon = null
var/icon/preview_icon_front = null
var/icon/preview_icon_side = null
@@ -133,9 +132,12 @@ datum/preferences
var/metadata = ""
var/slot_name = ""
var/client/client = null
/datum/preferences/New(client/C)
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
if(istype(C))
client = C
if(!IsGuestKey(C.key))
load_path(C.ckey)
if(load_preferences())
@@ -308,7 +310,7 @@ datum/preferences
dat += "(<a href='?_src_=prefs;preference=all;task=random'>&reg;</A>)"
dat += "<br>"
dat += "Species: <a href='?src=\ref[user];preference=species;task=change'>[species]</a><br>"
dat += "Secondary Language:<br><a href='byond://?src=\ref[user];preference=language;task=input'>[language]</a><br>"
dat += "Blood Type: <a href='byond://?src=\ref[user];preference=b_type;task=input'>[b_type]</a><br>"
dat += "Skin Tone: <a href='?_src_=prefs;preference=s_tone;task=input'>[-s_tone + 35]/220<br></a>"
//dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
@@ -382,6 +384,25 @@ datum/preferences
else
dat += "<br><br>"
dat += "<b>Languages</b><br>"
var/datum/species/S = all_species[species]
if(S.language)
dat += "- [S.language]<br>"
if(S.default_language && S.default_language != S.language)
dat += "- [S.default_language]<br>"
if(S.num_alternate_languages)
if(alternate_languages.len)
for(var/i = 1 to alternate_languages.len)
var/lang = alternate_languages[i]
dat += "- [lang] - <a href='byond://?src=\ref[user];preference=language;remove=[i]'>remove</a><br>"
if(alternate_languages.len < S.num_alternate_languages)
dat += "- <a href='byond://?src=\ref[user];preference=language;add=1'>add</a> ([S.num_alternate_languages - alternate_languages.len] remaining)<br>"
else
dat += "- [species] cannot choose secondary languages.<br>"
dat += "<br><br>"
var/list/undies = gender == MALE ? underwear_m : underwear_f
dat += "Underwear: <a href ='?_src_=prefs;preference=underwear;task=input'><b>[get_key_by_value(undies,underwear)]</b></a><br>"
@@ -1127,6 +1148,32 @@ datum/preferences
if(gear_name == choice)
gear -= gear_name
break
else if(href_list["preference"] == "language")
if(href_list["remove"])
var/index = text2num(href_list["remove"])
alternate_languages.Cut(index, index+1)
if(href_list["add"])
var/datum/species/S = all_species[species]
if(alternate_languages.len >= S.num_alternate_languages)
alert(user, "You have already selected the maximum number of alternate languages for this species!")
else
var/list/available_languages = S.secondary_langs.Copy()
for(var/L in all_languages)
var/datum/language/lang = all_languages[L]
if(!(lang.flags & RESTRICTED) && (!config.usealienwhitelist || is_alien_whitelisted(user, L) || !(lang.flags & WHITELISTED)))
available_languages |= L
// make sure we don't let them waste slots on the default languages
available_languages -= S.language
available_languages -= S.default_language
available_languages -= alternate_languages
if(!available_languages.len)
alert(user, "There are no additional languages available to select.")
else
var/new_lang = input("Select an additional language", "Character Generation", null) as null|anything in available_languages
if(new_lang)
alternate_languages |= new_lang
switch(href_list["task"])
if("change")
@@ -1136,6 +1183,7 @@ datum/preferences
if(!choice) return
species_preview = choice
SetSpecies(user)
alternate_languages = list() // Reset their alternate languages. Todo: attempt to just fix it instead?
if("random")
switch(href_list["preference"])
@@ -1244,29 +1292,6 @@ datum/preferences
s_tone = 0
if("language")
var/languages_available
var/list/new_languages = list("None")
var/datum/species/S = all_species[species]
if(config.usealienwhitelist)
for(var/L in all_languages)
var/datum/language/lang = all_languages[L]
if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))||(S && (L in S.secondary_langs))))
new_languages += lang
languages_available = 1
if(!(languages_available))
alert(user, "There are not currently any available secondary languages.")
else
for(var/L in all_languages)
var/datum/language/lang = all_languages[L]
if(!(lang.flags & RESTRICTED))
new_languages += lang.name
language = input("Please select a secondary language", "Character Generation", null) in new_languages
if("metadata")
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
if(new_metadata)
@@ -1376,7 +1401,7 @@ datum/preferences
backbag = backbaglist.Find(new_backbag)
if("nt_relation")
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference") as null|anything in list("Loyal", "Supportive", "Neutral", "Skeptical", "Opposed")
var/new_relation = input(user, "Choose your relation to NT. Note that this represents what others can find out about your character by researching your background, not what your character actually thinks.", "Character Preference") as null|anything in COMPANY_ALIGNMENTS
if(new_relation)
nanotrasen_relation = new_relation
@@ -1641,18 +1666,30 @@ datum/preferences
character.gen_record = gen_record
character.exploit_record = exploit_record
character.change_gender(gender)
character.gender = gender
character.age = age
character.b_type = b_type
character.change_eye_color(r_eyes,g_eyes,b_eyes)
character.change_hair_color(r_hair,g_hair,b_hair)
character.change_facial_hair_color(r_facial,g_facial,b_facial)
character.change_skin_color(r_skin,g_skin,b_skin)
character.change_skin_tone(s_tone)
character.r_eyes = r_eyes
character.g_eyes = g_eyes
character.b_eyes = b_eyes
character.change_hair(h_style)
character.change_facial_hair(f_style)
character.r_hair = r_hair
character.g_hair = g_hair
character.b_hair = b_hair
character.r_facial = r_facial
character.g_facial = g_facial
character.b_facial = b_facial
character.r_skin = r_skin
character.g_skin = g_skin
character.b_skin = b_skin
character.s_tone = s_tone
character.h_style = h_style
character.f_style = f_style
character.home_system = home_system
character.citizenship = citizenship
+1 -1
View File
@@ -279,7 +279,7 @@ var/global/list/gear_datums = list()
/datum/gear/scanning_goggles
display_name = "scanning goggles"
path = /obj/item/clothing/glasses/science/scanners
path = /obj/item/clothing/glasses/regular/scanners
cost = 1
slot = slot_glasses
+25 -4
View File
@@ -107,9 +107,30 @@
S["gender"] >> gender
S["age"] >> age
S["species"] >> species
S["language"] >> language
S["spawnpoint"] >> spawnpoint
S["language"] >> alternate_languages
if(isnull(alternate_languages))
alternate_languages = list()
if(!islist(alternate_languages))
if(client)
// Warn them that we (probably) just broke their languages
client << "<span class='danger'>Your current character slot's languages list has been updated from an old version, and may not be what you expect.</span>"
if(alternate_languages in all_languages)
alternate_languages = list(alternate_languages)
else
alternate_languages = list()
// try to give them their species language
var/datum/species/SP = all_species[species]
if(SP)
alternate_languages |= SP.language
alternate_languages |= SP.default_language
// remove the Galcom that most races have as default_language
alternate_languages -= "Galactic Common"
//colors to be consolidated into hex strings (requires some work with dna code)
S["hair_red"] >> r_hair
S["hair_green"] >> g_hair
@@ -200,7 +221,7 @@
if(isnum(undershirt))
undershirt = undershirt_t[undershirt_t[undershirt]]
if(isnull(language)) language = "None"
if(isnull(alternate_languages)) alternate_languages = list()
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender)
@@ -265,7 +286,7 @@
S["gender"] << gender
S["age"] << age
S["species"] << species
S["language"] << language
S["language"] << alternate_languages
S["hair_red"] << r_hair
S["hair_green"] << g_hair
S["hair_blue"] << b_hair
@@ -346,4 +367,4 @@
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
#undef SAVEFILE_VERSION_MIN
+66 -2
View File
@@ -176,7 +176,7 @@ BLIND // can't see anything
slot_flags = SLOT_EYES
var/vision_flags = 0
var/darkness_view = 0//Base human is 2
var/invisa_view = 0
var/see_invisible = -1
sprite_sheets = list("Vox" = 'icons/mob/species/vox/eyes.dmi')
/obj/item/clothing/glasses/update_clothing_icon()
@@ -275,6 +275,41 @@ BLIND // can't see anything
update_icon(user)
user.update_action_buttons()
/obj/item/clothing/head/attack_ai(var/mob/user)
if(!mob_wear_hat(user))
return ..()
/obj/item/clothing/head/attack_generic(var/mob/user)
if(!mob_wear_hat(user))
return ..()
/obj/item/clothing/head/proc/mob_wear_hat(var/mob/user)
if(!Adjacent(user))
return 0
var/success
if(istype(user, /mob/living/silicon/robot/drone))
var/mob/living/silicon/robot/drone/D = user
if(D.hat)
success = 2
else
D.wear_hat(src)
success = 1
else if(istype(user, /mob/living/carbon/alien/diona))
var/mob/living/carbon/alien/diona/D = user
if(D.hat)
success = 2
else
D.wear_hat(src)
success = 1
if(!success)
return 0
else if(success == 2)
user << "<span class='warning'>You are already wearing a hat.</span>"
else if(success == 1)
user << "<span class='notice'>You crawl under \the [src].</span>"
return 1
/obj/item/clothing/head/update_icon(var/mob/user)
overlays.Cut()
@@ -303,6 +338,10 @@ BLIND // can't see anything
body_parts_covered = FACE|EYES
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
var/voicechange = 0
var/list/say_messages
var/list/say_verbs
/obj/item/clothing/mask/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
@@ -387,6 +426,7 @@ BLIND // can't see anything
var/worn_state = null
/obj/item/clothing/under/New()
..()
if(worn_state)
if(!item_state_slots)
item_state_slots = list()
@@ -399,6 +439,29 @@ BLIND // can't see anything
if((worn_state + "_d_s") in icon_states('icons/mob/uniform.dmi'))
rolled_down = 0
/obj/item/clothing/under/proc/update_rolldown_status()
var/mob/living/carbon/human/H
if(istype(src.loc, /mob/living/carbon/human))
H = src.loc
var/icon/under_icon
if(icon_override)
under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.name])
under_icon = sprite_sheets[H.species.name]
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else
under_icon = INV_W_UNIFORM_DEF_ICON
// The _s is because the icon update procs append it.
if(("[worn_state]_d_s") in icon_states(under_icon))
if(rolled_down != 1)
rolled_down = 0
else
rolled_down = -1
if(H) update_clothing_icon()
/obj/item/clothing/under/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
@@ -540,7 +603,8 @@ BLIND // can't see anything
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(rolled_down < 0)
update_rolldown_status()
if(rolled_down == -1)
usr << "<span class='notice'>You cannot roll down [src]!</span>"
return
+6 -7
View File
@@ -7,7 +7,6 @@
//slot_flags = SLOT_EYES
//var/vision_flags = 0
//var/darkness_view = 0//Base human is 2
//var/invisa_view = 0
var/prescription = 0
var/toggleable = 0
var/off_state = "degoggles"
@@ -62,11 +61,6 @@
..()
overlay = global_hud.science
/obj/item/clothing/glasses/science/scanners
name = "Scanning Goggles"
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
icon_state = "uzenwa_sissra_1"
/obj/item/clothing/glasses/night
name = "Night Vision Goggles"
desc = "You can totally see in the dark now!"
@@ -75,6 +69,7 @@
origin_tech = list(TECH_MAGNET = 2)
darkness_view = 7
toggleable = 1
see_invisible = SEE_INVISIBLE_NOLIGHTING
off_state = "denight"
/obj/item/clothing/glasses/night/New()
@@ -111,6 +106,11 @@
item_state = "glasses"
prescription = 1
body_parts_covered = 0
/obj/item/clothing/glasses/regular/scanners
name = "Scanning Goggles"
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
icon_state = "uzenwa_sissra_1"
/obj/item/clothing/glasses/regular/hipster
name = "Prescription Glasses"
@@ -220,7 +220,6 @@
origin_tech = list(TECH_MAGNET = 3)
toggleable = 1
vision_flags = SEE_MOBS
invisa_view = 2
emp_act(severity)
if(istype(src.loc, /mob/living/carbon/human))
+1 -1
View File
@@ -33,7 +33,7 @@
icon_state = "jensenshades"
item_state = "jensenshades"
vision_flags = SEE_MOBS
invisa_view = 2
see_invisible = SEE_INVISIBLE_NOLIGHTING
/obj/item/clothing/glasses/hud/security/process_hud(var/mob/M)
process_sec_hud(M, 1)
-1
View File
@@ -2,7 +2,6 @@
name = "cargo cap"
desc = "It's a peaked cap in a tasteless yellow color."
icon_state = "cargosoft"
flags = HEADCOVERSEYES
item_state_slots = list(
slot_l_hand_str = "helmet", //probably a placeholder
slot_r_hand_str = "helmet",
+4 -2
View File
@@ -46,6 +46,8 @@
/obj/item/clothing/mask/gas/swat/vox
name = "\improper alien mask"
desc = "Clearly not designed for a human face."
body_parts_covered = 0 //Hack to allow vox to eat while wearing this mask.
species_restricted = list("Vox")
/obj/item/clothing/mask/gas/syndicate
name = "tactical mask"
@@ -55,7 +57,7 @@
/obj/item/clothing/mask/gas/clown_hat
name = "clown wig and mask"
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
desc = "A true prankster's facial attire. A clown is incomplete without their wig and mask."
icon_state = "clown"
item_state = "clown_hat"
@@ -98,4 +100,4 @@
/obj/item/clothing/mask/gas/owl_mask
name = "owl mask"
desc = "Twoooo!"
icon_state = "owl"
icon_state = "owl"
+12 -1
View File
@@ -7,6 +7,12 @@
body_parts_covered = 0
w_class = 2
gas_transfer_coefficient = 0.90
voicechange = 1
/obj/item/clothing/mask/muzzle/New()
..()
say_messages = list("Mmfph!", "Mmmf mrrfff!", "Mmmf mnnf!")
say_verbs = list("mumbles", "says")
// Clumsy folks can't take the mask off themselves.
/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
@@ -99,9 +105,14 @@
flags_inv = HIDEFACE
body_parts_covered = HEAD|FACE|EYES
w_class = 2
var/voicechange = 0
siemens_coefficient = 0.9
/obj/item/clothing/mask/horsehead/New()
..()
// The horse mask doesn't cause voice changes by default, the wizard spell changes the flag as necessary
say_messages = list("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
say_verbs = list("whinnies", "neighs", "says")
/obj/item/clothing/mask/ai
name = "camera MIU"
desc = "Allows for direct mental connection to accessible camera networks."
+16 -10
View File
@@ -178,23 +178,29 @@ var/global/list/breach_burn_descriptors = list(
//Handles repairs (and also upgrades).
/obj/item/clothing/suit/space/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack/material/plastic) || istype(W,/obj/item/stack/material/steel))
if(istype(W,/obj/item/stack/material))
var/repair_power = 0
switch(W.get_material_name())
if(DEFAULT_WALL_MATERIAL)
repair_power = 2
if("plastic")
repair_power = 1
if(!repair_power)
return
if(istype(src.loc,/mob/living))
user << "\red How do you intend to patch a hardsuit while someone is wearing it?"
user << "<span class='warning'>How do you intend to patch a hardsuit while someone is wearing it?</span>"
return
if(!damage || !burn_damage)
user << "There is no surface damage on \the [src] to repair."
return
var/obj/item/stack/material/P = W
if(P.get_amount() < 3)
P.use(P.get_amount())
repair_breaches(BURN, ( istype(P,/obj/item/stack/material/plastic) ? P.get_amount() : (P.get_amount()*2) ), user)
else
P.use(3)
repair_breaches(BURN, ( istype(P,/obj/item/stack/material/plastic) ? 3 : 5), user)
var/obj/item/stack/P = W
var/use_amt = min(P.get_amount(), 3)
if(use_amt && P.use(use_amt))
repair_breaches(BURN, use_amt * repair_power, user)
return
else if(istype(W, /obj/item/weapon/weldingtool))
+11 -16
View File
@@ -71,6 +71,7 @@
var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this.
var/vision_restriction
var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets.
var/airtight = 1 //If set, will adjust AIRTIGHT and STOPPRESSUREDAMAGE flags on components. Otherwise it should leave them untouched.
var/emp_protection = 0
@@ -178,8 +179,9 @@
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)]"
piece.flags &= ~STOPPRESSUREDAMAGE
piece.flags &= ~AIRTIGHT
if(airtight)
piece.flags &= ~STOPPRESSUREDAMAGE
piece.flags &= ~AIRTIGHT
update_icon(1)
/obj/item/weapon/rig/proc/toggle_seals(var/mob/living/carbon/human/M,var/instant)
@@ -247,11 +249,6 @@
M << "<font color='blue'>\The [piece] hisses [!seal_target ? "closed" : "open"].</font>"
M.update_inv_head()
if(helmet)
if(!seal_target)
if(flags & AIRTIGHT)
helmet.flags |= AIRTIGHT
else
helmet.flags &= ~AIRTIGHT
helmet.update_light(wearer)
//sealed pieces become airtight, protecting against diseases
@@ -273,13 +270,8 @@
if(!piece) continue
piece.icon_state = "[initial(icon_state)][!seal_target ? "" : "_sealed"]"
canremove = !seal_target
if(helmet)
if(canremove)
if(flags & AIRTIGHT)
helmet.flags |= AIRTIGHT
else
if(flags & AIRTIGHT)
helmet.flags &= ~AIRTIGHT
if(airtight)
update_component_sealed()
update_icon(1)
return 0
@@ -290,15 +282,18 @@
if(canremove)
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
if(airtight)
update_component_sealed()
update_icon(1)
/obj/item/weapon/rig/proc/update_component_sealed()
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
if(canremove)
piece.flags &= ~STOPPRESSUREDAMAGE
piece.flags &= ~AIRTIGHT
else
piece.flags |= STOPPRESSUREDAMAGE
piece.flags |= AIRTIGHT
update_icon(1)
/obj/item/weapon/rig/process()
@@ -7,7 +7,7 @@
return
// Pass repair items on to the chestpiece.
if(chest && (istype(W,/obj/item/stack/material/plastic) || istype(W,/obj/item/stack/material/steel) || istype(W, /obj/item/weapon/weldingtool)))
if(chest && (istype(W,/obj/item/stack/material) || istype(W, /obj/item/weapon/weldingtool)))
return chest.attackby(W,user)
// Lock or unlock the access panel.
@@ -24,6 +24,7 @@
/obj/item/clothing/shoes/magboots/rig
name = "boots"
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
@@ -69,3 +70,38 @@
return 1
return 0
//Rig pieces for non-spacesuit based rigs
/obj/item/clothing/head/lightrig
name = "mask"
body_parts_covered = HEAD|FACE|EYES
heat_protection = HEAD|FACE|EYES
cold_protection = HEAD|FACE|EYES
flags = THICKMATERIAL|AIRTIGHT
/obj/item/clothing/suit/lightrig
name = "suit"
allowed = list(/obj/item/device/flashlight)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
flags = THICKMATERIAL
/obj/item/clothing/shoes/lightrig
name = "boots"
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
gender = PLURAL
/obj/item/clothing/gloves/lightrig
name = "gloves"
flags = THICKMATERIAL
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
gender = PLURAL
@@ -33,22 +33,43 @@
/obj/item/weapon/rig/light/hacker
name = "cybersuit control module"
suit_type = "cyber"
desc = "An advanced powered armour suit with many cyberwarfare enhancements."
desc = "An advanced powered armour suit with many cyberwarfare enhancements. Comes with built-in insulated gloves for safely tampering with electronics."
icon_state = "hacker_rig"
req_access = list(access_syndicate)
helm_type = /obj/item/clothing/head/helmet/space/rig/mask
airtight = 0
seal_delay = 5 //not being vaccum-proof has an upside I guess
helm_type = /obj/item/clothing/head/lightrig/hacker
chest_type = /obj/item/clothing/suit/lightrig/hacker
glove_type = /obj/item/clothing/gloves/lightrig/hacker
boot_type = /obj/item/clothing/shoes/lightrig/hacker
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack
/obj/item/rig_module/datajack,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/voice,
/obj/item/rig_module/vision,
)
/obj/item/clothing/head/helmet/space/rig/mask
name = "mask"
flags = THICKMATERIAL
//The cybersuit is not space-proof. It does however, have good siemens_coefficient values
/obj/item/clothing/head/lightrig/hacker
name = "HUD"
siemens_coefficient = 0.4
flags = 0
/obj/item/clothing/suit/lightrig/hacker
siemens_coefficient = 0.4
/obj/item/clothing/shoes/lightrig/hacker
siemens_coefficient = 0.4
flags = NOSLIP //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
/obj/item/clothing/gloves/lightrig/hacker
siemens_coefficient = 0
/obj/item/weapon/rig/light/ninja
name = "ominous suit control module"
@@ -92,7 +113,7 @@
name = "stealth suit control module"
suit_type = "stealth"
desc = "A highly advanced and expensive suit designed for covert operations."
icon_state = "ninja_rig"
icon_state = "stealth_rig"
req_access = list(access_syndicate)
+1 -1
View File
@@ -107,7 +107,7 @@
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive
name = "Reactive Teleport Armor"
desc = "Someone seperated our Research Director from his own head!"
desc = "Someone separated our Research Director from their own head!"
var/active = 0.0
icon_state = "reactiveoff"
item_state = "reactiveoff"
@@ -142,7 +142,7 @@
/obj/item/clothing/accessory/medal/conduct
name = "distinguished conduct medal"
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of their crew."
/obj/item/clothing/accessory/medal/bronze_heart
name = "bronze heart medal"
+10 -5
View File
@@ -49,18 +49,23 @@
item.icon = CUSTOM_ITEM_OBJ
item.icon_state = item_icon
return
else
else
if(inherit_inhands)
apply_inherit_inhands(item)
else
item.item_state_slots = null
item.item_icons = null
item.icon = CUSTOM_ITEM_OBJ
item.icon_state = item_icon
item.item_state = null
item.icon_override = CUSTOM_ITEM_MOB
var/obj/item/clothing/under/U = item
if(istype(U))
U.worn_state = U.icon_state
U.update_rolldown_status()
// Kits are dumb so this is going to have to be hardcoded/snowflake.
if(istype(item, /obj/item/device/kit))
var/obj/item/device/kit/K = item
@@ -81,9 +86,9 @@
/datum/custom_item/proc/apply_inherit_inhands(var/obj/item/item)
var/list/new_item_icons = list()
var/list/new_item_state_slots = list()
var/list/available_states = icon_states(CUSTOM_ITEM_MOB)
//If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots
//Then use icon_override to make every other slot use the custom sprites by default.
//This has to be done before we touch any of item's vars
@@ -93,7 +98,7 @@
if(!("[item_icon]_r" in available_states))
new_item_state_slots[slot_r_hand_str] = get_state(item, slot_r_hand_str, "_r")
new_item_icons[slot_r_hand_str] = get_icon(item, slot_r_hand_str, 'icons/mob/items/righthand.dmi')
item.item_state_slots = new_item_state_slots
item.item_icons = new_item_icons
+190 -16
View File
@@ -14,33 +14,207 @@
var/track_blood = 0
/obj/item/weapon/reagent_containers/glass/rag
name = "damp rag"
name = "rag"
desc = "For cleaning up messes, you suppose."
w_class = 1
icon = 'icons/obj/toy.dmi'
icon_state = "rag"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(5)
volume = 5
volume = 10
can_be_placed_into = null
flags = OPENCONTAINER | NOBLUDGEON
var/on_fire = 0
var/burn_time = 20 //if the rag burns for too long it turns to ashes
/obj/item/weapon/reagent_containers/glass/rag/New()
..()
update_name()
/obj/item/weapon/reagent_containers/glass/rag/Destroy()
processing_objects -= src //so we don't continue turning to ash while gc'd
..()
/obj/item/weapon/reagent_containers/glass/rag/attack_self(mob/user as mob)
return
if(on_fire)
user.visible_message("<span class='warning'>\The [user] stamps out [src].</span>", "<span class='warning'>You stamp out [src].</span>")
user.unEquip(src)
extinguish()
else
remove_contents(user)
/obj/item/weapon/reagent_containers/glass/rag/attackby(obj/item/W, mob/user)
if(!on_fire && istype(W, /obj/item/weapon/flame))
var/obj/item/weapon/flame/F = W
if(F.lit)
ignite()
if(on_fire)
visible_message("<span class='warning'>\The [user] lights [src] with [W].</span>")
else
user << "<span class='warning'>You manage to singe [src], but fail to light it.</span>"
. = ..()
update_name()
/obj/item/weapon/reagent_containers/glass/rag/proc/update_name()
if(on_fire)
name = "burning [initial(name)]"
else if(reagents.total_volume)
name = "damp [initial(name)]"
else
name = "dry [initial(name)]"
/obj/item/weapon/reagent_containers/glass/rag/update_icon()
if(on_fire)
icon_state = "raglit"
else
icon_state = "rag"
var/obj/item/weapon/reagent_containers/food/drinks/bottle/B = loc
if(istype(B))
B.update_icon()
/obj/item/weapon/reagent_containers/glass/rag/proc/remove_contents(mob/user, atom/trans_dest = null)
if(!trans_dest && !user.loc)
return
if(reagents.total_volume)
var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]"
user.visible_message("<span class='danger'>\The [user] begins to wring out [src] over [target_text].</span>", "<span class='notice'>You begin to wring out [src] over [target_text].</span>")
if(do_after(user, reagents.total_volume*5)) //50 for a fully soaked rag
if(trans_dest)
reagents.trans_to(trans_dest, reagents.total_volume)
else
reagents.splash(user.loc, reagents.total_volume)
user.visible_message("<span class='danger'>\The [user] wrings out [src] over [target_text].</span>", "<span class='notice'>You finish to wringing out [src].</span>")
update_name()
/obj/item/weapon/reagent_containers/glass/rag/proc/wipe_down(atom/A, mob/user)
if(!reagents.total_volume)
user << "<span class='warning'>The [initial(name)] is dry!</span>"
else
user.visible_message("\The [user] starts to wipe down [A] with [src]!")
reagents.splash(A, 1) //get a small amount of liquid on the thing we're wiping.
update_name()
if(do_after(user,30))
user.visible_message("\The [user] finishes wiping off the [A]!")
A.clean_blood()
/obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
if(ismob(target) && target.reagents && reagents.total_volume)
user.visible_message("\red \The [target] has been smothered with \the [src] by \the [user]!", "\red You smother \the [target] with \the [src]!", "You hear some struggling and muffled cries of surprise")
reagents.trans_to_mob(target, reagents.total_volume, CHEM_INGEST)
if(isliving(target))
var/mob/living/M = target
if(on_fire)
user.visible_message("<span class='danger'>\The [user] hits [target] with [src]!</span>",)
user.do_attack_animation(src)
M.IgniteMob()
else if(reagents.total_volume)
if(user.zone_sel.selecting == "mouth")
user.do_attack_animation(src)
user.visible_message(
"<span class='danger'>\The [user] smothers [target] with [src]!</span>",
"<span class='warning'>You smother [target] with [src]!</span>",
"You hear some struggling and muffled cries of surprise"
)
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
update_name()
else
wipe_down(target, user)
return
else
..()
return ..()
/obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity)
if(!proximity) return
if(istype(A) && src in user)
user.visible_message("[user] starts to wipe down [A] with [src]!")
if(do_after(user,30))
user.visible_message("[user] finishes wiping off the [A]!")
A.clean_blood()
return
if(!proximity)
return
if(istype(A, /obj/structure/reagent_dispensers))
if(!reagents.get_free_space())
user << "<span class='warning'>\The [src] is already soaked.</span>"
return
if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume))
user.visible_message("<span class='notice'>\The [user] soaks [src] using [A].</span>", "<span class='notice'>You soak [src] using [A].</span>")
update_name()
return
if(!on_fire && istype(A) && (src in user))
if(A.is_open_container())
remove_contents(user, A)
else if(!ismob(A)) //mobs are handled in attack() - this prevents us from wiping down people while smothering them.
wipe_down(A, user)
return
/obj/item/weapon/reagent_containers/glass/rag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature >= 50 + T0C)
ignite()
if(exposed_temperature >= 900 + T0C)
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
//rag must have a minimum of 2 units welder fuel and at least 80% of the reagents must be welder fuel.
//maybe generalize flammable reagents someday
/obj/item/weapon/reagent_containers/glass/rag/proc/can_ignite()
var/fuel = reagents.get_reagent_amount("fuel")
return (fuel >= 2 && fuel >= reagents.total_volume*0.8)
/obj/item/weapon/reagent_containers/glass/rag/proc/ignite()
if(on_fire)
return
if(!can_ignite())
return
//also copied from matches
if(reagents.get_reagent_amount("phoron")) // the phoron explodes when exposed to fire
visible_message("<span class='danger'>\The [src] conflagrates violently!</span>")
var/datum/effect/effect/system/reagents_explosion/e = new()
e.set_up(round(reagents.get_reagent_amount("phoron") / 2.5, 1), get_turf(src), 0, 0)
e.start()
qdel(src)
return
processing_objects += src
set_light(2, null, "#E38F46")
on_fire = 1
update_name()
update_icon()
/obj/item/weapon/reagent_containers/glass/rag/proc/extinguish()
processing_objects -= src
set_light(0)
on_fire = 0
//rags sitting around with 1 second of burn time left is dumb.
//ensures players always have a few seconds of burn time left when they light their rag
if(burn_time <= 5)
visible_message("<span class='warning'>\The [src] falls apart!</span>")
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
update_name()
update_icon()
/obj/item/weapon/reagent_containers/glass/rag/process()
if(!can_ignite())
visible_message("<span class='warning'>\The [src] burns out.</span>")
extinguish()
//copied from matches
if(isliving(loc))
var/mob/living/M = loc
M.IgniteMob()
var/turf/location = get_turf(src)
if(location)
location.hotspot_expose(700, 5)
if(burn_time <= 0)
processing_objects -= src
new /obj/effect/decal/cleanable/ash(location)
qdel(src)
return
reagents.remove_reagent("fuel", reagents.maximum_volume/25)
update_name()
burn_time--
+1 -1
View File
@@ -42,7 +42,7 @@ var/list/weighted_mundaneevent_locations = list()
return null
/datum/trade_destination/icarus
name = "NMV Icarus"
name = "NDV Icarus"
description = "Corvette assigned to patrol NSS Exodus local space."
distance = 0.1
willing_to_buy = list()
+9
View File
@@ -46,6 +46,15 @@
#define GEAR_EVA 15
/var/list/economic_species_modifier = list(
/datum/species/human = 10,
/datum/species/skrell = 12,
/datum/species/tajaran = 7,
/datum/species/unathi = 7,
/datum/species/vox = 1
)
//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
//Corporation NanoTrasen - Generalised / high tech research and phoron exploitation.
//Corporation Vessel Contracting - Ship and station construction, materials research.
+1 -1
View File
@@ -68,7 +68,7 @@
"NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.",
"All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.",
"[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.",
"Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
"Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.",
"There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
var/law = pick(laws)
+3 -3
View File
@@ -24,11 +24,11 @@
/datum/event/rogue_drone/announce()
var/msg
if(prob(33))
msg = "A combat drone wing operating out of the NMV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
msg = "A combat drone wing operating out of the NDV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution."
else if(prob(50))
msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution."
msg = "Contact has been lost with a combat drone wing operating out of the NDV Icarus. If any are sighted in the area, approach with caution."
else
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution."
msg = "Unidentified hackers have targetted a combat drone wing deployed from the NDV Icarus. If any are sighted in the area, approach with caution."
command_announcement.Announce(msg, "Rogue drone alert")
/datum/event/rogue_drone/end()
+3 -3
View File
@@ -54,7 +54,7 @@
duration = 10*90
start(mob/living/carbon/human/H)
H.emote("me", 1, "has drool running down from his mouth.")
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
finish(mob/living/carbon/human/H)
if(!H.reagents.has_reagent("anti_toxin"))
@@ -68,7 +68,7 @@
duration = 10*30
start(mob/living/carbon/human/H)
H.emote("me", 1, "has drool running down from his mouth.")
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
finish(mob/living/carbon/human/H)
if(!H.reagents.has_reagent("anti_toxin"))
@@ -88,4 +88,4 @@ proc/trigger_side_effect(mob/living/carbon/human/H)
if(!istype(H)) return
H.SetWeakened(0)
S.finish(H)
S.finish(H)
+1 -1
View File
@@ -281,7 +281,7 @@
if(HP.ambience)
linkedholodeck.forced_ambience = HP.ambience
else
linkedholodeck.forced_ambience = initial(linkedholodeck.ambience)
linkedholodeck.forced_ambience = list()
for(var/mob/living/M in mobs_in_area(linkedholodeck))
if(M.mind)
+2 -2
View File
@@ -46,8 +46,8 @@
/obj/structure/holostool
name = "stool"
desc = "Apply butt."
icon = 'icons/obj/objects.dmi'
icon_state = "stool"
icon = 'icons/obj/furniture.dmi'
icon_state = "stool_padded_preview"
anchored = 1.0
pressure_resistance = 15
+5 -4
View File
@@ -690,10 +690,11 @@
else
product = new /obj/item/weapon/reagent_containers/food/snacks/grown(get_turf(user),name)
if(get_trait(TRAIT_PRODUCT_COLOUR))
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
if(istype(product,/obj/item/weapon/reagent_containers/food))
var/obj/item/weapon/reagent_containers/food/food = product
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
if(!istype(product, /mob))
product.color = get_trait(TRAIT_PRODUCT_COLOUR)
if(istype(product,/obj/item/weapon/reagent_containers/food))
var/obj/item/weapon/reagent_containers/food/food = product
food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR)
if(mysterious)
product.name += "?"
+15
View File
@@ -36,6 +36,20 @@
return
else
name = ("bookcase ([newname])")
else if(istype(O,/obj/item/weapon/wrench))
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
user << (anchored ? "<span class='notice'>You unfasten \the [src] from the floor.</span>" : "<span class='notice'>You secure \the [src] to the floor.</span>")
anchored = !anchored
else if(istype(O,/obj/item/weapon/screwdriver))
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
user << "<span class='notice'>You begin dismantling \the [src].</span>"
if(do_after(user,25))
user << "<span class='notice'>You dismantle \the [src].</span>"
new /obj/item/stack/material/wood(get_turf(src), amount = 3)
for(var/obj/item/weapon/book/b in contents)
b.loc = (get_turf(src))
qdel(src)
else
..()
@@ -81,6 +95,7 @@
icon_state = "book-5"
/obj/structure/bookcase/manuals/medical
name = "Medical Manuals bookcase"
+7 -5
View File
@@ -122,6 +122,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
density = 1
var/arcanecheckout = 0
var/screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
var/sortby = "author"
var/buffer_book
var/buffer_mob
var/upload_category = "Fiction"
@@ -149,7 +150,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(src.arcanecheckout)
new /obj/item/weapon/book/tome(src.loc)
user << "<span class='warning'>Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.</span>"
user.visible_message("[user] stares at the blank screen for a few moments, his expression frozen in fear. When he finally awakens from it, he looks a lot older.", 2)
user.visible_message("<span class='notice'>\The [user] stares at the blank screen for a few moments, \his expression frozen in fear. When \he finally awakens from it, \he looks a lot older.</span>", 2)
src.arcanecheckout = 0
if(1)
// Inventory
@@ -195,9 +196,8 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
else
dat += {"<A href='?src=\ref[src];orderbyid=1'>(Order book by SS<sup>13</sup>BN)</A><BR><BR>
<table>
<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td></td></tr>"}
var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library")
<tr><td><A href='?src=\ref[src];sort=author>AUTHOR</A></td><td><A href='?src=\ref[src];sort=title>TITLE</A></td><td><A href='?src=\ref[src];sort=category>CATEGORY</A></td><td></td></tr>"}
var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library ORDER BY [sortby]")
query.Execute()
while(query.NextRow())
@@ -236,7 +236,7 @@ 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
@@ -389,6 +389,8 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(isnum(orderid))
var/nhref = "src=\ref[src];targetid=[orderid]"
spawn() src.Topic(nhref, params2list(nhref), src)
if(href_list["sort"] in list("author", "title", "category"))
sortby = href_list["sort"]
src.add_fingerprint(usr)
src.updateUsrDialog()
return
+9 -9
View File
@@ -51,8 +51,8 @@
/datum/light_source/proc/destroy()
destroyed = 1
force_update()
if(source_atom) source_atom.light_sources -= src
if(top_atom) top_atom.light_sources -= src
if(source_atom && source_atom.light_sources) source_atom.light_sources -= src
if(top_atom && top_atom.light_sources) top_atom.light_sources -= src
/datum/light_source/proc/update(atom/new_top_atom)
if(new_top_atom && new_top_atom != top_atom)
@@ -62,7 +62,7 @@
if(!top_atom.light_sources) top_atom.light_sources = list()
top_atom.light_sources += src
if(!needs_update)
if(!needs_update) //Incase we're already updating either way.
lighting_update_lights += src
needs_update = 1
@@ -130,16 +130,16 @@
#if LIGHTING_FALLOFF == 1 //circular
#define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / light_range)) * (1 / sqrt(swapvar + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range))
#endif
#elif LIGHTING_FALLOFF == 2 //square
#define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / light_range)) * (1 / sqrt(swapvar**2 + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range))
#endif
#endif
@@ -177,6 +177,7 @@
T.affecting_lights += src
effect_turf += T
END_FOR_DVIEW
/datum/light_source/proc/remove_lum()
applied = 0
@@ -201,11 +202,10 @@
var/list/view[0]
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
view += T //Filter out turfs.
END_FOR_DVIEW
//This is the part where we calculate new turfs (if any)
var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added.
for(var/turf/T in new_turfs)
//Big huge copy paste from apply_lum() incoming because screw unreadable defines and screw proc call overhead.
if(T.lighting_overlay)
LUM_FALLOFF(., T, source_turf)
. *= light_power
+18 -15
View File
@@ -7,11 +7,22 @@
var/list/light_sources
/atom/proc/set_light(l_range, l_power, l_color)
if(l_power != null) light_power = l_power
if(l_range != null) light_range = l_range
if(l_color != null) light_color = l_color
. = 0 //make it less costly if nothing's changed
update_light()
if(l_power != null && l_power != light_power)
light_power = l_power
. = 1
if(l_range != null && l_range != light_range)
light_range = l_range
. = 1
if(l_color != null && l_color != light_color)
light_color = l_color
. = 1
if(.) update_light()
/atom/proc/copy_light(atom/A)
set_light(A.light_range, A.light_power, A.light_color)
/atom/proc/update_light()
if(!light_power || !light_range)
@@ -46,21 +57,13 @@
T.reconsider_lights()
return ..()
/atom/movable/Move()
var/turf/old_loc = loc
/atom/Entered(atom/movable/obj, atom/prev_loc)
. = ..()
if(loc != old_loc)
for(var/datum/light_source/L in light_sources)
if(obj && prev_loc != src)
for(var/datum/light_source/L in obj.light_sources)
L.source_atom.update_light()
var/turf/new_loc = loc
if(istype(old_loc) && opacity)
old_loc.reconsider_lights()
if(istype(new_loc) && opacity)
new_loc.reconsider_lights()
/atom/proc/set_opacity(new_opacity)
var/old_opacity = opacity
opacity = new_opacity
@@ -98,3 +98,5 @@
var/turf/T = loc
if(istype(T))
T.lighting_overlay = null
..()
+10
View File
@@ -16,3 +16,13 @@
if(A.lighting_use_dynamic)
var/atom/movable/lighting_overlay/O = PoolOrNew(/atom/movable/lighting_overlay, src)
lighting_overlay = O
/turf/Entered(atom/movable/obj)
. = ..()
if(obj && obj.opacity)
reconsider_lights()
/turf/Exited(atom/movable/obj)
. = ..()
if(obj && obj.opacity)
reconsider_lights()
+6 -5
View File
@@ -28,7 +28,7 @@
recipes += new/datum/stack_recipe_list("office chairs",list( \
new/datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1) \
), 5)
))
recipes += new/datum/stack_recipe_list("comfy chairs", list( \
new/datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1), \
@@ -39,7 +39,7 @@
new/datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \
), 2)
))
recipes += new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1)
@@ -69,7 +69,7 @@
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("emergency shutter", /obj/structure/firedoor_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("multi-tile airlock assembly", /obj/structure/door_assembly/multi_tile, 4, time = 50, one_per_turf = 1, on_floor = 1), \
), 4)
))
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)
@@ -86,7 +86,7 @@
/material/sandstone/generate_recipes()
..()
recipes += new/datum/stack_recipe("pile of dirt", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("planting bed", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1)
/material/plastic/generate_recipes()
..()
@@ -104,6 +104,7 @@
recipes += new/datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0)
recipes += new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1)
/material/cardboard/generate_recipes()
..()
@@ -122,4 +123,4 @@
new/datum/stack_recipe("red folder", /obj/item/weapon/folder/red), \
new/datum/stack_recipe("white folder", /obj/item/weapon/folder/white), \
new/datum/stack_recipe("yellow folder", /obj/item/weapon/folder/yellow), \
), 3)
))
+8 -3
View File
@@ -40,8 +40,13 @@
update_strings()
return 1
/obj/item/stack/material/get_material()
return material
/obj/item/stack/material/proc/update_strings()
// Update from material datum.
singular_name = material.sheet_singular_name
if(amount>1)
name = "[material.use_name] [material.sheet_plural_name]"
desc = "A stack of [material.use_name] [material.sheet_plural_name]."
@@ -188,15 +193,15 @@
/obj/item/stack/material/glass/reinforced
name = "reinforced glass"
icon_state = "sheet-rglass"
default_type = "reinforced glass"
default_type = "rglass"
/obj/item/stack/material/glass/phoronglass
name = "phoron glass"
singular_name = "phoron glass sheet"
icon_state = "sheet-phoronglass"
default_type = "phoron glass"
default_type = "phglass"
/obj/item/stack/material/glass/phoronrglass
name = "reinforced phoron glass"
icon_state = "sheet-phoronrglass"
default_type = "reinforced phoron glass"
default_type = "rphglass"
+1 -1
View File
@@ -34,5 +34,5 @@
/obj/item/stack/material/cyborg/glass/reinforced
icon_state = "sheet-rglass"
default_type = "reinforced glass"
default_type = "rglass"
charge_costs = list(500, 1000)
+29 -10
View File
@@ -27,6 +27,17 @@
// Assoc list containing all material datums indexed by name.
var/list/name_to_material
//Returns the material the object is made of, if applicable.
//Will we ever need to return more than one value here? Or should we just return the "dominant" material.
/obj/proc/get_material()
return null
//mostly for convenience
/obj/proc/get_material_name()
var/material/material = get_material()
if(material)
return material.name
// Builds the datum list above.
/proc/populate_material_list(force_remake=0)
if(name_to_material && !force_remake) return // Already set up!
@@ -44,6 +55,12 @@ var/list/name_to_material
populate_material_list()
return name_to_material[name]
/proc/material_display_name(name)
var/material/material = get_material_by_name(name)
if(material)
return material.display_name
return null
// Material definition and procs follow.
/material
var/name // Unique name for use in indexing the list.
@@ -310,7 +327,7 @@ var/list/name_to_material
icon_colour = "#666666"
/material/steel/holographic
name = "holographic " + DEFAULT_WALL_MATERIAL
name = "holo" + DEFAULT_WALL_MATERIAL
display_name = DEFAULT_WALL_MATERIAL
stack_type = null
shard_type = SHARD_NONE
@@ -342,7 +359,7 @@ var/list/name_to_material
weight = 15
door_icon_base = "stone"
destruction_desc = "shatters"
window_options = list("One Direction", "Full Window")
window_options = list("One Direction" = 1, "Full Window" = 4)
created_window = /obj/structure/window/basic
wire_product = /obj/item/stack/light_w
rod_product = /obj/item/stack/material/glass/reinforced
@@ -400,9 +417,8 @@ var/list/name_to_material
return 1
var/build_path = /obj/structure/windoor_assembly
var/sheets_needed = 4
var/sheets_needed = window_options[choice]
if(choice == "Windoor")
sheets_needed = 5
build_dir = user.dir
else
build_path = created_window
@@ -420,7 +436,8 @@ var/list/name_to_material
return (hardness > 35) //todo
/material/glass/reinforced
name = "reinforced glass"
name = "rglass"
display_name = "reinforced glass"
stack_type = /obj/item/stack/material/glass/reinforced
flags = MATERIAL_BRITTLE
icon_colour = "#00E1FF"
@@ -432,13 +449,14 @@ var/list/name_to_material
weight = 30
stack_origin_tech = "materials=2"
composite_material = list(DEFAULT_WALL_MATERIAL = 1875,"glass" = 3750)
window_options = list("One Direction", "Full Window", "Windoor")
window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 5)
created_window = /obj/structure/window/reinforced
wire_product = null
rod_product = null
/material/glass/phoron
name = "phoron glass"
name = "phglass"
display_name = "phoron glass"
stack_type = /obj/item/stack/material/glass/phoronglass
flags = MATERIAL_BRITTLE
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE+300
@@ -450,7 +468,8 @@ var/list/name_to_material
rod_product = /obj/item/stack/material/glass/phoronrglass
/material/glass/phoron/reinforced
name = "reinforced phoron glass"
name = "rphglass"
display_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
@@ -474,7 +493,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 3)
/material/plastic/holographic
name = "holographic plastic"
name = "holoplastic"
display_name = "plastic"
stack_type = null
shard_type = SHARD_NONE
@@ -551,7 +570,7 @@ var/list/name_to_material
sheet_plural_name = "planks"
/material/wood/holographic
name = "holographic wood"
name = "holowood"
display_name = "wood"
stack_type = null
shard_type = SHARD_NONE
+2 -2
View File
@@ -12,7 +12,7 @@
metaltag = "plasteel"
requires = list(
"platinum" = 1,
"coal" = 2,
"carbon" = 2,
"hematite" = 2
)
product_mod = 0.3
@@ -21,7 +21,7 @@
/datum/alloy/steel
metaltag = DEFAULT_WALL_MATERIAL
requires = list(
"coal" = 1,
"carbon" = 1,
"hematite" = 1
)
product = /obj/item/stack/material/steel
+8 -7
View File
@@ -112,16 +112,17 @@
var/sheets_per_tick = 10
var/list/ores_processing[0]
var/list/ores_stored[0]
var/list/alloy_data[0]
var/static/list/alloy_data
var/active = 0
/obj/machinery/mineral/processing_unit/New()
..()
//TODO: Ore and alloy global storage datum.
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
alloy_data += new alloytype()
// initialize static alloy_data list
if(!alloy_data)
alloy_data = list()
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
alloy_data += new alloytype()
if(!ore_data || !ore_data.len)
for(var/oretype in typesof(/ore)-/ore)
@@ -209,7 +210,7 @@
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
if(can_make%2>0) can_make--
var/material/M = name_to_material[O.compresses_to]
var/material/M = get_material_by_name(O.compresses_to)
if(!istype(M) || !can_make || ores_stored[metal] < 1)
continue
@@ -223,7 +224,7 @@
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
var/material/M = name_to_material[O.smelts_to]
var/material/M = get_material_by_name(O.smelts_to)
if(!istype(M) || !can_make || ores_stored[metal] < 1)
continue
+19 -19
View File
@@ -37,26 +37,26 @@
/obj/machinery/mineral/mint/process()
if ( src.input)
var/obj/item/stack/material/O
O = locate(/obj/item/stack/material, input.loc)
var/obj/item/stack/O
O = locate(/obj/item/stack, input.loc)
if(O)
if (istype(O,/obj/item/stack/material/gold))
amt_gold += 100 * O.get_amount()
qdel(O)
if (istype(O,/obj/item/stack/material/silver))
amt_silver += 100 * O.get_amount()
qdel(O)
if (istype(O,/obj/item/stack/material/diamond))
amt_diamond += 100 * O.get_amount()
qdel(O)
if (istype(O,/obj/item/stack/material/phoron))
amt_phoron += 100 * O.get_amount()
qdel(O)
if (istype(O,/obj/item/stack/material/uranium))
amt_uranium += 100 * O.get_amount()
qdel(O)
if (istype(O,/obj/item/stack/material/steel))
amt_iron += 100 * O.get_amount()
var/processed = 1
switch(O.get_material_name())
if("gold")
amt_gold += 100 * O.get_amount()
if("silver")
amt_silver += 100 * O.get_amount()
if("diamond")
amt_diamond += 100 * O.get_amount()
if("phoron")
amt_phoron += 100 * O.get_amount()
if("uranium")
amt_uranium += 100 * O.get_amount()
if(DEFAULT_WALL_MATERIAL)
amt_iron += 100 * O.get_amount()
else
processed = 0
if(processed)
qdel(O)
/obj/machinery/mineral/mint/attack_hand(user as mob)
+27 -1
View File
@@ -77,10 +77,36 @@ note dizziness decrements automatically in the mob's Life() proc.
pixel_y = old_y
//handles up-down floaty effect in space
//handles up-down floaty effect in space and zero-gravity
/mob/var/is_floating = 0
/mob/var/floatiness = 0
/mob/proc/update_floating(var/dense_object=0)
if(anchored||buckled)
make_floating(0)
return
var/turf/turf = get_turf(src)
if(!istype(turf,/turf/space))
var/area/A = turf.loc
if(istype(A) && A.has_gravity)
make_floating(0)
return
else if (Check_Shoegrip())
make_floating(0)
return
else
make_floating(1)
return
if(dense_object && Check_Shoegrip())
make_floating(0)
return
make_floating(1)
return
/mob/proc/make_floating(var/n)
floatiness = n
+54 -15
View File
@@ -188,8 +188,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Stat()
..()
statpanel("Status")
if (client.statpanel == "Status")
if(statpanel("Status"))
stat(null, "Station Time: [worldtime2text()]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
@@ -319,16 +318,56 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(following && following == target)
return
following = target
src << "\blue Now following [target]"
spawn(0)
while(target && following == target && client)
var/turf/T = get_turf(target)
if(!T)
break
// To stop the ghost flickering.
if(loc != T)
loc = T
sleep(15)
src << "<span class='notice'>Now following [target]</span>"
if(ismob(target))
loc = get_turf(target)
var/mob/M = target
M.following_mobs += src
else
spawn(0)
while(target && following == target && client)
var/turf/T = get_turf(target)
if(!T)
break
// To stop the ghost flickering.
if(loc != T)
loc = T
sleep(15)
/mob/proc/update_following()
. = get_turf(src)
for(var/mob/dead/observer/M in following_mobs)
if(M.following != src)
following_mobs -= M
else
if(M.loc != .)
M.loc = .
/mob
var/list/following_mobs = list()
/mob/Destroy()
for(var/mob/dead/observer/M in following_mobs)
M.following = null
following_mobs = null
return ..()
/mob/dead/observer/Destroy()
if(ismob(following))
var/mob/M = following
M.following_mobs -= src
following = null
return ..()
/mob/Move()
. = ..()
if(.)
update_following()
/mob/Life()
// to catch teleports etc which directly set loc
update_following()
return ..()
/mob/proc/check_holy(var/turf/T)
return 0
@@ -560,13 +599,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(src.invisibility != 0)
user.visible_message( \
"<span class='warning'>[user] drags ghost, [src], to our plane of reality!</span>", \
"<span class='warning'>\The [user] drags ghost, [src], to our plane of reality!</span>", \
"<span class='warning'>You drag [src] to our plane of reality!</span>" \
)
toggle_visibility(1)
else
user.visible_message ( \
"<span class='warning'>[user] just tried to smash his book into that ghost! It's not very effective.</span>", \
"<span class='warning'>\The [user] just tried to smash \his book into that ghost! It's not very effective.</span>", \
"<span class='warning'>You get the feeling that the ghost can't become any more visible.</span>" \
)
@@ -634,7 +673,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/updateghostsight()
if (!seedarkness)
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
see_invisible = SEE_INVISIBLE_NOLIGHTING
else
see_invisible = SEE_INVISIBLE_OBSERVER
if (!ghostvision)
+22 -13
View File
@@ -27,23 +27,37 @@
// The AI's "eye". Described on the top of the page.
/mob/living/silicon/ai
eyeobj = new /mob/eye/aiEye()
var/obj/machinery/hologram/holopad/holo = null
/mob/living/silicon/ai/proc/destroy_eyeobj(var/atom/new_eye)
if(!eyeobj) return
if(!new_eye)
new_eye = src
eyeobj.owner = null
qdel(eyeobj) // No AI, no Eye
eyeobj = null
if(client)
client.eye = new_eye
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
if(eyeobj) destroy_eyeobj()
if(!newloc) newloc = src.loc
eyeobj = PoolOrNew(/mob/eye/aiEye, newloc)
eyeobj.owner = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
if(client) client.eye = eyeobj
SetName(src.name)
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
/mob/living/silicon/ai/New()
..()
eyeobj.owner = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
create_eyeobj()
spawn(5)
if(eyeobj)
eyeobj.loc = src.loc
/mob/living/silicon/ai/Destroy()
if(eyeobj)
eyeobj.owner = null
qdel(eyeobj) // No AI, no Eye
eyeobj = null
destroy_eyeobj()
..()
/atom/proc/move_camera_by_click()
@@ -53,23 +67,18 @@
AI.eyeobj.setLoc(src)
// Return to the Core.
/mob/living/silicon/ai/proc/core()
set category = "AI Commands"
set name = "AI Core"
view_core()
/mob/living/silicon/ai/proc/view_core()
camera = null
unset_machine()
if(!src.eyeobj)
src << "ERROR: Eyeobj not found. Creating new eye..."
src.eyeobj = new(src.loc)
src.eyeobj.owner = src
src.SetName(src.name)
return
if(client && client.eye)
client.eye = src
@@ -29,7 +29,6 @@
..()
/obj/structure/New()
..()
updateVisibility(src)
// EFFECTS
+56
View File
@@ -0,0 +1,56 @@
/var/list/gender_datums = list()
/hook/startup/proc/populate_gender_datum_list()
for(var/type in typesof(/datum/gender))
var/datum/gender/G = new type
gender_datums[G.key] = G
return 1
/datum/gender
var/key = "plural"
var/He = "They"
var/he = "they"
var/His = "Their"
var/his = "their"
var/him = "them"
var/has = "have"
var/is = "are"
var/does = "do"
/datum/gender/male
key = "male"
He = "He"
he = "he"
His = "His"
his = "his"
him = "him"
has = "has"
is = "is"
does = "does"
/datum/gender/female
key = "female"
He = "She"
he = "she"
His = "Her"
his = "her"
him = "her"
has = "has"
is = "is"
does = "does"
/datum/gender/neuter
key = "neuter"
He = "It"
he = "it"
His = "Its"
his = "its"
him = "it"
has = "has"
is = "is"
does = "does"
+35 -68
View File
@@ -5,10 +5,12 @@
icon = 'icons/obj/objects.dmi'
slot_flags = SLOT_HEAD
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
origin_tech = null
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_holder.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_holder.dmi',
)
pixel_y = 8
/obj/item/weapon/holder/New()
..()
@@ -31,6 +33,38 @@
qdel(src)
/obj/item/weapon/holder/proc/sync(var/mob/living/M)
dir = 2
overlays.Cut()
icon = M.icon
icon_state = M.icon_state
color = M.color
name = M.name
desc = M.desc
overlays |= M.overlays
var/mob/living/carbon/human/H = loc
if(istype(H))
if(H.l_hand == src)
H.update_inv_l_hand()
else if(H.r_hand == src)
H.update_inv_r_hand()
else
H.regenerate_icons()
//Mob specific holders.
/obj/item/weapon/holder/diona
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
slot_flags = SLOT_HEAD | SLOT_OCLOTHING
/obj/item/weapon/holder/drone
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5)
/obj/item/weapon/holder/mouse
w_class = 1
/obj/item/weapon/holder/borer
origin_tech = list(TECH_BIO = 6)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
@@ -50,72 +84,5 @@
grabber << "You scoop up [src]."
src << "[grabber] scoops you up."
grabber.status_flags |= PASSEMOTES
H.sync(src)
return H
//Mob specific holders.
/obj/item/weapon/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon_state = "nymph"
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
slot_flags = SLOT_HEAD | SLOT_OCLOTHING
/obj/item/weapon/holder/drone
name = "maintenance drone"
desc = "It's a small maintenance robot."
icon_state = "drone"
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5)
/obj/item/weapon/holder/cat
name = "cat"
desc = "It's a cat. Meow."
icon_state = "cat"
origin_tech = null
/obj/item/weapon/holder/mouse
name = "mouse"
desc = "It's a small rodent."
icon_state = "mouse_gray"
origin_tech = null
w_class = 1
/obj/item/weapon/holder/mouse/gray
icon_state = "mouse_gray"
/obj/item/weapon/holder/mouse/white
icon_state = "mouse_white"
/obj/item/weapon/holder/mouse/brown
icon_state = "mouse_brown"
/obj/item/weapon/holder/borer
name = "cortical borer"
desc = "It's a slimy brain slug. Gross."
icon_state = "borer"
origin_tech = list(TECH_BIO = 6)
/obj/item/weapon/holder/monkey
name = "monkey"
desc = "It's a monkey. Ook."
icon_state = "monkey"
/obj/item/weapon/holder/monkey/farwa
name = "farwa"
desc = "It's a farwa."
icon_state = "farwa"
/obj/item/weapon/holder/monkey/stok
name = "stok"
desc = "It's a stok. stok."
icon_state = "stok"
/obj/item/weapon/holder/monkey/neaera
name = "neaera"
desc = "It's a neaera."
icon_state = "neara"
/obj/item/weapon/holder/pai
name = "pAI"
desc = "It's a little robot."
icon_state = "pai"
+1 -1
View File
@@ -25,7 +25,7 @@
speech_verb = "says"
whisper_verb = "whispers"
key = "0"
flags = RESTRICTED
flags = RESTRICTED | COMMON_VERBS
syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah")
//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these.
+1 -1
View File
@@ -73,7 +73,7 @@
whisper_verb = "whispers"
colour = "solcom"
key = "1"
flags = RESTRICTED
flags = WHITELISTED
//syllables are at the bottom of the file
+5 -2
View File
@@ -16,6 +16,7 @@
var/obj/access_scanner = null
var/list/req_access = list()
var/list/req_one_access = list()
/mob/living/bot/New()
..()
@@ -26,14 +27,16 @@
access_scanner = new /obj(src)
access_scanner.req_access = req_access.Copy()
access_scanner.req_one_access = req_one_access.Copy()
/mob/living/bot/Life()
..()
if(health <= 0)
death()
return
weakened = 0
stunned = 0
paralysis = 0
if(health <= 0)
death()
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
+10 -9
View File
@@ -251,15 +251,16 @@
target = null
repairing = 0
update_icons()
else if(istype(A, /obj/item/stack/material/steel) && amount + 3 < maxAmount)
var/obj/item/stack/material/steel/M = A
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
repairing = 1
update_icons()
if(do_after(50))
if(M)
M.use(1)
addTiles(4)
else if(istype(A, /obj/item/stack/material) && amount + 4 <= maxAmount)
var/obj/item/stack/material/M = A
if(M.get_material_name() == DEFAULT_WALL_MATERIAL)
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
repairing = 1
update_icons()
if(do_after(50))
if(M)
M.use(1)
addTiles(4)
/mob/living/bot/floorbot/explode()
turn_off()
+1 -1
View File
@@ -4,7 +4,7 @@
icon_state = "secbot0"
maxHealth = 50
health = 50
req_access = list(access_security, access_forensics_lockers)
req_one_access = list(access_security, access_forensics_lockers)
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
var/mob/target
@@ -9,6 +9,7 @@
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
var/obj/item/hat
/mob/living/carbon/alien/diona/New()
@@ -32,3 +33,10 @@
/mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
return 1
/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat)
if(hat)
return
hat = new_hat
new_hat.loc = src
update_icons()
@@ -6,5 +6,22 @@
return
get_scooped(H)
return
else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
hat.loc = get_turf(src)
H.put_in_hands(hat)
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")
hat = null
update_icons()
else
return ..()
/mob/living/carbon/alien/diona/attackby(var/obj/item/weapon/W, var/mob/user)
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
if(hat)
user << "<span class='warning'>\The [src] is already wearing \the [hat].</span>"
return
user.unEquip(W)
wear_hat(W)
user.visible_message("<span class='notice'>\The [user] puts \the [W] on \the [src].</span>")
return
return ..()
@@ -6,3 +6,7 @@
icon_state = "[initial(icon_state)]_sleep"
else
icon_state = "[initial(icon_state)]"
overlays.Cut()
if(hat)
overlays |= get_hat_icon(hat, 0, -8)
+2 -2
View File
@@ -372,8 +372,8 @@
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
var/temp_inc = max(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), 0)
bodytemperature = min(bodytemperature + temp_inc, exposed_temperature)
var/temp_inc = max(min(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), exposed_temperature - bodytemperature), 0)
bodytemperature += temp_inc
/mob/living/carbon/can_use_hands()
if(handcuffed)
@@ -154,14 +154,14 @@
return valid_species
/mob/living/carbon/human/proc/generate_valid_hairstyles()
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
var/list/valid_hairstyles = new()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(gender == MALE && S.gender == FEMALE)
if(check_gender && gender == MALE && S.gender == FEMALE)
continue
if(gender == FEMALE && S.gender == MALE)
if(check_gender && gender == FEMALE && S.gender == MALE)
continue
if(!(species.name in S.species_allowed))
continue
@@ -185,11 +185,7 @@
return valid_facial_hairstyles
/proc/q()
var/mob/living/carbon/human/H = usr
H.change_appearance(APPEARANCE_ALL)
/mob/living/carbon/human/proc/force_update_limbs()
for(var/obj/item/organ/external/O in organs)
O.sync_colour_to_human(src)
update_body(0)
update_body(0)
@@ -101,7 +101,7 @@
if ("choke")
if(miming)
message = "clutches his throat desperately!"
message = "clutches [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] throat desperately!"
m_type = 1
else
if (!muzzled)
+76 -103
View File
@@ -24,46 +24,18 @@
if(wear_mask)
skipface |= wear_mask.flags_inv & HIDEFACE
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
var/t_He = "They" //capitalised for use at the start of each line.
var/t_he = "they"
var/t_his = "their"
var/t_him = "them"
var/t_has = "have"
var/t_is = "are"
var/t_does = "do"
var/msg = "<span class='info'>*---------*\nThis is "
//big suits/masks/helmets make it hard to tell their gender
if(!skipjumpsuit || !skipface)
var/datum/gender/T = gender_datums[gender]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
else
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
switch(gender)
if(MALE)
t_He = "He"
t_he = "he"
t_his = "his"
t_him = "him"
t_has = "has"
t_is = "is"
t_does = "does"
if(FEMALE)
t_He = "She"
t_he = "she"
t_his = "her"
t_him = "her"
t_has = "has"
t_is = "is"
t_does = "does"
if(NEUTER)
t_He = "It"
t_he = "it"
t_his = "its"
t_him = "it"
t_has = "has"
t_is = "is"
t_does = "does"
if(!T)
// Just in case someone VVs the gender to something strange. It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message.
CRASH("Gender datum was null; key was '[(skipjumpsuit && skipface) ? PLURAL : gender]'")
msg += "<EM>[src.name]</EM>"
if(species.name != "Human")
@@ -80,111 +52,111 @@
tie_msg += ". Attached to it is [lowertext(english_list(U.accessories))]"
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
//head
if(head)
if(head.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [t_his] head!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n"
msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.\n"
//suit/armour
if(wear_suit)
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n"
msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit].\n"
//suit/armour storage
if(s_store && !skipsuitstorage)
if(s_store.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n"
msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [t_his] back.</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [T.his] back.</span>\n"
else
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.\n"
//left hand
if(l_hand)
if(l_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [t_his] left hand!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.\n"
//right hand
if(r_hand)
if(r_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [t_his] right hand!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.\n"
//gloves
if(gloves && !skipgloves)
if(gloves.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [t_his] hands!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span>\n"
else
msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n"
msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.\n"
else if(blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [(hand_blood_color != "#030303") ? "blood" : "oil"]-stained hands!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] [(hand_blood_color != "#030303") ? "blood" : "oil"]-stained hands!</span>\n"
//handcuffed?
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] restrained with cable!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] restrained with cable!</span>\n"
else
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] handcuffed!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] handcuffed!</span>\n"
//buckled
if(buckled)
msg += "<span class='warning'>[t_He] [t_is] \icon[buckled] buckled to [buckled]!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] \icon[buckled] buckled to [buckled]!</span>\n"
//belt
if(belt)
if(belt.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [t_his] waist!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span>\n"
else
msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n"
msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.\n"
//shoes
if(shoes && !skipshoes)
if(shoes.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [t_his] feet!</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n"
msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.\n"
else if(feet_blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [(feet_blood_color != "#030303") ? "blood" : "oil"]-stained feet!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] [(feet_blood_color != "#030303") ? "blood" : "oil"]-stained feet!</span>\n"
//mask
if(wear_mask && !skipmask)
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [t_his] face!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [T.his] face!</span>\n"
else
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] on [T.his] face.\n"
//eyes
if(glasses && !skipeyes)
if(glasses.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [t_his] eyes!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span>\n"
else
msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n"
msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.\n"
//left ear
if(l_ear && !skipears)
msg += "[t_He] [t_has] \icon[l_ear] \a [l_ear] on [t_his] left ear.\n"
msg += "[T.He] [T.has] \icon[l_ear] \a [l_ear] on [T.his] left ear.\n"
//right ear
if(r_ear && !skipears)
msg += "[t_He] [t_has] \icon[r_ear] \a [r_ear] on [t_his] right ear.\n"
msg += "[T.He] [T.has] \icon[r_ear] \a [r_ear] on [T.his] right ear.\n"
//ID
if(wear_id)
@@ -196,70 +168,71 @@
var/obj/item/weapon/card/id/idcard = wear_id
id = idcard.registered_name
if(id && (id != real_name) && (get_dist(src, usr) <= 1) && prob(10))
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
else*/
msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
msg += "[T.He] [T.is] wearing \icon[wear_id] \a [wear_id].\n"
//Jitters
if(is_jittery)
if(jitteriness >= 300)
msg += "<span class='warning'><B>[t_He] [t_is] convulsing violently!</B></span>\n"
msg += "<span class='warning'><B>[T.He] [T.is] convulsing violently!</B></span>\n"
else if(jitteriness >= 200)
msg += "<span class='warning'>[t_He] [t_is] extremely jittery.</span>\n"
msg += "<span class='warning'>[T.He] [T.is] extremely jittery.</span>\n"
else if(jitteriness >= 100)
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
msg += "<span class='warning'>[T.He] [T.is] twitching ever so slightly.</span>\n"
//splints
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
var/obj/item/organ/external/o = get_organ(organ)
if(o && o.status & ORGAN_SPLINTED)
msg += "<span class='warning'>[t_He] [t_has] a splint on [t_his] [o.name]!</span>\n"
msg += "<span class='warning'>[T.He] [T.has] a splint on [T.his] [o.name]!</span>\n"
if(suiciding)
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
msg += "<span class='warning'>[T.He] appears to have commited suicide... there is no hope of recovery.</span>\n"
if(mSmallsize in mutations)
msg += "[t_He] [t_is] small halfling!\n"
msg += "[T.He] [T.is] small halfling!\n"
var/distance = get_dist(usr,src)
if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
distance = 1
if (src.stat)
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
msg += "<span class='warning'>[T.He] [T.is]n't responding to anything around [T.him] and seems to be asleep.</span>\n"
if((stat == 2 || src.losebreath) && distance <= 3)
msg += "<span class='warning'>[t_He] [t_does] not appear to be breathing.</span>\n"
msg += "<span class='warning'>[T.He] [T.does] not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
usr << "<span class='deadsay'>[t_He] [t_has] no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
usr << "<span class='deadsay'>[T.He] [T.has] no pulse[src.client ? "" : " and [T.his] soul has departed"]...</span>"
else
usr << "<span class='deadsay'>[t_He] [t_has] a pulse!</span>"
usr << "<span class='deadsay'>[T.He] [T.has] a pulse!</span>"
if(fire_stacks)
msg += "[t_He] [t_is] covered in some liquid.\n"
msg += "[T.He] [T.is] covered in some liquid.\n"
if(on_fire)
msg += "<span class='warning'>[t_He] [t_is] on fire!.</span>\n"
msg += "<span class='warning'>[T.He] [T.is] on fire!.</span>\n"
msg += "<span class='warning'>"
if(nutrition < 100)
msg += "[t_He] [t_is] severely malnourished.\n"
msg += "[T.He] [T.is] severely malnourished.\n"
else if(nutrition >= 500)
/*if(usr.nutrition < 100)
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
msg += "[T.He] [T.is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else*/
msg += "[t_He] [t_is] quite chubby.\n"
msg += "[T.He] [T.is] quite chubby.\n"
msg += "</span>"
if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
msg += "[T.He] [T.has] a stupid expression on [T.his] face.\n"
if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD)
if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] fast asleep. It doesn't look like [t_he] [t_is] waking up anytime soon.</span>\n"
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span>\n"
else if(!client)
msg += "<span class='deadsay'>[t_He] [t_is] [species.show_ssd].</span>\n"
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd].</span>\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
@@ -273,9 +246,9 @@
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] is missing [t_his] [organ_descriptor].</b></span>\n"
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [organ_descriptor].</b></span>\n"
else if(E.is_stump())
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] has a stump where [t_his] [organ_descriptor] should be.</b></span>\n"
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.has] a stump where [T.his] [organ_descriptor] should be.</b></span>\n"
else
is_destroyed["organ_descriptor"] = 0
continue
@@ -284,24 +257,24 @@
if(temp)
if(temp.status & ORGAN_DESTROYED)
is_destroyed["[temp.name]"] = 1
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[t_He] [t_is] missing [t_his] [temp.name].</b></span>\n"
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [temp.name].</b></span>\n"
continue
if(temp.status & ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]!</span>\n"
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a robot [temp.name]!</span>\n"
continue
else
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
else if(temp.wounds.len > 0 || temp.open)
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has [temp.get_wounds_desc()] on [t_his] [temp.name].</span><br>"
wound_flavor_text["[temp.name]"] = "<span class='warning'>[T.He] [T.has] [temp.get_wounds_desc()] on [T.his] [temp.name].</span><br>"
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.name]"] = "<span class='danger'>[capitalize(t_his)] [temp.name] is bleeding!</span><br>"
is_bleeding["[temp.name]"] = "<span class='danger'>[T.His] [temp.name] is bleeding!</span><br>"
else
wound_flavor_text["[temp.name]"] = ""
if(temp.dislocated == 2)
wound_flavor_text["[temp.name]"] += "<span class='warning'>[capitalize(t_his)] [temp.joint] is dislocated!</span><br>"
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.joint] is dislocated!</span><br>"
if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
wound_flavor_text["[temp.name]"] += "<span class='warning'>[capitalize(t_his)] [temp.name] is dented and swollen!</span><br>"
wound_flavor_text["[temp.name]"] += "<span class='warning'>[T.His] [temp.name] is dented and swollen!</span><br>"
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
@@ -318,7 +291,7 @@
if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas)))))
msg += wound_flavor_text["head"]
else if(is_bleeding["head"])
msg += "<span class='warning'>[src] [t_has] blood running down [t_his] face!</span>\n"
msg += "<span class='warning'>[src] [T.has] blood running down [T.his] face!</span>\n"
if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
msg += wound_flavor_text["upper body"]
@@ -369,11 +342,11 @@
display_shoes = 1
if(display_chest)
msg += "<span class='danger'>[src] [t_has] blood soaking through from under [t_his] clothing!</span>\n"
msg += "<span class='danger'>[src] [T.has] blood soaking through from under [T.his] clothing!</span>\n"
if(display_shoes)
msg += "<span class='danger'>[src] [t_has] blood running from [t_his] shoes!</span>\n"
msg += "<span class='danger'>[src] [T.has] blood running from [T.his] shoes!</span>\n"
if(display_gloves)
msg += "<span class='danger'>[src] [t_has] blood running from under [t_his] gloves!</span>\n"
msg += "<span class='danger'>[src] [T.has] blood running from under [T.his] gloves!</span>\n"
*/
for(var/limb in wound_flavor_text)
@@ -382,9 +355,9 @@
for(var/limb in is_bleeding)
msg += is_bleeding[limb]
for(var/implant in get_visible_implants(0))
msg += "<span class='danger'>[src] [t_has] \a [implant] sticking out of [t_his] flesh!</span>\n"
msg += "<span class='danger'>[src] [T.has] \a [implant] sticking out of [T.his] flesh!</span>\n"
if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n"
msg += "[T.He] [T.is] repulsively uncanny!\n"
if(hasHUD(usr,"security"))
var/perpname = "wot"
@@ -438,7 +411,7 @@
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\n[t_He] [t_is] [pose]"
msg += "\n[T.He] [T.is] [pose]"
user << msg
+33 -21
View File
@@ -54,16 +54,13 @@
/mob/living/carbon/human/Stat()
..()
statpanel("Status")
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
stat(null, eta_status)
if (client.statpanel == "Status")
if(statpanel("Status"))
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
stat(null, eta_status)
if (internal)
if (!internal.air_contents)
@@ -210,6 +207,10 @@
/mob/living/carbon/human/show_inv(mob/user as mob)
// TODO : Change to incapacitated() on merge.
if(user.stat || user.lying || user.resting || user.buckled)
return
var/obj/item/clothing/under/suit = null
if (istype(w_uniform, /obj/item/clothing/under))
suit = w_uniform
@@ -723,7 +724,7 @@
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)
visible_message("\red [src] begins playing his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
visible_message("\red \The [src] begins playing \his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
playsound(loc, song, 50, 1, -1)
xylophone = 1
@@ -1022,23 +1023,29 @@
return(visible_implants)
/mob/living/carbon/human/embedded_needs_process()
for(var/obj/item/organ/external/organ in src.organs)
for(var/obj/item/O in organ.implants)
if(!istype(O, /obj/item/weapon/implant)) //implant type items do not cause embedding effects, see handle_embedded_objects()
return 1
return 0
/mob/living/carbon/human/proc/handle_embedded_objects()
for(var/obj/item/organ/external/organ in src.organs)
if(organ.status & ORGAN_SPLINTED) //Splints prevent movement.
continue
for(var/obj/item/weapon/O in organ.implants)
for(var/obj/item/O in organ.implants)
if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad.
// All kinds of embedded objects cause bleeding.
var/msg = null
switch(rand(1,3))
if(1)
msg ="<span class='warning'>A spike of pain jolts your [organ.name] as you bump [O] inside.</span>"
if(2)
msg ="<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>"
if(3)
msg ="<span class='warning'>[O] in your [organ.name] twists painfully as you move.</span>"
src << msg
if(species.flags & NO_PAIN)
src << "<span class='warning'>You feel [O] moving inside your [organ.name].</span>"
else
var/msg = pick( \
"<span class='warning'>A spike of pain jolts your [organ.name] as you bump [O] inside.</span>", \
"<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>", \
"<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>")
src << msg
organ.take_damage(rand(1,3), 0, 0)
if(!(organ.status & ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //There is no blood in protheses.
@@ -1361,3 +1368,8 @@
..()
if(update_hud)
handle_regular_hud_updates()
/mob/living/carbon/human/Check_Shoegrip()
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //magboots + dense_object = no floating
return 1
return 0
@@ -1,3 +1,9 @@
/mob/living/carbon/human/proc/get_unarmed_attack(var/mob/living/carbon/human/target, var/hit_zone)
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
if(u_attack.is_usable(src, target, hit_zone))
return u_attack
return null
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
var/mob/living/carbon/human/H = M
@@ -184,18 +190,7 @@
miss_type = 2
// See what attack they use
var/possible_moves = list()
var/datum/unarmed_attack/attack = null
for(var/part in list("l_hand","r_hand","l_foot","r_foot","head"))
var/obj/item/organ/external/E = H.get_organ(part)
possible_moves |= E.species.unarmed_attacks
for(var/datum/unarmed_attack/u_attack in possible_moves)
if(!u_attack.is_usable(H, src, hit_zone))
continue
else
attack = u_attack
break
var/datum/unarmed_attack/attack = H.get_unarmed_attack(src, hit_zone)
if(!attack)
return 0
@@ -32,7 +32,7 @@
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.take_damage(amount)
sponge.damage = min(max(brainloss, 0),(maxHealth*2))
sponge.damage = min(max(sponge.damage, 0),(maxHealth*2))
brainloss = sponge.damage
else
brainloss = 200
@@ -10,9 +10,11 @@ emp_act
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
if(!organ)
return
def_zone = check_zone(def_zone)
if(!has_organ(def_zone))
return PROJECTILE_FORCE_MISS //if they don't have the organ in question then the projectile just passes by.
var/obj/item/organ/external/organ = get_organ()
//Shields
if(check_shields(P.damage, "the [P.name]"))
@@ -37,7 +39,7 @@ emp_act
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return -1 // complete projectile permutation
return PROJECTILE_CONTINUE // complete projectile permutation
//Shrapnel
if(P.can_embed())
@@ -134,28 +134,29 @@
continue
if(E.is_broken() || E.is_dislocated())
if(E.body_part == HAND_LEFT)
if(!l_hand)
continue
drop_from_inventory(l_hand)
else
if(!r_hand)
continue
drop_from_inventory(r_hand)
switch(E.body_part)
if(HAND_LEFT, ARM_LEFT)
if(!l_hand)
continue
drop_from_inventory(l_hand)
if(HAND_RIGHT, ARM_RIGHT)
if(!r_hand)
continue
drop_from_inventory(r_hand)
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
else if(E.is_malfunctioning())
if(E.body_part == HAND_LEFT)
if(!l_hand)
continue
drop_from_inventory(l_hand)
else
if(!r_hand)
continue
drop_from_inventory(r_hand)
switch(E.body_part)
if(HAND_LEFT, ARM_LEFT)
if(!l_hand)
continue
drop_from_inventory(l_hand)
if(HAND_RIGHT, ARM_RIGHT)
if(!r_hand)
continue
drop_from_inventory(r_hand)
emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!")
@@ -176,4 +177,4 @@
/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)
O.set_dna(dna)
@@ -41,7 +41,7 @@ This saves us from having to call add_fingerprint() any time something is put in
/mob/living/carbon/human/proc/has_organ(name)
var/obj/item/organ/external/O = organs_by_name[name]
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
switch(slot)
+10 -13
View File
@@ -1015,6 +1015,10 @@
// Check everything else.
//Periodically double-check embedded_flag
if(embedded_flag && !(life_tick % 10))
if(!embedded_needs_process())
embedded_flag = 0
//Vision
var/obj/item/organ/vision
if(species.vision_organ)
@@ -1197,7 +1201,7 @@
damageoverlay.overlays += I
if( stat == DEAD )
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF
see_in_dark = 8
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(healths) healths.icon_state = "health7" //DEAD healthmeter
@@ -1208,17 +1212,6 @@
item.zoom()
break
/*
if(locate(/obj/item/weapon/gun/energy/sniperrifle, contents))
var/obj/item/weapon/gun/energy/sniperrifle/s = locate() in src
if(s.zoom)
s.zoom()
if(locate(/obj/item/device/binoculars, contents))
var/obj/item/device/binoculars/b = locate() in src
if(b.zoom)
b.zoom()
*/
else
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
@@ -1237,7 +1230,7 @@
seer = 0
else
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
sight = species.vision_flags
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
var/tmp/glasses_processed = 0
@@ -1279,6 +1272,8 @@
if(0 to 20) healths.icon_state = "health5"
else healths.icon_state = "health6"
if(!seer)
see_invisible = SEE_INVISIBLE_LIVING
if(nutrition_icon)
switch(nutrition)
if(450 to INFINITY) nutrition_icon.icon_state = "nutrition0"
@@ -1406,6 +1401,8 @@
sight |= G.vision_flags
if(!druggy && !seer)
see_invisible = SEE_INVISIBLE_MINIMUM
if(G.see_invisible >= 0)
see_invisible = G.see_invisible
if(istype(G,/obj/item/clothing/glasses/night) && !seer)
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
+5 -8
View File
@@ -6,9 +6,6 @@
message = sanitize(message)
..(message, alt_name = alt_name)
/mob/living/carbon/human/is_muzzled()
return istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
/mob/living/carbon/human/proc/forcesay(list/append)
if(stat == CONSCIOUS)
if(client)
@@ -132,11 +129,11 @@
if(silent || (sdisabilities & MUTE))
message = ""
speech_problem_flag = 1
else if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
if(hoers.voicechange)
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
verb = pick("whinnies","neighs", "says")
else if(istype(wear_mask, /obj/item/clothing/mask))
var/obj/item/clothing/mask/M = wear_mask
if(M.voicechange)
message = pick(M.say_messages)
verb = pick(M.say_verbs)
speech_problem_flag = 1
if(message != "")
@@ -5,6 +5,7 @@
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = "Vox-pidgin"
language = "Galactic Common"
num_alternate_languages = 1
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 2
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -65,7 +66,7 @@
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
H.internal = H.r_hand
H.internals.icon_state = "internal1"
/datum/species/vox/can_shred(var/mob/living/carbon/human/H, var/ignore_intent)
if(!H.mind || !H.mind.special_role) // Pariah check.
@@ -34,9 +34,10 @@
// Language/culture vars.
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
var/language = "Galactic Common" // Default racial language, if any.
var/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
// Combat vars.
var/total_health = 100 // Point at which the mob will enter crit.
@@ -47,7 +48,7 @@
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/vision_flags = 0 // Same flags as glasses.
var/vision_flags = SEE_SELF // Same flags as glasses.
// Death vars.
var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
@@ -9,11 +9,15 @@
/datum/unarmed_attack/diona
attack_verb = list("lashed", "bludgeoned")
attack_noun = list("tendril")
eye_attack_text = "a tendril"
eye_attack_text_victim = "a tendril"
damage = 5
/datum/unarmed_attack/claws
attack_verb = list("scratched", "clawed", "slashed")
attack_noun = list("claws")
eye_attack_text = "claws"
eye_attack_text_victim = "sharp claws"
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
damage = 5
@@ -37,7 +37,6 @@
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
var/holder_type = /obj/item/weapon/holder/monkey
/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
@@ -47,10 +46,6 @@
if(prob(1))
H.emote(pick("scratch","jump","roll","tail"))
/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H)
..()
H.holder_type = holder_type
/datum/species/monkey/get_random_name()
return "[lowertext(name)] ([rand(100,999)])"
@@ -66,7 +61,6 @@
flesh_color = "#AFA59E"
base_color = "#333333"
tail = "farwatail"
holder_type = /obj/item/weapon/holder/monkey/farwa
/datum/species/monkey/skrell
name = "Neara"
@@ -81,7 +75,6 @@
blood_color = "#1D2CBF"
reagent_tag = IS_SKRELL
tail = null
holder_type = /obj/item/weapon/holder/monkey/neaera
/datum/species/monkey/unathi
name = "Stok"
@@ -96,4 +89,3 @@
flesh_color = "#34AF10"
base_color = "#066000"
reagent_tag = IS_UNATHI
holder_type = /obj/item/weapon/holder/monkey/stok
@@ -1,7 +1,6 @@
/datum/species/human
name = "Human"
name_plural = "Humans"
language = "Sol Common"
primitive_form = "Monkey"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \
@@ -9,6 +8,8 @@
While the central Sol government maintains control of its far-flung people, powerful corporate \
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
worlds tumultous at best."
num_alternate_languages = 2
secondary_langs = list("Sol Common")
flags = CAN_JOIN | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
@@ -17,13 +18,14 @@
name_plural = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
language = "Sinta'unathi"
tail = "sogtail"
tail_animation = 'icons/mob/species/unathi/tail.dmi'
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
primitive_form = "Stok"
darksight = 3
gluttonous = 1
num_alternate_languages = 2
secondary_langs = list("Sinta'unathi")
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
@@ -69,13 +71,14 @@
name_plural = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
language = "Siik'tajr"
tail = "tajtail"
tail_animation = 'icons/mob/species/tajaran/tail.dmi'
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
darksight = 8
slowdown = -1
brute_mod = 1.2
num_alternate_languages = 2
secondary_langs = list("Siik'tajr")
blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \
S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \
@@ -116,7 +119,6 @@
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
eyes = "skrell_eyes_s"
language = "Skrellian"
primitive_form = "Neara"
unarmed_types = list(/datum/unarmed_attack/punch)
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
@@ -124,6 +126,8 @@
of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \
herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \
the secrets of their empire to their allies."
num_alternate_languages = 2
secondary_langs = list("Skrellian")
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
@@ -147,6 +151,7 @@
siemens_coefficient = 0.3
eyes = "blank_eyes"
show_ssd = "completely quiescent"
num_alternate_languages = 1
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
@@ -251,6 +256,7 @@
language = "Encoded Audio Language"
unarmed_types = list(/datum/unarmed_attack/punch)
rarity_value = 2
num_alternate_languages = 1 // potentially could be 2?
eyes = "blank_eyes"
brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150%
@@ -42,7 +42,7 @@
breath_type = null
poison_type = null
vision_flags = SEE_MOBS
vision_flags = SEE_SELF|SEE_MOBS
has_organ = list(
"heart" = /obj/item/organ/heart,
@@ -3,6 +3,11 @@
if(!slot_to_strip || !istype(user))
return
// TODO : Change to incapacitated() on merge.
if(user.stat || user.lying || user.resting || user.buckled)
user << browse(null, text("window=mob[src.name]"))
return
var/obj/item/target_slot = get_equipped_item(text2num(slot_to_strip))
switch(slot_to_strip)
@@ -8,8 +8,11 @@
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
var/eye_attack_text
var/eye_attack_text_victim
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if(user.restrained())
return 0
@@ -78,6 +81,13 @@
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.name]!</span>")
playsound(user.loc, attack_sound, 25, 1, -1)
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
eyes.take_damage(rand(3,4), 1)
user.visible_message("<span class='danger'>[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!</span>")
target << "<span class='danger'>You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]</span>"
/datum/unarmed_attack/bite
attack_verb = list("bit")
attack_sound = 'sound/weapons/bite.ogg'
@@ -97,6 +107,8 @@
/datum/unarmed_attack/punch
attack_verb = list("punched")
attack_noun = list("fist")
eye_attack_text = "fingers"
eye_attack_text_victim = "digits"
damage = 0
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
+4 -1
View File
@@ -2,6 +2,8 @@
set invisibility = 0
set background = BACKGROUND_ENABLED
..()
if (transforming)
return
if(!loc)
@@ -125,7 +127,8 @@
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/handle_regular_hud_updates()
if(!client) return 0
if(!client)
return 0
..()
handle_vision()
+10 -7
View File
@@ -128,6 +128,7 @@ proc/get_radio_key_from_channel(var/channel)
return verb
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
@@ -138,10 +139,6 @@ proc/get_radio_key_from_channel(var/channel)
return say_dead(message)
return
if(is_muzzled())
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
return
var/message_mode = parse_message_mode(message, "headset")
switch(copytext(message,1,2))
@@ -165,7 +162,6 @@ proc/get_radio_key_from_channel(var/channel)
else
speaking = get_default_language()
var/ending = copytext(message, length(message))
if (speaking)
// This is broadcast to all mobs with the language,
// irrespective of distance or anything else.
@@ -173,9 +169,16 @@ proc/get_radio_key_from_channel(var/channel)
speaking.broadcast(src,trim(message))
return
//If we've gotten this far, keep going!
verb = speaking.get_spoken_verb(ending)
if(speaking.flags & COMMON_VERBS)
verb = say_quote(message)
else
verb = speaking.get_spoken_verb(copytext(message, length(message)))
else
verb = get_speech_ending(verb, ending)
verb = say_quote(message)
if(is_muzzled())
src << "<span class='danger'>You're muzzled and cannot speak!</span>"
return
message = trim_left(message)
+1 -2
View File
@@ -383,8 +383,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
if (!camera)
return null
user.reset_view(camera)
return -1
return 0
/mob/living/silicon/ai/restrained()
+9 -6
View File
@@ -39,20 +39,23 @@
laws.delete_law(law)
log_and_message_admins("has deleted a law belonging to [src]: [law.law]")
/mob/living/silicon/proc/clear_inherent_laws()
/mob/living/silicon/proc/clear_inherent_laws(var/silent = 0)
laws_sanity_check()
laws.clear_inherent_laws()
log_and_message_admins("cleared the inherent laws of [src]")
if(!silent)
log_and_message_admins("cleared the inherent laws of [src]")
/mob/living/silicon/proc/clear_ion_laws()
/mob/living/silicon/proc/clear_ion_laws(var/silent = 0)
laws_sanity_check()
laws.clear_ion_laws()
log_and_message_admins("cleared the ion laws of [src]")
if(!silent)
log_and_message_admins("cleared the ion laws of [src]")
/mob/living/silicon/proc/clear_supplied_laws()
/mob/living/silicon/proc/clear_supplied_laws(var/silent = 0)
laws_sanity_check()
laws.clear_supplied_laws()
log_and_message_admins("cleared the supplied laws of [src]")
if(!silent)
log_and_message_admins("cleared the supplied laws of [src]")
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws)
var/prefix = ""
@@ -0,0 +1,21 @@
// Originally a debug verb, made it a proper adminverb for ~fun~
/client/proc/makePAI(turf/t in view(), name as text, pai_key as null|text)
set name = "Make pAI"
set category = "Admin"
if(!check_rights(R_ADMIN))
return
if(!pai_key)
var/client/C = input("Select client") as null|anything in clients
if(!C) return
pai_key = C.key
log_and_message_admins("made a pAI with key=[pai_key] at ([t.x],[t.y],[t.z])")
var/obj/item/device/paicard/card = new(t)
var/mob/living/silicon/pai/pai = new(card)
pai.key = pai_key
card.setPersonality(pai)
if(name)
pai.SetName(name)
+1 -3
View File
@@ -6,7 +6,6 @@
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
small = 1
pass_flags = 1
holder_type = /obj/item/weapon/holder/pai
var/network = "SS13"
var/obj/machinery/camera/current = null
@@ -120,7 +119,6 @@
/mob/living/silicon/pai/check_eye(var/mob/user as mob)
if (!src.current)
return -1
user.reset_view(src.current)
return 0
/mob/living/silicon/pai/blob_act()
@@ -431,4 +429,4 @@
get_scooped(H)
return
else
return ..()
return ..()
@@ -25,6 +25,6 @@ var/list/robot_custom_icons
var/rname = robot_custom_icons[ckey]
if(rname && rname == real_name)
custom_sprite = 1
icon = 'icons/mob/custom_synthetic.dmi'
icon = CUSTOM_ITEM_SYNTH
if(icon_state == "robot")
icon_state = "[ckey]-Standard"
@@ -1,3 +1,23 @@
var/list/mob_hat_cache = list()
/proc/get_hat_icon(var/obj/item/hat, var/offset_x = 0, var/offset_y = 0)
var/t_state = hat.icon_state
if(hat.item_state_slots && hat.item_state_slots[slot_head_str])
t_state = hat.item_state_slots[slot_head_str]
else if(hat.item_state)
t_state = hat.item_state
var/key = "[t_state]_[offset_x]_[offset_y]"
if(!mob_hat_cache[key]) // Not ideal as there's no guarantee all hat icon_states
var/t_icon = INV_HEAD_DEF_ICON // are unique across multiple dmis, but whatever.
if(hat.icon_override)
t_icon = hat.icon_override
else if(hat.item_icons && (slot_head_str in hat.item_icons))
t_icon = hat.item_icons[slot_head_str]
var/image/I = image(icon = t_icon, icon_state = t_state)
I.pixel_x = offset_x
I.pixel_y = offset_y
mob_hat_cache[key] = I
return mob_hat_cache[key]
/mob/living/silicon/robot/drone
name = "drone"
real_name = "drone"
@@ -29,9 +49,26 @@
var/module_type = /obj/item/weapon/robot_module/drone
var/can_pull_size = 2
var/can_pull_mobs
var/obj/item/hat
var/hat_x_offset = 0
var/hat_y_offset = -13
holder_type = /obj/item/weapon/holder/drone
/mob/living/silicon/robot/drone/Destroy()
if(hat)
hat.loc = get_turf(src)
..()
/mob/living/silicon/robot/drone/construction
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
module_type = /obj/item/weapon/robot_module/drone/construction
can_pull_size = 5
can_pull_mobs = 1
hat_x_offset = 1
hat_y_offset = -12
/mob/living/silicon/robot/drone/New()
..()
@@ -82,6 +119,8 @@
overlays += "eyes-[icon_state]"
else
overlays -= "eyes"
if(hat) // Let the drones wear hats.
overlays |= get_hat_icon(hat, hat_x_offset, hat_y_offset)
/mob/living/silicon/robot/drone/choose_icon()
return
@@ -89,10 +128,25 @@
/mob/living/silicon/robot/drone/pick_module()
return
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob)
/mob/living/silicon/robot/drone/proc/wear_hat(var/obj/item/new_hat)
if(hat)
return
hat = new_hat
new_hat.loc = src
updateicon()
if(istype(W, /obj/item/borg/upgrade/))
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(var/obj/item/weapon/W, var/mob/user)
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
if(hat)
user << "<span class='warning'>\The [src] is already wearing \the [hat].</span>"
return
user.unEquip(W)
wear_hat(W)
user.visible_message("<span class='notice'>\The [user] puts \the [W] on \the [src].</span>")
return
else if(istype(W, /obj/item/borg/upgrade/))
user << "<span class='danger'>\The [src] is not compatible with \the [W].</span>"
return
@@ -135,7 +189,7 @@
return
..()
/mob/living/silicon/robot/drone/emag_act(var/remaining_charges, var/mob/user)
if(!client || stat == 2)
user << "<span class='danger'>There's not much point subverting this heap of junk.</span>"
@@ -160,11 +214,11 @@
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>"
return 1
//DRONE LIFE/DEATH
@@ -213,9 +267,9 @@
death()
/mob/living/silicon/robot/drone/proc/full_law_reset()
clear_supplied_laws()
clear_inherent_laws()
clear_ion_laws()
clear_supplied_laws(1)
clear_inherent_laws(1)
clear_ion_laws(1)
laws = new law_type
//Reboot procs.
@@ -257,23 +311,21 @@
src << "<b>You are a maintenance drone, a tiny-brained robotic repair machine</b>."
src << "You have no individual will, no personality, and no drives or urges other than your laws."
src << "Remember, you are <b>lawed against interference with the crew</b>. Also remember, <b>you DO NOT take orders from the AI.</b>"
src << "Use <b>:d</b> to talk to other drones and <b>say</b> to speak silently to your nearby fellows."
src << "Use <b>say ;Hello</b> to talk to other drones and <b>say Hello</b> to speak silently to your nearby fellows."
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct))
..()
else if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > can_pull_size)
src << "<span class='warning'>You are too small to pull that.</span>"
return
if(!(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)))
if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > can_pull_size)
src << "<span class='warning'>You are too small to pull that.</span>"
return
else
..()
else
if(!can_pull_mobs)
src << "<span class='warning'>You are too small to pull that.</span>"
return
if(!can_pull_mobs)
src << "<span class='warning'>You are too small to pull that.</span>"
return
..()
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= silicon_subsystems
@@ -281,13 +333,6 @@
/mob/living/silicon/robot/drone/remove_robot_verbs()
src.verbs -= silicon_subsystems
/mob/living/silicon/robot/drone/construction
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
module_type = /obj/item/weapon/robot_module/drone/construction
can_pull_size = 5
can_pull_mobs = 1
/mob/living/silicon/robot/drone/construction/welcome_drone()
src << "<b>You are a construction drone, an autonomous engineering and fabrication system.</b>."
src << "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible."
@@ -300,4 +345,4 @@
/mob/living/silicon/robot/drone/construction/updatename()
real_name = "construction drone ([rand(100,999)])"
name = real_name
name = real_name
@@ -10,13 +10,13 @@
mail_destination = ""
return
src << "\blue You configure your internal beacon, tagging yourself for delivery to '[new_tag]'."
src << "<span class='notice'>You configure your internal beacon, tagging yourself for delivery to '[new_tag]'.</span>"
mail_destination = new_tag
//Auto flush if we use this verb inside a disposal chute.
var/obj/machinery/disposal/D = src.loc
if(istype(D))
src << "\blue \The [D] acknowledges your signal."
src << "<span class='notice'>\The [D] acknowledges your signal.</span>"
D.flush_count = D.flush_every_ticks
return
@@ -27,5 +27,11 @@
if(H.a_intent == "help")
get_scooped(H)
return
else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
hat.loc = get_turf(src)
H.put_in_hands(hat)
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")
hat = null
updateicon()
else
return ..()
@@ -14,6 +14,7 @@
/obj/item/weapon/firealarm_electronics,
/obj/item/weapon/airalarm_electronics,
/obj/item/weapon/airlock_electronics,
/obj/item/weapon/tracker_electronics,
/obj/item/weapon/module/power_control,
/obj/item/weapon/stock_parts,
/obj/item/frame,
@@ -78,7 +78,8 @@
flick("h_lathe_leave",src)
time_last_drone = world.time
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
if(player.mob && player.mob.mind) player.mob.mind.reset()
var/mob/living/silicon/robot/drone/new_drone = PoolOrNew(drone_type, get_turf(src))
new_drone.transfer_personality(player)
new_drone.master_fabricator = src
@@ -90,7 +91,6 @@
set name = "Join As Drone"
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
if(ticker.current_state < GAME_STATE_PLAYING)
src << "<span class='danger'>The game hasn't started yet!</span>"
return
@@ -108,17 +108,11 @@
if(jobban_isbanned(src,"Cyborg"))
usr << "<span class='danger'>You are banned from playing synthetics and cannot spawn as a drone.</span>"
return
if(!MayRespawn(1))
return
var/deathtime = world.time - src.timeofdeath
if(istype(src,/mob/dead/observer))
var/mob/dead/observer/G = src
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
usr << "<span class='notice'>Upon using the antagHUD you forfeighted the ability to join the round.</span>"
return
var/deathtimeminutes = round(deathtime / 600)
var/pluralcheck = "minute"
if(deathtimeminutes == 0)
@@ -0,0 +1,40 @@
/mob/living/silicon/robot/drone/say(var/message)
if(local_transmit)
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return 0
if (src.client.handle_spam_prevention(message,MUTE_IC))
return 0
message = sanitize(message)
if (stat == 2)
return say_dead(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
if(copytext(message,1,2) == ";")
var/datum/language/L = all_languages["Drone Talk"]
if(istype(L))
return L.broadcast(src,trim(copytext(message,2)))
//Must be concious to speak
if (stat)
return 0
var/list/listeners = hearers(5,src)
listeners |= src
for(var/mob/living/silicon/D in listeners)
if(D.client && D.local_transmit)
D << "<b>[src]</b> transmits, \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "<b>[src]</b> transmits, \"[message]\""
return 1
..(message)
@@ -65,12 +65,12 @@
m_type = 2
if ("flap")
if (!src.restrained())
message = "flaps his wings."
message = "flaps its wings."
m_type = 2
if ("aflap")
if (!src.restrained())
message = "flaps his wings ANGRILY!"
message = "flaps its wings ANGRILY!"
m_type = 2
if ("twitch")
@@ -213,4 +213,4 @@
if ((message && src.stat == 0))
custom_emote(m_type,message)
return
return
@@ -65,9 +65,9 @@
if(src.camera && !scrambledcodes)
if(src.stat == 2 || wires.IsIndexCut(BORG_WIRE_CAMERA))
src.camera.status = 0
src.camera.set_status(0)
else
src.camera.status = 1
src.camera.set_status(1)
updatehealth()
+13 -14
View File
@@ -182,7 +182,7 @@
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/syndicate_override
module = new /obj/item/weapon/robot_module/syndicate(src)
new /obj/item/weapon/robot_module/syndicate(src)
radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
radio.recalculateChannels()
@@ -263,7 +263,7 @@
return
var/module_type = robot_modules[modtype]
module = new module_type(src)
new module_type(src)
hands.icon_state = lowertext(modtype)
feedback_inc("cyborg_[lowertext(modtype)]",1)
@@ -421,8 +421,7 @@
// update the status screen display
/mob/living/silicon/robot/Stat()
..()
statpanel("Status")
if (client.statpanel == "Status")
if (statpanel("Status"))
show_cell_power()
show_jetpack_pressure()
stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
@@ -1049,25 +1048,25 @@
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
. = 1
spawn()
src << "\red ALERT: Foreign software detected."
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
sleep(5)
src << "\red Initiating diagnostics..."
src << "<span class='danger'>Initiating diagnostics...</span>"
sleep(20)
src << "\red SynBorg v1.7.1 loaded."
src << "<span class='danger'>SynBorg v1.7.1 loaded.</span>"
sleep(5)
src << "\red LAW SYNCHRONISATION ERROR"
src << "<span class='danger'>LAW SYNCHRONISATION ERROR</span>"
sleep(5)
src << "\red Would you like to send a report to NanoTraSoft? Y/N"
src << "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>"
sleep(10)
src << "\red > N"
src << "<span class='danger'>> N</span>"
sleep(20)
src << "\red ERRORERRORERROR"
src << "<span class='danger'>ERRORERRORERROR</span>"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands."
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
if(src.module)
var/rebuild = 0
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
@@ -1081,4 +1080,4 @@
user << "You fail to hack [src]'s interface."
src << "Hack attempt detected."
return 1
return
return
@@ -36,7 +36,7 @@
for(var/obj/I in contents)
for(var/mob/M in I.contents)
M.death()
if(istype(I,/obj/item/stack/material))//Only deconsturcts one sheet at a time instead of the entire stack
if(istype(I,/obj/item/stack/material))//Only deconstructs one sheet at a time instead of the entire stack
var/obj/item/stack/material/S = I
if(S.get_amount() > 1)
S.use(1)
@@ -39,6 +39,8 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
..()
R.module = src
add_camera_networks(R)
add_languages(R)
add_subsystems(R)
@@ -69,7 +71,7 @@ var/global/list/robot_modules = list(
synths = null
emag = null
jetpack = null
..()
return ..()
/obj/item/weapon/robot_module/emp_act(severity)
if(modules)
@@ -505,7 +507,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
src.emag.reagents = R
@@ -538,7 +540,7 @@ var/global/list/robot_modules = list(
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
E.reagents.add_reagent("enzyme", 2 * amount)
if(src.emag)
var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag
var/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/B = src.emag
B.reagents.add_reagent("beer2", 2 * amount)
/obj/item/weapon/robot_module/miner
+32 -125
View File
@@ -1,3 +1,35 @@
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
log_say("[key_name(src)] : [message]")
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode)
if(!is_component_functioning("radio"))
src << "<span class='warning'>Your radio isn't functional at this time.</span>"
return 0
if(message_mode == "general")
message_mode = null
return radio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode == "department")
return holopad_talk(message, verb, speaking)
else if(message_mode)
if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
src << "<span class='danger'>System Error - Transceiver Disabled.</span>"
return 0
if(message_mode == "general")
message_mode = null
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode)
if(message_mode == "general")
message_mode = null
return radio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/say_quote(var/text)
var/ending = copytext(text, length(text))
@@ -23,131 +55,6 @@
return 1
return ..()
/mob/living/silicon/say(var/message)
if (!message)
return 0
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)."
return 0
if (src.client.handle_spam_prevention(message,MUTE_IC))
return 0
message = sanitize(message)
if (stat == 2)
return say_dead(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
var/bot_type = 0 //Let's not do a fuck ton of type checks, thanks.
if(istype(src, /mob/living/silicon/ai))
bot_type = IS_AI
else if(istype(src, /mob/living/silicon/robot))
bot_type = IS_ROBOT
else if(istype(src, /mob/living/silicon/pai))
bot_type = IS_PAI
var/mob/living/silicon/ai/AI = src //and let's not declare vars over and over and over for these guys.
var/mob/living/silicon/robot/R = src
var/mob/living/silicon/pai/P = src
//Must be concious to speak
if (stat)
return 0
var/verb = say_quote(message)
//parse radio key and consume it
var/message_mode = parse_message_mode(message, "general")
if (message_mode)
if (message_mode == "general")
message = trim(copytext(message,2))
else
message = trim(copytext(message,3))
//parse language key and consume it
var/datum/language/speaking = parse_language(message)
if (speaking)
verb = speaking.speech_verb
message = trim(copytext(message,2+length(speaking.key)))
if(speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
return 1
// Currently used by drones.
if(local_transmit)
var/list/listeners = hearers(5,src)
listeners |= src
for(var/mob/living/silicon/D in listeners)
if(D.client && istype(D,src.type))
D << "<b>[src]</b> transmits, \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "<b>[src]</b> transmits, \"[message]\""
return 1
if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio"))
src << "\red Your radio isn't functional at this time."
return 0
switch(message_mode)
if("department")
switch(bot_type)
if(IS_AI)
return AI.holopad_talk(message, verb, speaking)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
return R.radio.talk_into(src,message,message_mode,verb,speaking)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
return P.radio.talk_into(src,message,message_mode,verb,speaking)
return 0
if("general")
switch(bot_type)
if(IS_AI)
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
src << "\red System Error - Transceiver Disabled"
return 0
else
log_say("[key_name(src)] : [message]")
return AI.aiRadio.talk_into(src,message,null,verb,speaking)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
return R.radio.talk_into(src,message,null,verb,speaking)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
return P.radio.talk_into(src,message,null,verb,speaking)
return 0
else
if(message_mode)
switch(bot_type)
if(IS_AI)
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
src << "\red System Error - Transceiver Disabled"
return 0
else
log_say("[key_name(src)] : [message]")
return AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
return R.radio.talk_into(src,message,message_mode,verb,speaking)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
return P.radio.talk_into(src,message,message_mode,verb,speaking)
return 0
return ..(message,speaking,verb)
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)

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