Merge remote-tracking branch 'upstream/dev-freeze' into dev-freeze

Conflicts:
	baystation12.dme
	code/modules/mob/living/carbon/human/unarmed_attack.dm
This commit is contained in:
Hubblenaut
2014-12-28 00:04:53 +01:00
435 changed files with 7851 additions and 7883 deletions
+8 -4
View File
@@ -228,11 +228,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "<span class='warning'>You have no body.</span>"
return
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
usr << "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>"
usr << "<span class='warning'>Another consciousness is in your body... it is resisting you.</span>"
return
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune
if(!(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"])) //astral journeying rune
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
var/found_rune
for(var/obj/effect/rune/R in mind.current.loc) //whilst corpse is alive, we can only reenter the body if it's on the rune
if(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"]) // Found an astral journey rune.
found_rune = 1
break
if(!found_rune)
usr << "<span class='warning'>The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you.</span>"
return
mind.current.ajourn=0
+1 -1
View File
@@ -52,7 +52,7 @@
if(stat == DEAD)
return 0
if(!gibbed)
if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it.
src.visible_message("<b>\The [src.name]</b> [deathmessage]")
stat = DEAD
+29 -6
View File
@@ -24,6 +24,8 @@
if (message)
log_emote("[name]/[key] : [message]")
var/list/seeing_obj = list() //For objs that need to see emotes. You can use see_emote(), which is based off of hear_talk()
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
@@ -37,10 +39,21 @@
if(M.stat == 2 && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
for(var/I in view(world.view, get_turf(usr))) //get_turf is needed to stop weirdness with x-ray.
if(istype(I, /mob/))
var/mob/M = I
for(var/obj/O in M.contents)
seeing_obj |= O
else if(istype(I, /obj/))
var/obj/O = I
seeing_obj |= O
// Type 1 (Visual) emotes are sent to anyone in view of the item
if (m_type & 1)
for (var/mob/O in viewers(src, null))
//for (var/mob/O in viewers(src, null))
for (var/mob/O in viewers(get_turf(src), null)) //This may break people with x-ray being able to see emotes across walls,
//but this saves many headaches down the road, involving mechs and pAIs.
//x-ray is so rare these days anyways.
if(O.status_flags & PASSEMOTES)
@@ -52,8 +65,13 @@
O.show_message(message, m_type)
for(var/obj/O in seeing_obj)
spawn(0)
if(O) //It's possible that it could be deleted in the meantime.
O.see_emote(src, message, 1)
// Type 2 (Audible) emotes are sent to anyone in hear range
// of the *LOCATION* -- this is important for pAIs to be heard
// of the *LOCATION* -- this is important for AIs/pAIs to be heard
else if (m_type & 2)
for (var/mob/O in hearers(get_turf(src), null))
@@ -67,19 +85,24 @@
O.show_message(message, m_type)
for(var/obj/O in seeing_obj)
spawn(0)
if(O) //It's possible that it could be deleted in the meantime.
O.see_emote(src, message, 2)
/mob/proc/emote_dead(var/message)
if(client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot send deadchat emotes (muted)."
src << "<span class='danger'>You cannot send deadchat emotes (muted).</span>"
return
if(!(client.prefs.toggles & CHAT_DEAD))
src << "\red You have deadchat muted."
src << "<span class='danger'>You have deadchat muted.</span>"
return
if(!src.client.holder)
if(!dsay_allowed)
src << "\red Deadchat is globally muted"
if(!config.dsay_allowed)
src << "<span class='danger'>Deadchat is globally muted.</span>"
return
+40 -33
View File
@@ -25,22 +25,21 @@
hear_sleep(message)
return
var/style = "body"
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
message = pick(S.speak)
else
message = stars(message)
if(language)
style = language.colour
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
message = pick(S.speak)
else
if(language)
message = language.scramble(message)
else
message = stars(message)
var/speaker_name = speaker.name
if(istype(speaker, /mob/living/carbon/human))
@@ -61,12 +60,16 @@
message = "<b>[message]</b>"
if(sdisabilities & DEAF || ear_deaf)
if(speaker == src)
src << "<span class='warning'>You cannot hear yourself speak!</span>"
else
src << "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear \him."
if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
if(speaker == src)
src << "<span class='warning'>You cannot hear yourself speak!</span>"
else
src << "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear \him."
else
src << "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='[style]'>\"[message]\"</span></span></span>"
if(language)
src << "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>"
else
src << "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>"
if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
src.playsound_local(source, speech_sound, sound_vol, 1)
@@ -83,29 +86,28 @@
var/track = null
var/style = "body"
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
if(S.speak && S.speak.len)
message = pick(S.speak)
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
if(S.speak && S.speak.len)
message = pick(S.speak)
else
return
else
return
else
if(language)
message = language.scramble(language)
else
message = stars(message)
if(hard_to_hear)
message = stars(message)
if(language)
style = language.colour
if(hard_to_hear)
message = stars(message)
var/speaker_name = speaker.name
if(vname)
@@ -165,13 +167,18 @@
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] (<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>)"
var/formatted
if(language)
formatted = language.format_message_radio(message, verb)
else
formatted = "[verb], <span class=\"body\">\"[message]\"</span>"
if(sdisabilities & DEAF || ear_deaf)
if(prob(20))
src << "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>"
else if(track)
src << "[part_a][track][part_b][verb], <span class=\"[style]\">\"[message]\"</span></span></span>"
src << "[part_a][track][part_b][formatted]</span></span>"
else
src << "[part_a][speaker_name][part_b][verb], <span class=\"[style]\">\"[message]\"</span></span></span>"
src << "[part_a][speaker_name][part_b][formatted]</span></span>"
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
+136 -22
View File
@@ -10,28 +10,79 @@
var/exclaim_verb = "exclaims" // Used when sentence ends in a !
var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead.
var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
var/colour = "body" // CSS style to use for strings in this language.
var/colour = "body" // CSS style to use for strings in this language.
var/key = "x" // Character used to speak in language eg. :o for Unathi.
var/flags = 0 // Various language flags.
var/native // If set, non-native speakers will have trouble speaking.
var/list/syllables // Used when scrambling text for a non-speaker.
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string.
/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4)
if(!syllables || !syllables.len)
if(gender==FEMALE)
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
else
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
var/full_name = ""
var/new_name = ""
for(var/i = 0;i<name_count;i++)
new_name = ""
for(var/x = rand(Floor(syllable_count/2),syllable_count);x>0;x--)
new_name += pick(syllables)
full_name += " [capitalize(lowertext(new_name))]"
return "[trim(full_name)]"
/datum/language/proc/scramble(var/input)
if(!syllables || !syllables.len)
return stars(input)
var/input_size = length(input)
var/scrambled_text = ""
var/capitalize = 1
while(length(scrambled_text) < input_size)
var/next = pick(syllables)
if(capitalize)
next = capitalize(next)
capitalize = 0
scrambled_text += next
var/chance = rand(100)
if(chance <= 5)
scrambled_text += ". "
capitalize = 1
else if(chance > 5 && chance <= space_chance)
scrambled_text += " "
scrambled_text = trim(scrambled_text)
var/ending = copytext(scrambled_text, length(scrambled_text))
if(ending == ".")
scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1)
scrambled_text += copytext(input, length(input))
return scrambled_text
/datum/language/proc/format_message(message, verb)
return "[verb], <span class='message'><span class='[colour]'>\"[capitalize(message)]\"</span></span>"
/datum/language/proc/format_message_radio(message, verb)
return "[verb], <span class='[colour]'>\"[capitalize(message)]\"</span>"
/datum/language/proc/get_talkinto_msg_range(message)
// if you yell, you'll be heard from two tiles over instead of one
return (copytext(message, length(message)) == "!") ? 2 : 1
/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
log_say("[key_name(speaker)] : ([name]) [message]")
if(!speaker_mask) speaker_mask = speaker.name
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [format_message(message, get_spoken_verb(message))]</span></i>"
for(var/mob/player in player_list)
var/understood = 0
if(istype(player,/mob/dead))
understood = 1
else if((src in player.languages) && check_special_condition(player))
understood = 1
if(understood)
if(!speaker_mask) speaker_mask = speaker.name
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> <span class='message'>[speech_verb], \"<span class='[colour]'>[message]</span><span class='message'>\"</span></span></i>"
player << "[msg]"
if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
player << msg
/datum/language/proc/check_special_condition(var/mob/other)
return 1
@@ -44,6 +95,23 @@
return ask_verb
return speech_verb
// Noise "language", for audible emotes.
/datum/language/noise
name = "Noise"
desc = "Noises"
key = ""
flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG
/datum/language/noise/format_message(message, verb)
return "<span class='message'><span class='[colour]'>[message]</span></span>"
/datum/language/noise/format_message_radio(message, verb)
return "<span class='[colour]'>[message]</span>"
/datum/language/noise/get_talkinto_msg_range(message)
// if you make a loud noise (screams etc), you'll be heard from 4 tiles over instead of two
return (copytext(message, length(message)) == "!") ? 4 : 2
/datum/language/unathi
name = "Sinta'unathi"
desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
@@ -53,6 +121,14 @@
colour = "soghun"
key = "o"
flags = WHITELISTED
syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh")
/datum/language/unathi/get_random_name()
var/new_name = ..()
while(findtextEx(new_name,"sss",1,null))
new_name = replacetext(new_name, "sss", "ss")
return capitalize(new_name)
/datum/language/tajaran
name = "Siik'tajr"
@@ -63,6 +139,19 @@
colour = "tajaran"
key = "j"
flags = WHITELISTED
syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \
"hal","ket","jurl","mah","tul","cresh","azu","ragh")
/datum/language/tajaran/get_random_name(var/gender)
var/new_name = ..(gender,1)
if(prob(80))
new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]"
else
new_name += ..(gender,1)
return new_name
/datum/language/skrell
name = "Skrellian"
@@ -73,6 +162,7 @@
colour = "skrell"
key = "k"
flags = WHITELISTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
/datum/language/vox
name = "Vox-pidgin"
@@ -82,7 +172,12 @@
exclaim_verb = "SHRIEKS"
colour = "vox"
key = "5"
flags = RESTRICTED
flags = WHITELISTED
syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \
"SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA")
/datum/language/vox/get_random_name()
return ..(FEMALE,1,6)
/datum/language/diona
name = "Rootspeak"
@@ -93,6 +188,12 @@
colour = "soghun"
key = "q"
flags = RESTRICTED
syllables = list("hs","zt","kr","st","sh")
/datum/language/diona/get_random_name()
var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]"
new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]"
return new_name
/datum/language/common
name = "Galactic Common"
@@ -101,6 +202,7 @@
whisper_verb = "whispers"
key = "0"
flags = RESTRICTED
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.
/datum/language/common/get_spoken_verb(var/msg_end)
@@ -116,9 +218,10 @@
desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system."
speech_verb = "says"
whisper_verb = "whispers"
colour = "rough"
colour = "solcom"
key = "1"
flags = RESTRICTED
syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e")
/datum/language/human/get_spoken_verb(var/msg_end)
switch(msg_end)
@@ -135,6 +238,15 @@
speech_verb = "enunciates"
colour = "say_quote"
key = "2"
space_chance = 100
syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore",
"magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud",
"exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo",
"consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in",
"voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla",
"pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt",
"in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum")
/datum/language/gutter
name = "Gutter"
@@ -142,6 +254,7 @@
speech_verb = "growls"
colour = "rough"
key = "3"
syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra")
/datum/language/xenocommon
name = "Xenomorph"
@@ -152,6 +265,7 @@
exclaim_verb = "hisses"
key = "4"
flags = RESTRICTED
syllables = list("sss","sSs","SSS")
/datum/language/xenos
name = "Hivemind"
@@ -286,15 +400,14 @@
return 1
/mob/proc/remove_language(var/rem_language)
languages.Remove(all_languages[rem_language])
return 0
var/datum/language/L = all_languages[rem_language]
. = (L in languages)
languages.Remove(L)
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak(datum/language/speaking)
return (universal_speak || speaking in src.languages)
return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages)
//TBD
/mob/verb/check_languages()
@@ -305,7 +418,8 @@
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
for(var/datum/language/L in languages)
dat += "<b>[L.name] (:[L.key])</b><br/>[L.desc]<br/><br/>"
if(!(L.flags & NONGLOBAL))
dat += "<b>[L.name] (:[L.key])</b><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
+3 -12
View File
@@ -15,21 +15,12 @@
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
var/datum/language/speaking = null
if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
if(languages.len)
for(var/datum/language/L in languages)
if(lowertext(channel_prefix) == ":[L.key]")
verb = L.speech_verb
speaking = L
break
var/datum/language/speaking = parse_language(message)
if(speaking)
message = trim(copytext(message,3))
message = copytext(message, 2+length(speaking.key))
message = capitalize(trim_left(message))
message = trim(message)
if(!message || stat)
return
+4 -4
View File
@@ -2,7 +2,7 @@
/obj/item/device/mmi/digital/New()
src.brainmob = new(src)
src.brainmob.add_language("Binary")
src.brainmob.add_language("Robot Talk")
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.stat = 0
@@ -18,7 +18,7 @@
return
/obj/item/device/mmi
name = "Man-Machine Interface"
name = "man-machine interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity."
icon = 'icons/obj/assemblies.dmi'
icon_state = "mmi_empty"
@@ -116,7 +116,7 @@
return
/obj/item/device/mmi/radio_enabled
name = "Radio-enabled Man-Machine Interface"
name = "radio-enabled man-machine interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
origin_tech = "biotech=4"
@@ -165,4 +165,4 @@
brainmob.emp_damage += rand(10,20)
if(3)
brainmob.emp_damage += rand(0,10)
..()
..()
@@ -55,4 +55,7 @@
canmove = 1
use_me = 1 //If it can move, let it emote
else canmove = 0
return canmove
return canmove
/mob/living/carbon/brain/binarycheck()
return istype(loc, /obj/item/device/mmi/digital)
@@ -30,7 +30,7 @@
brainmob.client.screen.len = null //clear the hud
/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H)
name = "[H]'s brain"
name = "\the [H]'s [initial(src.name)]"
brainmob = new(src)
brainmob.name = H.real_name
brainmob.real_name = H.real_name
@@ -39,7 +39,7 @@
if(H.mind)
H.mind.transfer_to(brainmob)
brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain."
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a [initial(src.name)].</span>"
callHook("debrain", list(brainmob))
/obj/item/organ/brain/examine(mob/user) // -- TLE
@@ -72,4 +72,23 @@
if(brainmob.mind)
brainmob.mind.transfer_to(target)
else
target.key = brainmob.key
target.key = brainmob.key
..()
/obj/item/organ/brain/slime
name = "slime core"
desc = "A complex, organic knot of jelly and crystalline particles."
prosthetic_name = null
prosthetic_icon = null
robotic = 2
icon = 'icons/mob/slimes.dmi'
icon_state = "green slime extract"
/obj/item/organ/brain/golem
name = "chem"
desc = "A tightly furled roll of paper, covered with indecipherable runes."
prosthetic_name = null
prosthetic_icon = null
robotic = 2
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll"
@@ -1,7 +1,9 @@
/mob/living/carbon/brain/death(gibbed)
if(!gibbed && istype(container, /obj/item/device/mmi)) //If not gibbed but in a container.
container.icon_state = "mmi_dead"
return ..(gibbed,"beeps shrilly as the MMI flatlines!")
return ..(gibbed,"beeps shrilly as the MMI flatlines!")
else
return ..(gibbed,"no message")
/mob/living/carbon/brain/gib()
if(istype(container, /obj/item/device/mmi))
+20 -2
View File
@@ -6,13 +6,31 @@
if(!(container && istype(container, /obj/item/device/mmi)))
return //No MMI, can't speak, bucko./N
else
var/datum/language/speaking = parse_language(message)
if(speaking)
message = copytext(message, 2+length(speaking.key))
var/verb = "says"
var/ending = copytext(message, length(message))
if (speaking)
verb = speaking.get_spoken_verb(ending)
else
if(ending=="!")
verb=pick("exclaims","shouts","yells")
if(ending=="?")
verb="asks"
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
return
else
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
if(speaking && speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
return
if(istype(container, /obj/item/device/mmi/radio_enabled))
var/obj/item/device/mmi/radio_enabled/R = container
if(R.radio)
spawn(0) R.radio.hear_talk(src, sanitize(message))
..()
spawn(0) R.radio.hear_talk(src, trim(sanitize(message)), verb, speaking)
..(trim(message), speaking, verb)
+12 -2
View File
@@ -57,7 +57,7 @@
for(var/mob/N in viewers(src, null))
if(N.client)
N.show_message(text("\red <B>[M] bursts out of [src]!</B>"), 2)
. = ..(null,1)
..()
/mob/living/carbon/attack_hand(mob/M as mob)
if(!istype(M, /mob/living/carbon)) return
@@ -510,4 +510,14 @@
return
/mob/living/carbon/can_use_vents()
return
return
/mob/living/carbon/slip(var/slipped_on,stun_duration=8)
if(buckled)
return 0
stop_pulling()
src << "<span class='warning'>You slipped on [slipped_on]!</span>"
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
Stun(stun_duration)
Weaken(Floor(stun_duration/2))
return 1
+23 -22
View File
@@ -1,5 +1,12 @@
/mob/living/carbon/human/gib()
for(var/datum/organ/internal/I in internal_organs)
var/obj/item/organ/current_organ = I.remove()
if(current_organ)
if(istype(loc,/turf))
current_organ.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
current_organ.removed(src)
for(var/datum/organ/external/E in src.organs)
if(istype(E, /datum/organ/external/chest))
continue
@@ -8,12 +15,8 @@
// Override the current limb status and don't cause an explosion
E.droplimb(1,1)
..(species ? species.gibbed_anim : "gibbed-h")
if(species)
hgibs(loc, viruses, dna, species.flesh_color, species.blood_color)
else
hgibs(loc, viruses, dna)
..(species.gibbed_anim)
gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color)
/mob/living/carbon/human/dust()
if(species)
@@ -65,21 +68,6 @@
return ..(gibbed,species.death_message)
/mob/living/carbon/human/proc/makeSkeleton()
if(SKELETON in src.mutations) return
if(f_style)
f_style = "Shaved"
if(h_style)
h_style = "Bald"
update_hair(0)
mutations.Add(SKELETON)
status_flags |= DISFIGURED
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/ChangeToHusk()
if(HUSK in mutations) return
@@ -92,10 +80,23 @@
mutations.Add(HUSK)
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/Drain()
ChangeToHusk()
//mutations |= NOCLONE
return
/mob/living/carbon/human/proc/ChangeToSkeleton()
if(SKELETON in src.mutations) return
if(f_style)
f_style = "Shaved"
if(h_style)
h_style = "Bald"
update_hair(0)
mutations.Add(SKELETON)
status_flags |= DISFIGURED
update_body(0)
return
@@ -52,7 +52,10 @@
t_his = "her"
t_him = "her"
msg += "<EM>[src.name]</EM>!\n"
msg += "<EM>[src.name]</EM>"
if(species.name != "Human")
msg += ", a <b><font color='[species.flesh_color]'>[species.name]</font></b>"
msg += "!\n"
//uniform
if(w_uniform && !skipjumpsuit)
+23 -11
View File
@@ -38,8 +38,6 @@
if(dna)
dna.real_name = real_name
prev_gender = gender // Debug for plural genders
make_blood()
/mob/living/carbon/human/Stat()
@@ -730,13 +728,8 @@
return
/mob/living/carbon/human/get_species()
if(!species)
set_species()
if(dna && dna.mutantrace == "golem")
return "Animated Construct"
return species.name
/mob/living/carbon/human/proc/play_xylophone()
@@ -756,13 +749,13 @@
if(!lastpuke)
lastpuke = 1
src << "<spawn class='warning'>You feel nauseous..."
src << "<span class='warning'>You feel nauseous...</span>"
spawn(150) //15 seconds until second warning
src << "<spawn class='warning'>You feel like you are about to throw up!"
src << "<span class='warning'>You feel like you are about to throw up!</span>"
spawn(100) //and you have 10 more for mad dash to the bucket
Stun(5)
src.visible_message("<spawn class='warning'>[src] throws up!","<spawn class='warning'>You throw up!")
src.visible_message("<span class='warning'>[src] throws up!</span>","<span class='warning'>You throw up!</span>")
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
var/turf/location = loc
@@ -949,7 +942,11 @@
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
for (var/obj/item/weapon/organ/head/H in world)
// Fix up any missing organs.
// This will ignore any prosthetics in the prefs currently.
species.create_organs(src)
for (var/obj/item/organ/brain/H in world)
if(H.brainmob)
if(H.brainmob.real_name == src.real_name)
if(H.brainmob.mind)
@@ -965,6 +962,9 @@
var/datum/disease2/disease/V = virus2[ID]
V.cure(src)
losebreath = 0
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
..()
/mob/living/carbon/human/proc/is_lung_ruptured()
@@ -1146,6 +1146,13 @@
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
// Rebuild the HUD. If they aren't logged in then login() should reinstantiate it for them.
if(client && client.screen)
client.screen.len = null
if(hud_used)
del(hud_used)
hud_used = new /datum/hud(src)
if(species)
return 1
else
@@ -1286,3 +1293,8 @@
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1
return 0
/mob/living/carbon/human/slip(var/slipped_on, stun_duration=8)
if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP)))
return 0
..(slipped_on,stun_duration)
@@ -230,7 +230,7 @@
return W.afterattack(target,src)
var/randn = rand(1, 100)
if (randn <= 25)
if(!(species.flags & NO_SLIP) && randn <= 25)
apply_effect(3, WEAKEN, run_armor_check(affecting, "melee"))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("\red <B>[M] has pushed [src]!</B>")
+27 -132
View File
@@ -29,7 +29,6 @@
var/co2_alert = 0
var/fire_alert = 0
var/pressure_alert = 0
var/prev_gender = null // Debug for plural genders
var/temperature_alert = 0
var/in_stasis = 0
@@ -44,14 +43,6 @@
..()
/*
//This code is here to try to determine what causes the gender switch to plural error. Once the error is tracked down and fixed, this code should be deleted
//Also delete var/prev_gender once this is removed.
if(prev_gender != gender)
prev_gender = gender
if(gender in list(PLURAL, NEUTER))
message_admins("[src] ([ckey]) gender has been changed to plural or neuter. Please record what has happened recently to the person and then notify coders. (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?priv_msg=\ref[src]'>PM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>)")
*/
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
@@ -94,8 +85,10 @@
//Disabilities
handle_disabilities()
//Organ failure.
//Organs and blood
handle_organs()
handle_blood()
stabilize_body_temperature() //Body temperature adjusts itself (self-regulation)
//Random events (vomiting etc)
handle_random_events()
@@ -927,64 +920,6 @@
return min(1,thermal_protection)
/*
proc/add_fire_protection(var/temp)
var/fire_prot = 0
if(head)
if(head.protective_temperature > temp)
fire_prot += (head.protective_temperature/10)
if(wear_mask)
if(wear_mask.protective_temperature > temp)
fire_prot += (wear_mask.protective_temperature/10)
if(glasses)
if(glasses.protective_temperature > temp)
fire_prot += (glasses.protective_temperature/10)
if(ears)
if(ears.protective_temperature > temp)
fire_prot += (ears.protective_temperature/10)
if(wear_suit)
if(wear_suit.protective_temperature > temp)
fire_prot += (wear_suit.protective_temperature/10)
if(w_uniform)
if(w_uniform.protective_temperature > temp)
fire_prot += (w_uniform.protective_temperature/10)
if(gloves)
if(gloves.protective_temperature > temp)
fire_prot += (gloves.protective_temperature/10)
if(shoes)
if(shoes.protective_temperature > temp)
fire_prot += (shoes.protective_temperature/10)
return fire_prot
proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(nodamage)
return
//world <<"body_part = [body_part], exposed_temperature = [exposed_temperature], exposed_intensity = [exposed_intensity]"
var/discomfort = min(abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
if(exposed_temperature > bodytemperature)
discomfort *= 4
if(mutantrace == "plant")
discomfort *= TEMPERATURE_DAMAGE_COEFFICIENT * 2 //I don't like magic numbers. I'll make mutantraces a datum with vars sometime later. -- Urist
else
discomfort *= TEMPERATURE_DAMAGE_COEFFICIENT //Dangercon 2011 - now with less magic numbers!
//world <<"[discomfort]"
switch(body_part)
if(HEAD)
apply_damage(2.5*discomfort, BURN, "head")
if(UPPER_TORSO)
apply_damage(2.5*discomfort, BURN, "chest")
if(LEGS)
apply_damage(0.6*discomfort, BURN, "l_leg")
apply_damage(0.6*discomfort, BURN, "r_leg")
if(ARMS)
apply_damage(0.4*discomfort, BURN, "l_arm")
apply_damage(0.4*discomfort, BURN, "r_arm")
*/
proc/handle_chemicals_in_body()
if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents.
@@ -1022,7 +957,7 @@
adjustOxyLoss(-(light_amount))
//TODO: heal wounds, heal broken limbs.
if(dna && dna.mutantrace == "shadow")
if(species.light_dam)
var/light_amount = 0
if(isturf(loc))
var/turf/T = loc
@@ -1030,30 +965,11 @@
if(A)
if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount
else light_amount = 10
if(light_amount > 2) //if there's enough light, start dying
if(light_amount > species.light_dam) //if there's enough light, start dying
take_overall_damage(1,1)
else if (light_amount < 2) //heal in the dark
else //heal in the dark
heal_overall_damage(1,1)
/* //The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
if(FAT in mutations)
if(overeatduration < 100)
src << "\blue You feel fit again!"
mutations.Remove(FAT)
update_mutantrace(0)
update_mutations(0)
update_inv_w_uniform(0)
update_inv_wear_suit()
else
if(overeatduration > 500)
src << "\red You suddenly feel blubbery!"
mutations.Add(FAT)
update_mutantrace(0)
update_mutations(0)
update_inv_w_uniform(0)
update_inv_wear_suit()
*/
// nutrition decrease
if (nutrition > 0 && stat != 2)
nutrition = max (0, nutrition - HUNGER_FACTOR)
@@ -1070,22 +986,6 @@
take_overall_damage(2,0)
traumatic_shock++
if (drowsyness)
drowsyness--
eye_blurry = max(2, eye_blurry)
if (prob(5))
sleeping += 1
Paralyse(5)
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 15)
jitteriness = max(0, jitteriness - 15)
else
dizziness = max(0, dizziness - 3)
jitteriness = max(0, jitteriness - 3)
if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems()
updatehealth()
@@ -1101,10 +1001,6 @@
silent = 0
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
if(!in_stasis)
stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized.
handle_blood()
if(health <= config.health_threshold_dead || (species.has_organ["brain"] && !has_brain()))
death()
@@ -1119,13 +1015,6 @@
if( (getOxyLoss() > 50) || (config.health_threshold_crit > health) )
Paralyse(3)
/* Done by handle_breath()
if( health <= 20 && prob(1) )
spawn(0)
emote("gasp")
if(!reagents.has_reagent("inaprovaline"))
adjustOxyLoss(1)*/
if(hallucination)
if(hallucination >= 20)
if(prob(3))
@@ -1168,22 +1057,17 @@
if( prob(2) && health && !hal_crit )
spawn(0)
emote("snore")
else if(resting)
if(halloss > 0)
adjustHalLoss(-3)
//CONSCIOUS
else
stat = CONSCIOUS
if(halloss > 0)
adjustHalLoss(-1)
//Periodically double-check embedded_flag
if(embedded_flag && !(life_tick % 10))
var/list/E
E = get_visible_implants(0)
if(!E.len)
embedded_flag = 0
//Eyes
//Check rig first because it's two-check and other checks will override it.
if(istype(back,/obj/item/weapon/rig))
@@ -1223,9 +1107,28 @@
else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
ear_damage = max(ear_damage-0.05, 0)
//Resting
if(resting)
dizziness = max(0, dizziness - 15)
jitteriness = max(0, jitteriness - 15)
adjustHalLoss(-3)
else
dizziness = max(0, dizziness - 3)
jitteriness = max(0, jitteriness - 3)
adjustHalLoss(-1)
//Other
handle_statuses()
if (drowsyness)
drowsyness--
eye_blurry = max(2, eye_blurry)
if (prob(5))
sleeping += 1
Paralyse(5)
confused = max(0, confused - 1)
// If you're dirty, your gloves will become dirty, too.
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
@@ -1346,14 +1249,6 @@
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
if(dna)
switch(dna.mutantrace)
if("slime")
see_in_dark = 3
see_invisible = SEE_INVISIBLE_LEVEL_ONE
if("shadow")
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_ONE
if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
@@ -1484,7 +1379,7 @@
if(eye_blurry) client.screen += global_hud.blurry
if(druggy) client.screen += global_hud.druggy
if(tinted_weldhelh)
if(config.welder_vision)
var/found_welder
if(istype(glasses, /obj/item/clothing/glasses/welding))
var/obj/item/clothing/glasses/welding/O = glasses
+9 -5
View File
@@ -33,7 +33,7 @@
//parse the language code and consume it
var/datum/language/speaking = parse_language(message)
if(speaking)
message = copytext(message,3)
message = copytext(message,2+length(speaking.key))
else if(species.default_language)
speaking = all_languages[species.default_language]
@@ -55,7 +55,7 @@
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
message = capitalize(trim(message))
message = trim(message)
if(speech_problem_flag)
var/list/handle_r = handle_speech_problems(message)
@@ -132,10 +132,14 @@
if(used_radios.len)
italics = 1
message_range = 1
if(speaking)
message_range = speaking.get_talkinto_msg_range(message)
var/msg
if(!speaking || !(speaking.flags & NO_TALK_MSG))
msg = "<span class='notice'>\The [src] talks into \the [used_radios[1]]</span>"
for(var/mob/living/M in hearers(5, src))
if(M != src)
M.show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "the radio."]</span>")
if((M != src) && msg)
M.show_message(msg)
if (speech_sound)
sound_vol *= 0.5
@@ -1,542 +0,0 @@
/*
Datum-based species. Should make for much cleaner and easier to maintain mutantrace code.
*/
/datum/species
var/name // Species name.
var/name_plural
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/prone_icon // If set, draws this from icobase when mob is prone.
var/eyes = "eyes_s" // Icon for eyes.
var/primitive // Lesser form, if any (ie. monkey for humans)
var/tail // Name of tail image in species effects icon file.
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/datum/hud_data/hud
var/hud_type
var/slowdown = 0
var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species. Only used by ninja and cultists atm.
var/list/unarmed_types = list(/datum/unarmed_attack, /datum/unarmed_attack/bite)
var/language // Default racial language, if any.
// Default language is used when 'say' is used without modifiers.
var/default_language = "Galactic Common"
var/secondary_langs = list() // The names of secondary languages that are available to this species.
var/mutantrace // Safeguard due to old code.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance
var/has_fine_manipulation = 1 // Can use small items.
var/insulated // Immune to electrocution and glass shards to the feet.
// Some species-specific gibbing data.
var/gibbed_anim = "gibbed-h"
var/dusted_anim = "dust-h"
var/remains_type = /obj/effect/decal/remains/xeno
var/death_sound
var/death_message = "seizes up and falls limp, their eyes dead and lifeless..."
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "phoron" // Poisonous air.
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
var/total_health = 100 //Point at which the mob will enter crit.
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 above this point.
var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second
var/reagent_tag //Used for metabolizing reagents.
var/darksight = 2
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/brute_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
var/flags = 0 // Various specific features.
var/list/abilities = list() // For species-derived or admin-given powers
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
var/base_color //Used when setting species.
//Used in icon caching.
var/race_key = 0
var/icon/icon_template
// Species-specific abilities.
var/list/inherent_verbs
var/list/has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes
)
/datum/species/New()
if(hud_type)
hud = new hud_type()
else
hud = new()
unarmed_attacks = list()
for(var/u_type in unarmed_types)
unarmed_attacks += new u_type()
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
//Trying to work out why species changes aren't fixing organs properly.
if(H.organs) H.organs.Cut()
if(H.internal_organs) H.internal_organs.Cut()
if(H.organs_by_name) H.organs_by_name.Cut()
if(H.internal_organs_by_name) H.internal_organs_by_name.Cut()
H.organs = list()
H.internal_organs = list()
H.organs_by_name = list()
H.internal_organs_by_name = list()
//This is a basic humanoid limb setup.
H.organs_by_name["chest"] = new/datum/organ/external/chest()
H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"])
H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"])
H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"])
H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"])
H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"])
H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"])
H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"])
H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"])
H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"])
H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"])
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
H.internal_organs_by_name[organ] = new organ_type(H)
for(var/name in H.organs_by_name)
H.organs += H.organs_by_name[name]
for(var/datum/organ/external/O in H.organs)
O.owner = H
if(flags & IS_SYNTHETIC)
for(var/datum/organ/external/E in H.organs)
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
E.status |= ORGAN_ROBOT
for(var/datum/organ/internal/I in H.internal_organs)
I.mechanize()
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
var/t_him = "them"
switch(target.gender)
if(MALE)
t_him = "him"
if(FEMALE)
t_him = "her"
H.visible_message("<span class='notice'>[H] hugs [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [target] to make [t_him] feel better!</span>")
/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs -= verb_path
return
/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs |= verb_path
return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
add_inherent_verbs(H)
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
if(flags & IS_SYNTHETIC)
H.h_style = ""
spawn(100)
H.update_hair()
return
// Only used for alien plasma weeds atm, but could be used for Dionaea later.
/datum/species/proc/handle_environment_special(var/mob/living/carbon/human/H)
return
// Used to update alien icons for aliens.
/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H)
return
// As above.
/datum/species/proc/handle_logout_special(var/mob/living/carbon/human/H)
return
// Builds the HUD using species-specific icons and usable slots.
/datum/species/proc/build_hud(var/mob/living/carbon/human/H)
return
// Grabs the window recieved when you click-drag someone onto you.
/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H)
return
//Used by xenos understanding larvae and dionaea understanding nymphs.
/datum/species/proc/can_understand(var/mob/other)
return
/datum/species/human
name = "Human"
name_plural = "Humans"
language = "Sol Common"
primitive = /mob/living/carbon/monkey
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
//If you wanted to add a species-level ability:
/*abilities = list(/client/proc/test_ability)*/
/datum/species/unathi
name = "Unathi"
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"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
primitive = /mob/living/carbon/monkey/unathi
darksight = 3
gluttonous = 1
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 130 //Default 120
heat_level_1 = 420 //Default 360 - Higher is better
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
reagent_tag = IS_UNATHI
base_color = "#066000"
/datum/species/tajaran
name = "Tajara"
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"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
darksight = 8
cold_level_1 = 200 //Default 260
cold_level_2 = 140 //Default 200
cold_level_3 = 80 //Default 120
heat_level_1 = 330 //Default 360
heat_level_2 = 380 //Default 400
heat_level_3 = 800 //Default 1000
primitive = /mob/living/carbon/monkey/tajara
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E"
base_color = "#333333"
/datum/species/skrell
name = "Skrell"
name_plural = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
eyes = "skrell_eyes_s"
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
unarmed_types = list(/datum/unarmed_attack/punch)
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
reagent_tag = IS_SKRELL
/datum/species/vox
name = "Vox"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = "Vox-pidgin"
language = "Galactic Common"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 2
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = "nitrogen"
poison_type = "oxygen"
insulated = 1
flags = NO_SCAN | HAS_EYE_COLOR
blood_color = "#2299FC"
flesh_color = "#808D11"
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap
)
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"eyes" = /datum/organ/internal/eyes,
"stack" = /datum/organ/internal/stack/vox
)
/datum/species/vox/armalis
name = "Vox Armalis"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
rarity_value = 10
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
brute_mod = 0.2
burn_mod = 0.2
eyes = "blank_eyes"
breath_type = "nitrogen"
poison_type = "oxygen"
flags = NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR
blood_color = "#2299FC"
flesh_color = "#808D11"
tail = "armalis_tail"
icon_template = 'icons/mob/human_races/r_armalis.dmi'
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/commune
)
/datum/species/diona
name = "Diona"
name_plural = "Dionaea"
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/diona)
primitive = /mob/living/carbon/alien/diona
slowdown = 7
rarity_value = 3
has_organ = list(
"nutrient channel" = /datum/organ/internal/diona/nutrients,
"neural strata" = /datum/organ/internal/diona/strata,
"response node" = /datum/organ/internal/diona/node,
"gas bladder" = /datum/organ/internal/diona/bladder,
"polyp segment" = /datum/organ/internal/diona/polyp,
"anchoring ligament" = /datum/organ/internal/diona/ligament
)
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR
blood_color = "#004400"
flesh_color = "#907E4A"
reagent_tag = IS_DIONA
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/carbon/alien/diona/D = other
if(istype(D))
return 1
return 0
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
var/mob/living/carbon/alien/diona/S = new(get_turf(H))
if(H.mind)
H.mind.transfer_to(S)
for(var/mob/living/carbon/alien/diona/D in H.contents)
if(D.client)
D.loc = H.loc
else
del(D)
H.visible_message("\red[H] splits apart with a wet slithering noise!")
/datum/species/machine
name = "Machine"
name_plural = "machines"
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
language = "Tradeband"
unarmed_types = list(/datum/unarmed_attack/punch)
rarity_value = 2
eyes = "blank_eyes"
brute_mod = 0.5
burn_mod = 1
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
heat_level_2 = 1000
heat_level_3 = 2000
synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
blood_color = "#1F181F"
flesh_color = "#575757"
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain,
)
// Called when using the shredding behavior.
/datum/species/proc/can_shred(var/mob/living/carbon/human/H)
if(H.a_intent != "hurt")
return 0
for(var/datum/unarmed_attack/attack in unarmed_attacks)
if(!attack.is_usable(H))
continue
if(attack.shredding)
return 1
return 0
/datum/hud_data
var/icon // If set, overrides ui_style.
var/has_a_intent = 1 // Set to draw intent box.
var/has_m_intent = 1 // Set to draw move intent box.
var/has_warnings = 1 // Set to draw environment warnings.
var/has_pressure = 1 // Draw the pressure indicator.
var/has_nutrition = 1 // Draw the nutrition indicator.
var/has_bodytemp = 1 // Draw the bodytemp indicator.
var/has_hands = 1 // Set to draw shand.
var/has_drop = 1 // Set to draw drop button.
var/has_throw = 1 // Set to draw throw button.
var/has_resist = 1 // Set to draw resist button.
var/has_internals = 1 // Set to draw the internals toggle button.
var/list/equip_slots = list() // Checked by mob_can_equip().
// Contains information on the position and tag for all inventory slots
// to be drawn for the mob. This is fairly delicate, try to avoid messing with it
// unless you know exactly what it does.
var/list/gear = list(
"i_clothing" = list("loc" = ui_iclothing, "slot" = slot_w_uniform, "state" = "center", "toggle" = 1, "dir" = SOUTH),
"o_clothing" = list("loc" = ui_oclothing, "slot" = slot_wear_suit, "state" = "equip", "toggle" = 1, "dir" = SOUTH),
"mask" = list("loc" = ui_mask, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH),
"gloves" = list("loc" = ui_gloves, "slot" = slot_gloves, "state" = "gloves", "toggle" = 1),
"eyes" = list("loc" = ui_glasses, "slot" = slot_glasses, "state" = "glasses","toggle" = 1),
"l_ear" = list("loc" = ui_l_ear, "slot" = slot_l_ear, "state" = "ears", "toggle" = 1),
"r_ear" = list("loc" = ui_r_ear, "slot" = slot_r_ear, "state" = "ears", "toggle" = 1),
"head" = list("loc" = ui_head, "slot" = slot_head, "state" = "hair", "toggle" = 1),
"shoes" = list("loc" = ui_shoes, "slot" = slot_shoes, "state" = "shoes", "toggle" = 1),
"suit storage" = list("loc" = ui_sstore1, "slot" = slot_s_store, "state" = "belt", "dir" = 8),
"back" = list("loc" = ui_back, "slot" = slot_back, "state" = "back", "dir" = NORTH),
"id" = list("loc" = ui_id, "slot" = slot_wear_id, "state" = "id", "dir" = NORTH),
"storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"),
"belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt")
)
/datum/hud_data/New()
..()
for(var/slot in gear)
equip_slots |= gear[slot]["slot"]
if(has_hands)
equip_slots |= slot_l_hand
equip_slots |= slot_r_hand
equip_slots |= slot_handcuffed
if(slot_back in equip_slots)
equip_slots |= slot_in_backpack
if(slot_w_uniform in equip_slots)
equip_slots |= slot_tie
equip_slots |= slot_legcuffed
@@ -0,0 +1,25 @@
/datum/species/shadow
name = "Shadow"
name_plural = "shadows"
icobase = 'icons/mob/human_races/r_shadow.dmi'
deform = 'icons/mob/human_races/r_shadow.dmi'
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/sharp)
light_dam = 2
darksight = 8
has_organ = list()
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
remains_type = /obj/effect/decal/cleanable/ash
death_message = "dissolves into ash..."
flags = IS_RESTRICTED | NO_BLOOD | NO_POISON | NO_SCAN | NO_SLIP | NO_POISON
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)
new /obj/effect/decal/cleanable/ash(H.loc)
del(H)
@@ -0,0 +1,97 @@
/datum/species/vox
name = "Vox"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = "Vox-pidgin"
language = "Galactic Common"
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 \
scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \
alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \
refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \
smell.<br/><br/>Most humans will never meet a Vox raider, instead learning of this insular species through \
dealing with their traders and merchants; those that do rarely enjoy the experience."
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = "nitrogen"
poison_type = "oxygen"
insulated = 1
flags = IS_WHITELISTED | NO_SCAN | HAS_EYE_COLOR
blood_color = "#2299FC"
flesh_color = "#808D11"
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap
)
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"eyes" = /datum/organ/internal/eyes,
"stack" = /datum/organ/internal/stack/vox
)
/datum/species/vox/get_random_name(var/gender)
var/datum/language/species_language = all_languages[default_language]
return species_language.get_random_name(gender)
/datum/species/vox/armalis
name = "Vox Armalis"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
rarity_value = 10
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
brute_mod = 0.2
burn_mod = 0.2
eyes = "blank_eyes"
breath_type = "nitrogen"
poison_type = "oxygen"
flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR
blood_color = "#2299FC"
flesh_color = "#808D11"
tail = "armalis_tail"
icon_template = 'icons/mob/human_races/r_armalis.dmi'
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/commune
)
@@ -0,0 +1,217 @@
/*
Datum-based species. Should make for much cleaner and easier to maintain race code.
*/
/datum/species
// Descriptors and strings.
var/name // Species name.
var/name_plural // Pluralized name (since "[name]s" is not always valid)
var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen.
// Icon/appearance vars.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/prone_icon // If set, draws this from icobase when mob is prone.
var/eyes = "eyes_s" // Icon for eyes.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previes..
var/tail // Name of tail image in species effects icon file.
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
// 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/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance // The likelihood of a speech sound playing.
// Combat vars.
var/total_health = 100 // Point at which the mob will enter crit.
var/list/unarmed_types = list( // Possible unarmed attacks that the mob will use in combat.
/datum/unarmed_attack,
/datum/unarmed_attack/bite
)
var/list/unarmed_attacks = null // For empty hand harm-intent attack
var/brute_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
// Death vars.
var/gibber_type = /obj/effect/gibspawner/human
var/remains_type = /obj/effect/decal/remains/xeno
var/gibbed_anim = "gibbed-h"
var/dusted_anim = "dust-h"
var/death_sound
var/death_message = "seizes up and falls limp, their eyes dead and lifeless..."
// Environment tolerance/life processes vars.
var/reagent_tag //Used for metabolizing reagents.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "phoron" // Poisonous air.
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 above this point.
var/synth_temp_gain = 0 // IS_SYNTHETIC species will gain this much temperature every second
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative.
var/body_temperature = 310.15 // Non-IS_SYNTHETIC species will try to stabilize at this temperature.
// (also affects temperature processing)
// HUD data vars.
var/datum/hud_data/hud
var/hud_type
// Body/form vars.
var/list/inherent_verbs // Species-specific verbs.
var/has_fine_manipulation = 1 // Can use small items.
var/insulated // Immune to electrocution and glass shards to the feet.
var/darksight = 2 // Native darksight distance.
var/flags = 0 // Various specific features.
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/primitive // Lesser form, if any (ie. monkey for humans)
var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species.
// Determines the organs that the species spawns with and
var/list/has_organ = list( // which required-organ checks are conducted.
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes
)
/datum/species/New()
if(hud_type)
hud = new hud_type()
else
hud = new()
unarmed_attacks = list()
for(var/u_type in unarmed_types)
unarmed_attacks += new u_type()
/datum/species/proc/get_random_name(var/gender)
var/datum/language/species_language = all_languages[language]
return species_language.get_random_name(gender)
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
//Trying to work out why species changes aren't fixing organs properly.
if(H.organs) H.organs.Cut()
if(H.internal_organs) H.internal_organs.Cut()
if(H.organs_by_name) H.organs_by_name.Cut()
if(H.internal_organs_by_name) H.internal_organs_by_name.Cut()
H.organs = list()
H.internal_organs = list()
H.organs_by_name = list()
H.internal_organs_by_name = list()
//This is a basic humanoid limb setup.
H.organs_by_name["chest"] = new/datum/organ/external/chest()
H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"])
H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"])
H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"])
H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"])
H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"])
H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"])
H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"])
H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"])
H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"])
H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"])
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
H.internal_organs_by_name[organ] = new organ_type(H)
for(var/name in H.organs_by_name)
H.organs += H.organs_by_name[name]
for(var/datum/organ/external/O in H.organs)
O.owner = H
if(flags & IS_SYNTHETIC)
for(var/datum/organ/external/E in H.organs)
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
E.status |= ORGAN_ROBOT
for(var/datum/organ/internal/I in H.internal_organs)
I.mechanize()
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
var/t_him = "them"
switch(target.gender)
if(MALE)
t_him = "him"
if(FEMALE)
t_him = "her"
H.visible_message("<span class='notice'>[H] hugs [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [target] to make [t_him] feel better!</span>")
/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs -= verb_path
return
/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs |= verb_path
return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
add_inherent_verbs(H)
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
return
// Only used for alien plasma weeds atm, but could be used for Dionaea later.
/datum/species/proc/handle_environment_special(var/mob/living/carbon/human/H)
return
// Used to update alien icons for aliens.
/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H)
return
// As above.
/datum/species/proc/handle_logout_special(var/mob/living/carbon/human/H)
return
// Builds the HUD using species-specific icons and usable slots.
/datum/species/proc/build_hud(var/mob/living/carbon/human/H)
return
// Grabs the window recieved when you click-drag someone onto you.
/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H)
return
//Used by xenos understanding larvae and dionaea understanding nymphs.
/datum/species/proc/can_understand(var/mob/other)
return
// Called when using the shredding behavior.
/datum/species/proc/can_shred(var/mob/living/carbon/human/H)
if(H.a_intent != "hurt")
return 0
for(var/datum/unarmed_attack/attack in unarmed_attacks)
if(!attack.is_usable(H))
continue
if(attack.shredding)
return 1
return 0
@@ -0,0 +1,263 @@
//Species unarmed attacks
/datum/unarmed_attack
var/attack_verb = list("attack") // Empty hand hurt intent verb.
var/attack_noun = list("fist")
var/damage = 0 // Extra empty hand attack damage.
var/attack_sound = "punch"
var/miss_sound = 'sound/weapons/punchmiss.ogg'
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
if(user.restrained())
return 0
// Check if they have a functioning hand.
var/datum/organ/external/E = user.organs_by_name["l_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
var/stun_chance = rand(0, 100)
if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
switch(zone) // strong punches can have effects depending on where they hit
if("head", "mouth", "eyes")
// Induce blurriness
target.visible_message("<span class='danger'>[target] looks dazed.</span>", "<span class='danger'>You see stars.</span>")
target.apply_effect(attack_damage*2, EYE_BLUR, armour)
if("l_arm", "l_hand")
if (target.l_hand)
// Disarm left hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!</span>")
target.drop_l_hand()
if("r_arm", "r_hand")
if (target.r_hand)
// Disarm right hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!</span>")
target.drop_r_hand()
if("chest")
if(!target.lying)
var/turf/T = get_step(get_turf(target), get_dir(get_turf(user), get_turf(target)))
if(!T.density)
step(target, get_dir(get_turf(user), get_turf(target)))
target.visible_message("<span class='danger'>[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]</span>")
else
target.visible_message("<span class='danger'>[target] slams into [T]!</span>")
if(prob(50))
target.set_dir(reverse_dir[target.dir])
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if("groin")
target.visible_message("<span class='warning'>[target] looks like \he is in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>")
target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour)
if("l_leg", "l_foot", "r_leg", "r_foot")
if(!target.lying)
target.visible_message("<span class='warning'>[src] gives way slightly.</span>")
target.apply_effect(attack_damage*3, AGONY, armour)
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance)
if(!target.lying)
target.visible_message("<span class='danger'>[target] [pick("slumps", "falls", "drops")] down to the ground!</span>")
else
target.visible_message("<span class='danger'>[target] has been weakened!</span>")
target.apply_effect(3, WEAKEN, armour)
/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.display_name]!</span>")
playsound(user.loc, attack_sound, 25, 1, -1)
/datum/unarmed_attack/bite
attack_verb = list("bit")
attack_sound = 'sound/weapons/bite.ogg'
shredding = 0
damage = 0
sharp = 0
edge = 0
/datum/unarmed_attack/bite/sharp //eye teeth
attack_verb = list("bit", "chomped on")
attack_sound = 'sound/weapons/bite.ogg'
shredding = 0
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
return 0
if (user == target && (zone == "head" || zone == "eyes" || zone == "mouth"))
return 0
return 1
/datum/unarmed_attack/punch
attack_verb = list("punched")
attack_noun = list("fist")
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)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case.
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [organ]!</span>")
return 0
if(!target.lying)
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>")
if(5) user.visible_message("<span class='danger'>[user] gave [target] a resounding slap to the face!</span>")
if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_let", "l_foot", "r_foot")
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target]'s [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!</span>")
else
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>")
/datum/unarmed_attack/kick
attack_verb = list("kicked", "kneed")
attack_noun = list("kick")
attack_sound = "swing_hit"
damage = 1
/datum/unarmed_attack/kick/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (target.legcuffed)
return 0
if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin")))
return 0
var/datum/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
attack_damage = Clamp(attack_damage, 1, 5)
switch(zone)
if("groin", "l_leg", "r_leg")
// -- LOWER BODY -- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] gave [target] a light [pick(attack_noun)] to the [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!</span>")
if("l_foot", "r_foot")
// ----- FEET ----- //
switch(attack_damage)
if(1 to 4) user.visible_message("<span class='danger'>[user] kicked [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] stomped down hard on [target]'s [organ]!</span>")
/datum/unarmed_attack/stomp
attack_verb = null
attack_noun = list("kick")
attack_sound = "swing_hit"
damage = 3
/datum/unarmed_attack/stomp/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (target.legcuffed)
return 0
if (target.lying && !user.lying)
var/datum/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
attack_damage = Clamp(attack_damage, 1, 5)
switch(attack_damage)
if(1 to 3)
user.visible_message("<span class='danger'>[user] [pick("gave a kick against", "kicked against", "stomped down on", "slammed their foot into")] [target]'s [organ]!</span>")
if(4 to 5)
user.visible_message("<span class='danger'>[user] [pick("landed a strong kick against", "kicked against", "stomped down hard on", "rammed their foot into")] [target]'s [organ]!</span>")
/datum/unarmed_attack/diona
attack_verb = list("lashed", "bludgeoned")
attack_noun = list("tendril")
damage = 5
/datum/unarmed_attack/claws
attack_verb = list("scratched", "clawed", "slashed")
attack_noun = list("claws")
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/skill = user.skills["combat"]
var/datum/organ/external/affecting = target.get_organ(zone)
if(!skill) skill = 1
attack_damage = Clamp(attack_damage, 1, 5)
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.display_name]!</span>")
return 0
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]</span>")
if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot")
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target]'s [affecting.display_name]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!</span>")
/datum/unarmed_attack/claws/strong
attack_verb = list("slash")
damage = 10
shredding = 1
/datum/unarmed_attack/bite/strong
attack_verb = list("maul")
damage = 15
shredding = 1
/datum/unarmed_attack/slime_glomp
attack_verb = list("glomped")
attack_noun = list("body")
damage = 0
/datum/unarmed_attack/slime_glomp/apply_effects()
//Todo, maybe have a chance of causing an electrical shock?
return
@@ -0,0 +1,53 @@
/datum/hud_data
var/icon // If set, overrides ui_style.
var/has_a_intent = 1 // Set to draw intent box.
var/has_m_intent = 1 // Set to draw move intent box.
var/has_warnings = 1 // Set to draw environment warnings.
var/has_pressure = 1 // Draw the pressure indicator.
var/has_nutrition = 1 // Draw the nutrition indicator.
var/has_bodytemp = 1 // Draw the bodytemp indicator.
var/has_hands = 1 // Set to draw shand.
var/has_drop = 1 // Set to draw drop button.
var/has_throw = 1 // Set to draw throw button.
var/has_resist = 1 // Set to draw resist button.
var/has_internals = 1 // Set to draw the internals toggle button.
var/list/equip_slots = list() // Checked by mob_can_equip().
// Contains information on the position and tag for all inventory slots
// to be drawn for the mob. This is fairly delicate, try to avoid messing with it
// unless you know exactly what it does.
var/list/gear = list(
"i_clothing" = list("loc" = ui_iclothing, "slot" = slot_w_uniform, "state" = "center", "toggle" = 1, "dir" = SOUTH),
"o_clothing" = list("loc" = ui_oclothing, "slot" = slot_wear_suit, "state" = "equip", "toggle" = 1, "dir" = SOUTH),
"mask" = list("loc" = ui_mask, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH),
"gloves" = list("loc" = ui_gloves, "slot" = slot_gloves, "state" = "gloves", "toggle" = 1),
"eyes" = list("loc" = ui_glasses, "slot" = slot_glasses, "state" = "glasses","toggle" = 1),
"l_ear" = list("loc" = ui_l_ear, "slot" = slot_l_ear, "state" = "ears", "toggle" = 1),
"r_ear" = list("loc" = ui_r_ear, "slot" = slot_r_ear, "state" = "ears", "toggle" = 1),
"head" = list("loc" = ui_head, "slot" = slot_head, "state" = "hair", "toggle" = 1),
"shoes" = list("loc" = ui_shoes, "slot" = slot_shoes, "state" = "shoes", "toggle" = 1),
"suit storage" = list("loc" = ui_sstore1, "slot" = slot_s_store, "state" = "belt", "dir" = 8),
"back" = list("loc" = ui_back, "slot" = slot_back, "state" = "back", "dir" = NORTH),
"id" = list("loc" = ui_id, "slot" = slot_wear_id, "state" = "id", "dir" = NORTH),
"storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"),
"belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt")
)
/datum/hud_data/New()
..()
for(var/slot in gear)
equip_slots |= gear[slot]["slot"]
if(has_hands)
equip_slots |= slot_l_hand
equip_slots |= slot_r_hand
equip_slots |= slot_handcuffed
if(slot_back in equip_slots)
equip_slots |= slot_in_backpack
if(slot_w_uniform in equip_slots)
equip_slots |= slot_tie
equip_slots |= slot_legcuffed
@@ -0,0 +1,30 @@
/datum/species/golem
name = "Golem"
name_plural = "golems"
icobase = 'icons/mob/human_races/r_golem.dmi'
deform = 'icons/mob/human_races/r_golem.dmi'
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch)
flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | IS_SYNTHETIC | NO_SCAN | NO_POISON
breath_type = null
poison_type = null
blood_color = "#515573"
flesh_color = "#137E8F"
has_organ = list(
"brain" = /datum/organ/internal/brain/golem
)
death_message = "becomes completely motionless..."
/datum/species/golem/handle_post_spawn(var/mob/living/carbon/human/H)
if(H.mind)
H.mind.assigned_role = "Golem"
H.mind.special_role = "Golem"
H.real_name = "adamantine golem ([rand(1, 1000)])"
H.name = H.real_name
..()
@@ -0,0 +1,24 @@
/datum/species/slime
name = "Slime"
name_plural = "slimes"
icobase = 'icons/mob/human_races/r_slime.dmi'
deform = 'icons/mob/human_races/r_slime.dmi'
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
flags = IS_RESTRICTED | NO_BLOOD | NO_SCAN | NO_SLIP | NO_BREATHE
darksight = 3
blood_color = "#05FF9B"
flesh_color = "#05FFFB"
has_organ = list(
"brain" = /datum/organ/internal/brain/slime
)
inherent_verbs = list(
)
breath_type = null
poison_type = null
@@ -0,0 +1,211 @@
/datum/species/human
name = "Human"
name_plural = "Humans"
language = "Sol Common"
primitive = /mob/living/carbon/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 \
colonies across a wide swathe of space. They hold a wide range of forms and creeds.<br/><br/> \
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."
flags = CAN_JOIN | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
/datum/species/unathi
name = "Unathi"
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"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
primitive = /mob/living/carbon/monkey/unathi
darksight = 3
gluttonous = 1
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 \
desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \
else, frequently even their own lives. They prefer warmer temperatures than most species and \
their native tongue is a heavy hissing laungage called Sinta'Unathi."
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 130 //Default 120
heat_level_1 = 420 //Default 360 - Higher is better
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
reagent_tag = IS_UNATHI
base_color = "#066000"
/datum/species/tajaran
name = "Tajara"
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"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
darksight = 8
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 \
influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \
of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \
using unique inflections their mouths form."
cold_level_1 = 200 //Default 260
cold_level_2 = 140 //Default 200
cold_level_3 = 80 //Default 120
heat_level_1 = 330 //Default 360
heat_level_2 = 380 //Default 400
heat_level_3 = 800 //Default 1000
primitive = /mob/living/carbon/monkey/tajara
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E"
base_color = "#333333"
/datum/species/skrell
name = "Skrell"
name_plural = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
eyes = "skrell_eyes_s"
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
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 \
the royals' or 'Light of the Crown'.<br/><br/>Skrell are a highly advanced and logical race who live under the rule \
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."
flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
reagent_tag = IS_SKRELL
/datum/species/diona
name = "Diona"
name_plural = "Dionaea"
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/diona)
primitive = /mob/living/carbon/alien/diona
slowdown = 7
rarity_value = 3
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \
Minoris primary being ringed with a cloud of singing space-station-sized entities.<br/><br/>The Dionaea coexist peacefully with \
all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \
even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \
water and other radiation."
has_organ = list(
"nutrient channel" = /datum/organ/internal/diona/nutrients,
"neural strata" = /datum/organ/internal/diona/strata,
"response node" = /datum/organ/internal/diona/node,
"gas bladder" = /datum/organ/internal/diona/bladder,
"polyp segment" = /datum/organ/internal/diona/polyp,
"anchoring ligament" = /datum/organ/internal/diona/ligament
)
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR
blood_color = "#004400"
flesh_color = "#907E4A"
reagent_tag = IS_DIONA
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/carbon/alien/diona/D = other
if(istype(D))
return 1
return 0
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
var/mob/living/carbon/alien/diona/S = new(get_turf(H))
if(H.mind)
H.mind.transfer_to(S)
for(var/mob/living/carbon/alien/diona/D in H.contents)
if(D.client)
D.loc = H.loc
else
del(D)
H.visible_message("\red[H] splits apart with a wet slithering noise!")
/datum/species/machine
name = "Machine"
name_plural = "machines"
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
language = "Tradeband"
unarmed_types = list(/datum/unarmed_attack/punch)
rarity_value = 2
eyes = "blank_eyes"
brute_mod = 0.5
burn_mod = 1
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
heat_level_2 = 1000
heat_level_3 = 2000
synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
blood_color = "#1F181F"
flesh_color = "#575757"
has_organ = list() //TODO: Positronic brain.
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
..()
if(flags & IS_SYNTHETIC)
H.h_style = ""
spawn(100)
if(H) H.update_hair()
@@ -38,7 +38,7 @@ var/const/MAX_ACTIVE_TIME = 400
Attach(M)
/obj/item/clothing/mask/facehugger/New()
if(aliens_allowed)
if(config.aliens_allowed)
..()
else
del(src)
@@ -83,7 +83,7 @@
set desc = "Lay an egg to produce huggers to impregnate prey with."
set category = "Abilities"
if(!aliens_allowed)
if(!config.aliens_allowed)
src << "You begin to lay an egg, but hesitate. You suspect it isn't allowed."
verbs -= /mob/living/carbon/human/proc/lay_egg
return
@@ -25,7 +25,7 @@
cold_level_2 = -1
cold_level_3 = -1
flags = NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON
flags = IS_RESTRICTED | NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON
reagent_tag = IS_XENOS
@@ -1,261 +0,0 @@
//Species unarmed attacks
/datum/unarmed_attack
var/attack_verb = list("attack") // Empty hand hurt intent verb.
var/attack_noun = list("fist")
var/damage = 0 // Extra empty hand attack damage.
var/attack_sound = "punch"
var/miss_sound = 'sound/weapons/punchmiss.ogg'
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
if(user.restrained())
return 0
// Check if they have a functioning hand.
var/datum/organ/external/E = user.organs_by_name["l_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/proc/get_unarmed_damage()
return damage
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
var/stun_chance = rand(0, 100)
if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
switch(zone) // strong punches can have effects depending on where they hit
if("head", "mouth", "eyes")
// Induce blurriness
target.visible_message("<span class='danger'>[target] looks dazed.</span>", "<span class='danger'>You see stars.</span>")
target.apply_effect(attack_damage*2, EYE_BLUR, armour)
if("l_arm", "l_hand")
if (target.l_hand)
// Disarm left hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!</span>")
target.drop_l_hand()
if("r_arm", "r_hand")
if (target.r_hand)
// Disarm right hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!</span>")
target.drop_r_hand()
if("chest")
if(!target.lying)
var/turf/T = get_step(get_turf(target), get_dir(get_turf(user), get_turf(target)))
if(!T.density)
step(target, get_dir(get_turf(user), get_turf(target)))
target.visible_message("<span class='danger'>[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]</span>")
else
target.visible_message("<span class='danger'>[target] slams into [T]!</span>")
if(prob(50))
target.set_dir(reverse_dir[target.dir])
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if("groin")
target.visible_message("<span class='warning'>[target] looks like \he is in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>")
target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour)
if("l_leg", "l_foot", "r_leg", "r_foot")
if(!target.lying)
target.visible_message("<span class='warning'>[src] gives way slightly.</span>")
target.apply_effect(attack_damage*3, AGONY, armour)
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance)
if(!target.lying)
target.visible_message("<span class='danger'>[target] [pick("slumps", "falls", "drops")] down to the ground!</span>")
else
target.visible_message("<span class='danger'>[target] has been weakened!</span>")
target.apply_effect(3, WEAKEN, armour)
/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.display_name]!</span>")
playsound(user.loc, attack_sound, 25, 1, -1)
/datum/unarmed_attack/bite
attack_verb = list("bit")
attack_sound = 'sound/weapons/bite.ogg'
shredding = 0
damage = 0
sharp = 0
edge = 0
/datum/unarmed_attack/bite/sharp //eye teeth
attack_verb = list("bit", "chomped on")
attack_sound = 'sound/weapons/bite.ogg'
shredding = 0
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
return 0
if (user == target && (zone == "head" || zone == "eyes" || zone == "mouth"))
return 0
return 1
/datum/unarmed_attack/punch
attack_verb = list("punched")
attack_noun = list("fist")
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)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case.
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [organ]!</span>")
return 0
if(!target.lying)
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>")
if(5) user.visible_message("<span class='danger'>[user] gave [target] a resounding slap to the face!</span>")
if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_let", "l_foot", "r_foot")
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target]'s [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!</span>")
else
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>")
/datum/unarmed_attack/kick
attack_verb = list("kicked", "kneed")
attack_noun = list("kick", "knee strike")
attack_sound = "swing_hit"
damage = 0
/datum/unarmed_attack/kick/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (user.legcuffed)
return 0
if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin")))
return 0
var/datum/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/kick/get_unarmed_damage(var/mob/living/carbon/human/user)
var/obj/item/clothing/shoes = user.shoes
if(!istype(shoes))
return damage
return damage + (shoes ? shoes.unarmed_damage : 0)
/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
attack_damage = Clamp(attack_damage, 1, 5)
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] gave [target] a light [pick(attack_noun)] to the [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!</span>")
/datum/unarmed_attack/stomp
attack_verb = null
attack_noun = list("kick")
attack_sound = "swing_hit"
damage = 0
/datum/unarmed_attack/stomp/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (user.legcuffed)
return 0
if (!user.lying && (target.lying || zone in list("l_foot", "r_foot")))
if(target.grabbed_by == user && target.lying)
return 0
var/datum/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/stomp/get_unarmed_damage(var/mob/living/carbon/human/user)
var/obj/item/clothing/shoes = user.shoes
return damage + (shoes ? shoes.unarmed_damage : 0)
/datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/datum/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.display_name
var/obj/item/clothing/shoes = user.shoes
attack_damage = Clamp(attack_damage, 1, 5)
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] [pick("clomped on", "treaded on")] [target]'s [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick("stomped down on", "slammed their [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] [pick("landed a devastating stomp on", "stomped down hard on", "slammed their [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>")
/datum/unarmed_attack/diona
attack_verb = list("lashed", "bludgeoned")
attack_noun = list("tendril")
damage = 5
/datum/unarmed_attack/claws
attack_verb = list("scratched", "clawed", "slashed")
attack_noun = list("claws")
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/skill = user.skills["combat"]
var/datum/organ/external/affecting = target.get_organ(zone)
if(!skill) skill = 1
attack_damage = Clamp(attack_damage, 1, 5)
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.display_name]!</span>")
return 0
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]</span>")
if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot")
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target]'s [affecting.display_name]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!</span>")
/datum/unarmed_attack/claws/strong
attack_verb = list("slash")
damage = 10
shredding = 1
/datum/unarmed_attack/bite/strong
attack_verb = list("maul")
damage = 15
shredding = 1
@@ -68,7 +68,6 @@ There are several things that need to be remembered:
> There are also these special cases:
update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows
update_mutantrace() //handles updating your appearance after setting the mutantrace var
UpdateDamageIcon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it)
update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
@@ -106,30 +105,29 @@ Please contact me on #coderbus IRC. ~Carn x
*/
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1
#define MUTATIONS_LAYER 2
#define DAMAGE_LAYER 3
#define UNIFORM_LAYER 4
#define TAIL_LAYER 5 //bs12 specific. this hack is probably gonna come back to haunt me
#define ID_LAYER 6
#define SHOES_LAYER 7
#define GLOVES_LAYER 8
#define SUIT_LAYER 9
#define GLASSES_LAYER 10
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 12
#define BACK_LAYER 13
#define HAIR_LAYER 14 //TODO: make part of head layer?
#define EARS_LAYER 15
#define FACEMASK_LAYER 16
#define HEAD_LAYER 17
#define COLLAR_LAYER 18
#define HANDCUFF_LAYER 19
#define LEGCUFF_LAYER 20
#define L_HAND_LAYER 21
#define R_HAND_LAYER 22
#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 23
#define MUTATIONS_LAYER 1
#define DAMAGE_LAYER 2
#define UNIFORM_LAYER 3
#define TAIL_LAYER 4 //bs12 specific. this hack is probably gonna come back to haunt me
#define ID_LAYER 5
#define SHOES_LAYER 6
#define GLOVES_LAYER 7
#define SUIT_LAYER 8
#define GLASSES_LAYER 9
#define BELT_LAYER 10 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 11
#define BACK_LAYER 12
#define HAIR_LAYER 13 //TODO: make part of head layer?
#define EARS_LAYER 14
#define FACEMASK_LAYER 15
#define HEAD_LAYER 16
#define COLLAR_LAYER 17
#define HANDCUFF_LAYER 18
#define LEGCUFF_LAYER 19
#define L_HAND_LAYER 20
#define R_HAND_LAYER 21
#define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 22
//////////////////////////////////
/mob/living/carbon/human
@@ -271,8 +269,6 @@ proc/get_damage_icon_part(damage_state, body_part)
else
//BEGIN CACHED ICON GENERATION.
// Why don't we just make skeletons/shadows/golems a species? ~Z
var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
@@ -478,26 +474,6 @@ proc/get_damage_icon_part(damage_state, body_part)
overlays_standing[MUTATIONS_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1)
var/fat
if( FAT in mutations )
fat = "fat"
if(dna)
switch(dna.mutantrace)
if("golem","slime","shadow","adamantine")
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
else
overlays_standing[MUTANTRACE_LAYER] = null
if(!dna || !(dna.mutantrace in list("golem","metroid")))
update_body(0)
update_hair(0)
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
@@ -514,8 +490,10 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/regenerate_icons()
..()
if(monkeyizing) return
update_mutations(0)
update_mutantrace(0)
update_body(0)
update_hair(0)
update_inv_w_uniform(0)
update_inv_wear_id(0)
update_inv_gloves(0)
@@ -972,7 +950,6 @@ proc/get_damage_icon_part(damage_state, body_part)
return face_lying_image
//Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
@@ -29,7 +29,7 @@
//parse the language code and consume it
var/datum/language/speaking = parse_language(message)
if (speaking)
message = copytext(message,3)
message = copytext(message,2+length(speaking.key))
whisper_say(message, speaking, alt_name)
@@ -49,7 +49,7 @@
else
var/adverb = pick("quietly", "softly")
verb = "[speaking.speech_verb] [adverb]"
not_heard = "[verb] something [adverb]"
not_heard = "[speaking.speech_verb] something [adverb]"
else
not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null
@@ -126,7 +126,7 @@
for (var/obj/O in view(message_range, src))
spawn (0)
if (O)
O.hear_talk(src, message) //O.hear_talk(src, message, verb, speaking)
O.hear_talk(src, message, verb, speaking)
var/list/eavesdropping = hearers(eavesdropping_range, src)
eavesdropping -= src
@@ -342,9 +342,8 @@
if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
if(H.dna)
if(H.dna.mutantrace == "slime")
continue
if(H.species.name == "Slime")
continue
if(!L.canmove) // Only one slime can latch on at a time.
var/notarget = 0
@@ -575,3 +574,6 @@
if (Leader) return 0
if (holding_still) return 0
return 1
/mob/living/carbon/slime/slip() //Can't slip something without legs.
return 0
@@ -678,90 +678,6 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
target.enahnced = 1
del(src)*/
////////Adamantine Golem stuff I dunno where else to put it
// This will eventually be removed.
/obj/item/clothing/under/golem
name = "adamantine skin"
desc = "a golem's skin"
icon_state = "golem"
item_state = "golem"
item_color = "golem"
has_sensor = 0
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
canremove = 0
/obj/item/clothing/suit/golem
name = "adamantine shell"
desc = "a golem's thick outter shell"
icon_state = "golem"
item_state = "golem"
w_class = 4//bulky item
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD
slowdown = 1.0
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
flags = FPRINT | TABLEPASS | ONESIZEFITSALL | STOPSPRESSUREDMAGE
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
canremove = 0
armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/shoes/golem
name = "golem's feet"
desc = "sturdy adamantine feet"
icon_state = "golem"
item_state = null
canremove = 0
flags = NOSLIP
slowdown = SHOES_SLOWDOWN+1
/obj/item/clothing/mask/gas/golem
name = "golem's face"
desc = "the imposing face of an adamantine golem"
icon_state = "golem"
item_state = "golem"
canremove = 0
siemens_coefficient = 0
unacidable = 1
/obj/item/clothing/mask/gas/golem
name = "golem's face"
desc = "the imposing face of an adamantine golem"
icon_state = "golem"
item_state = "golem"
canremove = 0
siemens_coefficient = 0
unacidable = 1
/obj/item/clothing/gloves/golem
name = "golem's hands"
desc = "strong adamantine hands"
icon_state = "golem"
item_state = null
siemens_coefficient = 0
canremove = 0
/obj/item/clothing/head/space/golem
icon_state = "golem"
item_state = "dermal"
item_color = "dermal"
name = "golem's head"
desc = "a golem's head"
canremove = 0
unacidable = 1
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE
heat_protection = HEAD
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0)
/obj/effect/golemrune
anchored = 1
desc = "a strange rune used to create golems. It glows when spirits are nearby."
@@ -797,16 +713,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(!ghost)
user << "The rune fizzles uselessly. There is no spirit nearby."
return
var/mob/living/carbon/human/G = new /mob/living/carbon/human
G.dna.mutantrace = "adamantine"
G.real_name = text("Adamantine Golem ([rand(1, 1000)])")
G.equip_to_slot_or_del(new /obj/item/clothing/under/golem(G), slot_w_uniform)
G.equip_to_slot_or_del(new /obj/item/clothing/suit/golem(G), slot_wear_suit)
G.equip_to_slot_or_del(new /obj/item/clothing/shoes/golem(G), slot_shoes)
G.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/golem(G), slot_wear_mask)
G.equip_to_slot_or_del(new /obj/item/clothing/gloves/golem(G), slot_gloves)
//G.equip_to_slot_or_del(new /obj/item/clothing/head/space/golem(G), slot_head)
G.loc = src.loc
var/mob/living/carbon/human/G = new(src.loc)
G.set_species("Golem")
G.key = ghost.key
G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost."
del (src)
@@ -82,18 +82,6 @@
update_icons()
return
/mob/living/carbon/monkey/unathi/New()
..()
dna.mutantrace = "lizard"
/mob/living/carbon/monkey/skrell/New()
..()
dna.mutantrace = "skrell"
/mob/living/carbon/monkey/tajara/New()
..()
dna.mutantrace = "tajaran"
/mob/living/carbon/monkey/movement_delay()
var/tally = 0
if(reagents)
+4 -1
View File
@@ -838,4 +838,7 @@
return 1
/mob/living/proc/has_eyes()
return 1
return 1
/mob/living/proc/slip(var/slipped_on,stun_duration=8)
return 0
+1 -1
View File
@@ -570,7 +570,7 @@ var/list/ai_verbs_default = list(
if(!C.can_use())
continue
var/list/tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS,1)
var/list/tempnetwork = difflist(C.network,restricted_camera_networks,1)
if(tempnetwork.len)
for(var/i in tempnetwork)
cameralist[i] = i
@@ -7,6 +7,9 @@
/turf
var/image/obscured
/turf/drain_power()
return -1
/turf/proc/visibilityChanged()
if(ticker)
cameranet.updateVisibility(src)
@@ -90,13 +93,13 @@
/obj/machinery/camera/New()
..()
cameranet.cameras += src //Camera must be added to global list of all cameras no matter what...
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
var/list/open_networks = difflist(network,restricted_camera_networks) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
if(open_networks.len) //If there is at least one open network, chunk is available for AI usage.
cameranet.addCamera(src)
/obj/machinery/camera/Del()
cameranet.cameras -= src
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS)
var/list/open_networks = difflist(network,restricted_camera_networks)
if(open_networks.len)
cameranet.removeCamera(src)
..()
+1 -1
View File
@@ -20,7 +20,7 @@
src.laws.add_ion_law(law)
for(var/mob/living/silicon/robot/R in mob_list)
if(R.lawupdate && (R.connected_ai == src))
R << "\red " + law + "\red...LAWS UPDATED"
R.show_laws()
/mob/living/silicon/ai/proc/ai_checklaws()
set category = "AI Commands"
+1 -1
View File
@@ -1,6 +1,6 @@
/mob/living/silicon/gib()
..("gibbed-r")
robogibs(loc, viruses)
gibs(loc, viruses, null, /obj/effect/gibspawner/robot)
/mob/living/silicon/dust()
..("dust-r", /obj/effect/decal/remains/robot)
@@ -19,7 +19,7 @@
/obj/item/alarm_frame,
/obj/item/firealarm_frame,
/obj/item/weapon/table_parts,
/obj/item/weapon/rack_parts,
/obj/item/weapon/table_parts/rack,
/obj/item/weapon/camera_assembly,
/obj/item/weapon/tank,
/obj/item/weapon/circuitboard,
@@ -166,8 +166,9 @@
src.sight &= ~SEE_MOBS
src.sight &= ~SEE_TURFS
src.sight &= ~SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_MINIMUM
src.see_in_dark = 8 // see_in_dark means you can FAINTLY see in the dark, humans have a range of 3 or so, tajaran have it at 8
src.see_invisible = SEE_INVISIBLE_LIVING // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness
// has a "invisible" value of 15
regular_hud_updates()
@@ -11,25 +11,23 @@
var/obj/item/borg/upgrade/jetpack = null
var/list/stacktypes
emp_act(severity)
if(modules)
for(var/obj/O in modules)
O.emp_act(severity)
if(emag)
emag.emp_act(severity)
..()
return
New()
// src.modules += new /obj/item/device/flashlight(src) // Replaced by verb and integrated light which uses power.
src.modules += new /obj/item/device/flash(src)
src.emag = new /obj/item/toy/sword(src)
src.emag.name = "Placeholder Emag Item"
// src.jetpack = new /obj/item/toy/sword(src)
// src.jetpack.name = "Placeholder Upgrade Item"
return
/obj/item/weapon/robot_module/emp_act(severity)
if(modules)
for(var/obj/O in modules)
O.emp_act(severity)
if(emag)
emag.emp_act(severity)
..()
return
/obj/item/weapon/robot_module/New()
..()
// Build initial inventory.
if(stacktypes && stacktypes.len)
for(var/stack_type in stacktypes)
var/obj/item/stack/new_stack = new stack_type (src)
new_stack.amount = stacktypes[stack_type]
modules |= new_stack
/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R)
@@ -42,7 +40,7 @@
if(!S)
src.modules -= null
S = new T(src)
src.modules += S
src.modules |= S
S.amount = 1
if(S && S.amount < stacktypes[T])
@@ -64,20 +62,19 @@
R.add_language("Skrellian", 0)
R.add_language("Gutter", 0)
/obj/item/weapon/robot_module/standard
name = "standard robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/baton/loaded(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.emag = new /obj/item/weapon/melee/energy/sword(src)
return
/obj/item/weapon/robot_module/standard/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/baton/loaded(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.emag = new /obj/item/weapon/melee/energy/sword(src)
return
/obj/item/weapon/robot_module/surgeon
name = "surgeon robot module"
@@ -86,29 +83,27 @@
/obj/item/stack/nanopaste = 5
)
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/weapon/scalpel(src)
src.modules += new /obj/item/weapon/hemostat(src)
src.modules += new /obj/item/weapon/retractor(src)
src.modules += new /obj/item/weapon/cautery(src)
src.modules += new /obj/item/weapon/bonegel(src)
src.modules += new /obj/item/weapon/FixOVein(src)
src.modules += new /obj/item/weapon/bonesetter(src)
src.modules += new /obj/item/weapon/circular_saw(src)
src.modules += new /obj/item/weapon/surgicaldrill(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
src.modules += new /obj/item/stack/nanopaste(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
return
/obj/item/weapon/robot_module/surgeon/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/weapon/scalpel(src)
src.modules += new /obj/item/weapon/hemostat(src)
src.modules += new /obj/item/weapon/retractor(src)
src.modules += new /obj/item/weapon/cautery(src)
src.modules += new /obj/item/weapon/bonegel(src)
src.modules += new /obj/item/weapon/FixOVein(src)
src.modules += new /obj/item/weapon/bonesetter(src)
src.modules += new /obj/item/weapon/circular_saw(src)
src.modules += new /obj/item/weapon/surgicaldrill(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
src.modules += new /obj/item/stack/nanopaste(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
return
/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R)
if(src.emag)
@@ -124,27 +119,25 @@
/obj/item/stack/medical/splint = 5
)
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/stack/medical/ointment(src)
src.modules += new /obj/item/stack/medical/bruise_pack(src)
src.modules += new /obj/item/stack/medical/splint(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
return
/obj/item/weapon/robot_module/crisis/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/stack/medical/ointment(src)
src.modules += new /obj/item/stack/medical/bruise_pack(src)
src.modules += new /obj/item/stack/medical/splint(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/extinguisher/mini(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
return
/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R)
@@ -171,17 +164,17 @@
/obj/item/stack/rods = 50
)
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/rcd/borg(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/device/pipe_painter(src)
/obj/item/weapon/robot_module/construction/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/rcd/borg(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/device/pipe_painter(src)
/obj/item/weapon/robot_module/engineering
name = "engineering robot module"
@@ -195,57 +188,39 @@
/obj/item/stack/tile/plasteel = 15
)
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/weldingtool/largetank(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/device/t_scanner(src)
src.modules += new /obj/item/device/analyzer(src)
src.modules += new /obj/item/taperoll/engineering(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/matter_decompiler(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.emag = new /obj/item/borg/stun(src)
var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
M.amount = 50
src.modules += M
var/obj/item/stack/sheet/glass/reinforced/cyborg/R = new (src)
R.amount = 50
src.modules += R
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src)
G.amount = 50
src.modules += G
var/obj/item/stack/cable_coil/robot/W = new /obj/item/stack/cable_coil/robot(src)
W.amount = 50
src.modules += W
return
/obj/item/weapon/robot_module/engineering/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/weldingtool/largetank(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/device/t_scanner(src)
src.modules += new /obj/item/device/analyzer(src)
src.modules += new /obj/item/taperoll/engineering(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/matter_decompiler(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.emag = new /obj/item/borg/stun(src)
return
/obj/item/weapon/robot_module/security
name = "security robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/sec(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
src.modules += new /obj/item/weapon/melee/baton/robot(src)
src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src)
src.modules += new /obj/item/taperoll/police(src)
src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
return
/obj/item/weapon/robot_module/security/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/hud/sec(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
src.modules += new /obj/item/weapon/melee/baton/robot(src)
src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src)
src.modules += new /obj/item/taperoll/police(src)
src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
return
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/device/flash/F = locate() in src.modules
@@ -265,18 +240,17 @@
/obj/item/weapon/robot_module/janitor
name = "janitorial robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/soap/nanotrasen(src)
src.modules += new /obj/item/weapon/storage/bag/trash(src)
src.modules += new /obj/item/weapon/mop(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("lube", 250)
src.emag.name = "Lube spray"
return
/obj/item/weapon/robot_module/janitor/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/soap/nanotrasen(src)
src.modules += new /obj/item/weapon/storage/bag/trash(src)
src.modules += new /obj/item/weapon/mop(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("lube", 250)
src.emag.name = "Lube spray"
return
/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/device/lightreplacer/LR = locate() in src.modules
@@ -288,65 +262,64 @@
/obj/item/weapon/robot_module/butler
name = "service robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
/obj/item/weapon/robot_module/butler/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
M.stored_matter = 30
src.modules += M
var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
M.stored_matter = 30
src.modules += M
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src)
L.lit = 1
src.modules += L
var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src)
L.lit = 1
src.modules += L
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
src.emag.reagents = R
R.my_atom = src.emag
R.add_reagent("beer2", 50)
src.emag.name = "Mickey Finn's Special Brew"
return
var/datum/reagents/R = new/datum/reagents(50)
src.emag.reagents = R
R.my_atom = src.emag
R.add_reagent("beer2", 50)
src.emag.name = "Mickey Finn's Special Brew"
return
add_languages(var/mob/living/silicon/robot/R)
//full set of languages
R.add_language("Sol Common", 1)
R.add_language("Sinta'unathi", 1)
R.add_language("Siik'maas", 1)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 1)
R.add_language("Rootspeak", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 1)
/obj/item/weapon/robot_module/butler/add_languages(var/mob/living/silicon/robot/R)
//full set of languages
R.add_language("Sol Common", 1)
R.add_language("Sinta'unathi", 1)
R.add_language("Siik'maas", 1)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 1)
R.add_language("Rootspeak", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 1)
/obj/item/weapon/robot_module/clerical
name = "clerical robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/pen/robopen(src)
src.modules += new /obj/item/weapon/form_printer(src)
src.modules += new /obj/item/weapon/gripper/paperwork(src)
/obj/item/weapon/robot_module/clerical/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/pen/robopen(src)
src.modules += new /obj/item/weapon/form_printer(src)
src.modules += new /obj/item/weapon/gripper/paperwork(src)
src.emag = new /obj/item/weapon/stamp/denied(src)
src.emag = new /obj/item/weapon/stamp/denied(src)
add_languages(var/mob/living/silicon/robot/R)
R.add_language("Sol Common", 1)
R.add_language("Sinta'unathi", 1)
R.add_language("Siik'maas", 1)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 1)
R.add_language("Rootspeak", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 1)
/obj/item/weapon/robot_module/clerical/add_languages(var/mob/living/silicon/robot/R)
R.add_language("Sol Common", 1)
R.add_language("Sinta'unathi", 1)
R.add_language("Siik'maas", 1)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 1)
R.add_language("Rootspeak", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 1)
/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
@@ -358,38 +331,35 @@
/obj/item/weapon/robot_module/miner
name = "miner robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/storage/bag/ore(src)
src.modules += new /obj/item/weapon/pickaxe/borgdrill(src)
src.modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src)
src.modules += new /obj/item/weapon/gripper/miner(src)
src.modules += new /obj/item/weapon/mining_scanner(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
return
/obj/item/weapon/robot_module/miner/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/storage/bag/ore(src)
src.modules += new /obj/item/weapon/pickaxe/borgdrill(src)
src.modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src)
src.modules += new /obj/item/weapon/gripper/miner(src)
src.modules += new /obj/item/weapon/mining_scanner(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
return
/obj/item/weapon/robot_module/syndicate
name = "illegal robot module"
New(var/mob/living/silicon/robot/R)
loc = R
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src)
src.modules += new /obj/item/weapon/card/emag(src)
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
return
/obj/item/weapon/robot_module/syndicate/New(var/mob/living/silicon/robot/R)
..()
loc = R
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src)
src.modules += new /obj/item/weapon/card/emag(src)
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
return
/obj/item/weapon/robot_module/syndicate/add_languages(var/mob/living/silicon/robot/R)
//full set of languages
@@ -403,18 +373,16 @@
/obj/item/weapon/robot_module/combat
name = "combat robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair?
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
return
/obj/item/weapon/robot_module/combat/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
return
/obj/item/weapon/robot_module/drone
name = "drone module"
@@ -430,30 +398,23 @@
/obj/item/stack/cable_coil/robot = 30
)
New()
src.modules += new /obj/item/weapon/weldingtool(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/matter_decompiler(src)
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
/obj/item/weapon/robot_module/drone/New()
..()
src.modules += new /obj/item/weapon/weldingtool(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/matter_decompiler(src)
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
src.emag.name = "Plasma Cutter"
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
src.emag.name = "Plasma Cutter"
for(var/T in stacktypes)
var/obj/item/stack/sheet/W = new T(src)
W.amount = stacktypes[T]
src.modules += W
return
add_languages(var/mob/living/silicon/robot/R)
return //not much ROM to spare in that tiny microprocessor!
/obj/item/weapon/robot_module/drone/add_languages(var/mob/living/silicon/robot/R)
return //not much ROM to spare in that tiny microprocessor!
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R)
var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
+43 -9
View File
@@ -72,7 +72,7 @@
var/datum/language/speaking = parse_language(message)
if (speaking)
verb = speaking.speech_verb
message = copytext(message,3)
message = trim(copytext(message,2+length(speaking.key)))
if(speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
@@ -102,7 +102,7 @@
if("department")
switch(bot_type)
if(IS_AI)
return AI.holopad_talk(message)
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)
@@ -110,7 +110,7 @@
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)
@@ -149,7 +149,7 @@
return ..(message,speaking,verb)
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message)
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
log_say("[key_name(src)] : [message]")
@@ -160,16 +160,22 @@
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user.
var/verb = say_quote(message)
//Human-like, sorta, heard by those who understand humans.
var/rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
var/rendered_a
//Speach distorted, heard by those who do not understand AIs.
var/message_stars = stars(message)
var/rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
var/rendered_b
if(speaking)
rendered_a = "<span class='game say'><span class='name'>[name]</span> [speaking.format_message(message, verb)]</span>"
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [speaking.format_message(message_stars, verb)]</span>"
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [speaking.format_message(message, verb)]</span></i>"//The AI can "hear" its own message.
else
rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'><span class='body'>\"[message]\"</span></span></span></i>"//The AI can "hear" its own message.
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'>[message]</span></span></i>"//The AI can "hear" its own message.
for(var/mob/M in hearers(T.loc))//The location is the object, default distance.
if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
M.show_message(rendered_a, 2)
@@ -182,6 +188,34 @@
return
return 1
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
log_emote("[key_name(src)] : [message]")
message = trim(message)
if (!message)
return
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src)
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message]</span></span>"
src << "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>"
for(var/mob/M in viewers(T.loc))
M.show_message(rendered, 2)
else //This shouldn't occur, but better safe then sorry.
src << "No holopad connected."
return
return 1
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.hologram && T.master == src) //Is the AI using a holopad?
src.holopad_emote(message)
else //Emote normally, then.
..()
#undef IS_AI
#undef IS_ROBOT
#undef IS_PAI
+3 -2
View File
@@ -203,7 +203,8 @@
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
for(var/datum/language/L in languages)
dat += "<b>[L.name] (:[L.key])</b><br/>Speech Synthesizer: <i>[(L in speech_synthesizer_langs)? "YES":"NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
if(!(L.flags & NONGLOBAL))
dat += "<b>[L.name] (:[L.key])</b><br/>Speech Synthesizer: <i>[(L in speech_synthesizer_langs)? "YES":"NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
@@ -277,4 +278,4 @@
if (stat != 2)
adjustBruteLoss(30)
updatehealth()
updatehealth()
@@ -208,7 +208,7 @@
held_item.loc = src.loc
held_item = null
robogibs(src.loc, viruses)
gibs(loc, viruses, null, null, /obj/effect/gibspawner/robot) //TODO: use gib() or refactor spiderbots into synthetics.
src.Del()
return
@@ -95,7 +95,10 @@
turns_since_move++
if(turns_since_move >= turns_per_move)
if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled
Move(get_step(src,pick(cardinal)))
/var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
moving_to = pick(cardinal)
dir = moving_to //How about we turn them the direction they are moving, yay.
Move(get_step(src,moving_to))
turns_since_move = 0
//Speaking
@@ -198,9 +201,6 @@
..()
/mob/living/simple_animal/gib()
if(meat_amount && meat_type)
for(var/i = 0; i < meat_amount; i++)
new meat_type(src.loc)
..(icon_gib,1)
/mob/living/simple_animal/emote(var/act, var/type, var/desc)
@@ -228,7 +228,7 @@
if("help")
if (health > 0)
M.visible_message("\blue [M] [response_help] \the [src]")
if("disarm")
M.visible_message("\blue [M] [response_disarm] \the [src]")
//TODO: Push the mob away or something
@@ -255,43 +255,43 @@
return
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) //Marker -Agouri
if(istype(O, /obj/item/stack/medical))
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(MED.get_amount() >= 1)
adjustBruteLoss(-MED.heal_brute)
MED.use(1)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\blue [user] applies the [MED] on [src]")
if(stat != DEAD && health < maxHealth)
var/obj/item/stack/medical/medical_pack = O
if(medical_pack.use(1))
adjustBruteLoss(-medical_pack.heal_brute)
visible_message("<span class='warning'>\The [user] applies the [medical_pack] to \the [src].</span>")
else
user << "\blue this [src] is dead, medical items won't bring it back to life."
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
new meat_type (get_turf(src))
if(prob(95))
user << "<span class='warning'>\The [src] cannot benefit from medical items in its current state.</span>"
return
else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
var/actual_meat_amount = max(1,(meat_amount/2))
if(meat_type && actual_meat_amount>0 && (stat == DEAD))
for(var/i=0;i<actual_meat_amount;i++)
var/obj/item/meat = new meat_type(get_turf(src))
meat.name = "[src.name] [meat.name]"
if(small)
user.visible_message("<span class='danger'>[user] chops up \the [src]!</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
del(src)
return
gib()
else
user.visible_message("<span class='danger'>[user] butchers \the [src] messily!</span>")
gib()
return
if(O.force)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
visible_message("<span class='danger'>\The [src] has been attacked with \the [O] by [user].</span>")
else
if(O.force)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
else
usr << "\red This weapon is ineffective, it does no damage."
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
user << "<span class='danger'>This weapon is ineffective; it does no damage.</span>"
visible_message("<span class='danger'>\The [user] gently taps [src] with the [O].</span>")
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later
@@ -371,4 +371,4 @@
message = capitalize(trim_left(message))
..(message, null, verb)
..(message, null, verb)
+5 -5
View File
@@ -392,14 +392,14 @@ var/list/slot_equipment_priority = list( \
set name = "Respawn"
set category = "OOC"
if (!( abandon_allowed ))
usr << "\blue Respawn is disabled."
if (!( config.abandon_allowed ))
usr << "<span class='notice'>Respawn is disabled.</span>"
return
if ((stat != 2 || !( ticker )))
usr << "\blue <B>You must be dead to use this!</B>"
usr << "<span class='notice'><B>You must be dead to use this!</B></span>"
return
if (ticker.mode.name == "meteor" || ticker.mode.name == "epidemic") //BS12 EDIT
usr << "\blue Respawn is disabled for this roundtype."
usr << "<span class='notice'>Respawn is disabled for this roundtype.</span>"
return
else
var/deathtime = world.time - src.timeofdeath
@@ -1159,4 +1159,4 @@ mob/proc/yank_out_object()
return 0
/mob/proc/updateicon()
return
return
+10 -7
View File
@@ -145,7 +145,7 @@
usr << "\red The round is either not ready, or has already finished..."
return
if(client.prefs.species != "Human")
if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0))
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
@@ -162,8 +162,11 @@
if(href_list["SelectedJob"])
if(!enter_allowed)
usr << "\blue There is an administrative lock on entering the game!"
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
return
if(client.prefs.species != "Human")
@@ -172,8 +175,8 @@
return 0
var/datum/species/S = all_species[client.prefs.species]
if(!(S.flags & IS_WHITELISTED))
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
if(!(S.flags & CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
@@ -293,8 +296,8 @@
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return 0
if(!enter_allowed)
usr << "\blue There is an administrative lock on entering the game!"
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return 0
if(!IsJobAvailable(rank))
src << alert("[rank] is not available. Please try another.")
+10 -4
View File
@@ -44,16 +44,16 @@
/mob/proc/say_dead(var/message)
if(say_disabled) //This is here to try to identify lag problems
usr << "\red Speech is currently admin-disabled."
usr << "<span class='danger'>Speech is currently admin-disabled.</span>"
return
if(!src.client.holder)
if(!dsay_allowed)
src << "\red Deadchat is globally muted"
if(!config.dsay_allowed)
src << "<span class='danger'>Deadchat is globally muted.</span>"
return
if(client && !(client.prefs.toggles & CHAT_DEAD))
usr << "\red You have deadchat muted."
usr << "<span class='danger'>You have deadchat muted.</span>"
return
say_dead_direct("[pick("complains","moans","whines","laments","blubbers")], <span class='message'>\"[message]\"</span>", src)
@@ -79,6 +79,9 @@
return 1
return 0
if(speaking.flags & INNATE)
return 1
//Language check.
for(var/datum/language/L in src.languages)
if(speaking.name == L.name)
@@ -142,6 +145,9 @@
//parses the language code (e.g. :j) from text, such as that supplied to say.
//returns the language object only if the code corresponds to a language that src can speak, otherwise null.
/mob/proc/parse_language(var/message)
if(length(message) >= 1 && copytext(message,1,2) == "!")
return all_languages["Noise"]
if(length(message) >= 2)
var/language_prefix = lowertext(copytext(message, 1 ,3))
var/datum/language/L = language_keys[language_prefix]