Merge branch 'master' into AI_langs

This commit is contained in:
Atermonera
2017-09-25 11:40:40 -07:00
committed by GitHub
1349 changed files with 67646 additions and 27065 deletions
+29 -28
View File
@@ -32,7 +32,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
var/anonsay = 0
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
var/ghostvision = 1 //is the ghost able to see things humans can't?
var/seedarkness = 1
// var/seedarkness = 1
incorporeal_move = 1
var/is_manifest = 0 //If set to 1, the ghost is able to whisper. Usually only set if a cultist drags them through the veil.
@@ -57,6 +57,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
"Black Cat" = "blackcat",
"Lizard" = "lizard",
"Goat" = "goat",
"Space Bear" = "bear",
"Bats" = "bat",
"Chicken" = "chicken_white",
"Parrot"= "parrot_fly",
@@ -67,7 +68,8 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
"Trout" = "trout-swim",
"Salmon" = "salmon-swim",
"Pike" = "pike-swim",
"Koi" = "koi-swim"
"Koi" = "koi-swim",
"Carp" = "carp",
"Red Robes" = "robe_red",
"Faithless" = "faithless",
"Shadowform" = "forgotten",
@@ -82,11 +84,9 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
"Guard Spider" = "guard",
"Hunter Spider" = "hunter",
"Nurse Spider" = "nurse",
"Carp" = "carp",
"Space Bear" = "bear",
"Rogue Drone" = "drone",
"ED-209" = "ed209",
"Beepsky" = "secbot",
"Beepsky" = "secbot"
)
/mob/observer/dead/New(mob/body)
@@ -145,7 +145,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
qdel(ghostimage)
ghostimage = null
updateallghostimages()
..()
return ..()
/mob/observer/dead/Topic(href, href_list)
if (href_list["track"])
@@ -225,7 +225,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(stat == DEAD)
if(stat == DEAD && !forbid_seeing_deadchat)
announce_ghost_joinleave(ghostize(1))
else
var/response
@@ -236,7 +236,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
src.client.admin_ghost()
else
response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another 30 minutes! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body")
response = alert(src, "Are you -sure- you want to ghost?\n(You are alive, or otherwise have the potential to become alive. If you ghost, you won't be able to play this round until you respawn as a new character! You can't change your mind so choose wisely!)", "Are you sure you want to ghost?", "Ghost", "Stay in body")
if(response != "Ghost")
return
resting = 1
@@ -298,10 +298,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
if(medHUD)
medHUD = 0
src << "\blue <B>Medical HUD Disabled</B>"
src << "<font color='blue'><B>Medical HUD Disabled</B></font>"
else
medHUD = 1
src << "\blue <B>Medical HUD Enabled</B>"
src << "<font color='blue'><B>Medical HUD Enabled</B></font>"
/mob/observer/dead/verb/toggle_antagHUD()
set category = "Ghost"
@@ -312,11 +312,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
var/mentor = is_mentor(usr.client)
if(!config.antag_hud_allowed && (!client.holder || mentor))
src << "\red Admins have disabled this for this round."
src << "<font color='red'>Admins have disabled this for this round.</font>"
return
var/mob/observer/dead/M = src
if(jobban_isbanned(M, "AntagHUD"))
src << "\red <B>You have been banned from using this feature</B>"
src << "<font color='red'><B>You have been banned from using this feature</B></font>"
return
if(config.antag_hud_restricted && !M.has_enabled_antagHUD && (!client.holder || mentor))
var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No")
@@ -326,10 +326,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
M.has_enabled_antagHUD = 1
if(M.antagHUD)
M.antagHUD = 0
src << "\blue <B>AntagHUD Disabled</B>"
src << "<font color='blue'><B>AntagHUD Disabled</B></font>"
else
M.antagHUD = 1
src << "\blue <B>AntagHUD Enabled</B>"
src << "<font color='blue'><B>AntagHUD Enabled</B></font>"
/mob/observer/dead/proc/dead_tele(var/area/A in return_sorted_areas())
set category = "Ghost"
@@ -461,11 +461,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/observer/dead/memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
src << "<font color='red'>You are dead! You have no mind to store memory!</font>"
/mob/observer/dead/add_memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
src << "<font color='red'>You are dead! You have no mind to store memory!</font>"
/mob/observer/dead/Post_Incorpmove()
following = null
@@ -485,16 +485,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles
src << "\blue <B>Results:</B>"
src << "<font color='blue'><B>Results:</B></font>"
if(abs(pressure - ONE_ATMOSPHERE) < 10)
src << "\blue Pressure: [round(pressure,0.1)] kPa"
src << "<font color='blue'>Pressure: [round(pressure,0.1)] kPa</font>"
else
src << "\red Pressure: [round(pressure,0.1)] kPa"
src << "<font color='red'>Pressure: [round(pressure,0.1)] kPa</font>"
if(total_moles)
for(var/g in environment.gas)
src << "\blue [gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)"
src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]&deg;C ([round(environment.temperature,0.1)]K)"
src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]"
src << "<font color='blue'>[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)</font>"
src << "<font color='blue'>Temperature: [round(environment.temperature-T0C,0.1)]&deg;C ([round(environment.temperature,0.1)]K)</font>"
src << "<font color='blue'>Heat Capacity: [round(environment.heat_capacity(),0.1)]</font>"
/mob/observer/dead/verb/become_mouse()
set name = "Become mouse"
@@ -528,11 +528,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/list/found_vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines)
if(!v.welded && v.z == T.z)
if(!v.welded && v.z == T.z && v.network && v.network.normal_members.len > 20)
found_vents.Add(v)
if(found_vents.len)
vent_found = pick(found_vents)
host = new /mob/living/simple_animal/mouse(vent_found.loc)
host = new /mob/living/simple_animal/mouse(vent_found)
else
src << "<span class='warning'>Unable to find any unwelded vents to spawn mice at.</span>"
@@ -541,6 +541,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
host.universal_understand = 0
announce_ghost_joinleave(src, 0, "They are now a mouse.")
host.ckey = src.ckey
host.add_ventcrawl(vent_found)
host << "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>"
/mob/observer/dead/verb/view_manfiest()
@@ -570,7 +571,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC."
if(!(config.cult_ghostwriter))
src << "\red That verb is not currently permitted."
src << "<font color='red'>That verb is not currently permitted.</font>"
return
if (!src.stat)
@@ -584,8 +585,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(cult.current_antagonists.len > config.cult_ghostwriter_req_cultists)
ghosts_can_write = 1
if(!ghosts_can_write)
src << "\red The veil is not thin enough for you to do that."
if(!ghosts_can_write && !check_rights(R_ADMIN, 0)) //Let's allow for admins to write in blood for events and the such.
src << "<font color='red'>The veil is not thin enough for you to do that.</font>"
return
var/list/choices = list()
@@ -635,7 +636,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
W.update_icon()
W.message = message
W.add_hiddenprint(src)
W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...")
W.visible_message("<font color='red'>Invisible fingers crudely paint something in blood on [T]...</font>")
/mob/observer/dead/pointed(atom/A as mob|obj|turf in view())
if(!..())
+2 -2
View File
@@ -10,7 +10,7 @@
if(message)
client.handle_spam_prevention(MUTE_DEADCHAT)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot talk in deadchat (muted)."
src << "<font color='red'>You cannot talk in deadchat (muted).</font>"
return
. = src.say_dead(message)
@@ -31,7 +31,7 @@
if(message)
client.handle_spam_prevention(MUTE_DEADCHAT)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot emote in deadchat (muted)."
src << "<font color='red'>You cannot emote in deadchat (muted).</font>"
return
. = src.emote_dead(message)
+5 -2
View File
@@ -34,11 +34,14 @@
var/list/m_viewers = in_range["mobs"]
var/list/o_viewers = in_range["objs"]
for(var/mob/M in m_viewers)
for(var/mob in m_viewers)
var/mob/M = mob
spawn(0) // It's possible that it could be deleted in the meantime, or that it runtimes.
if(M)
M.show_message(message, m_type)
for(var/obj/O in o_viewers)
for(var/obj in o_viewers)
var/obj/O = obj
spawn(0)
if(O)
O.see_emote(src, message, m_type)
+2 -2
View File
@@ -43,7 +43,7 @@
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
if(eyeobj) destroy_eyeobj()
if(!newloc) newloc = src.loc
eyeobj = PoolOrNew(/mob/observer/eye/aiEye, newloc)
eyeobj = new /mob/observer/eye/aiEye(newloc)
eyeobj.owner = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
if(client) client.eye = eyeobj
@@ -59,7 +59,7 @@
/mob/living/silicon/ai/Destroy()
destroy_eyeobj()
..()
return ..()
/atom/proc/move_camera_by_click()
if(istype(usr, /mob/living/silicon/ai))
@@ -59,7 +59,7 @@
/obj/machinery/camera/Destroy()
clear_all_networks()
cameranet.cameras -= src
..()
return ..()
// Mobs
/mob/living/silicon/ai/rejuvenate()
+5 -1
View File
@@ -38,7 +38,11 @@ mob/observer/eye/Destroy()
qdel(ghostimage)
ghostimage = null
updateallghostimages()
..()
if(owner)
if(owner.eyeobj == src)
owner.eyeobj = null
owner = null
. = ..()
/mob/observer/eye/Move(n, direct)
if(owner == src)
@@ -25,7 +25,7 @@
/mob/living/Destroy()
cultnet.updateVisibility(src, 0)
..()
return ..()
/mob/living/rejuvenate()
var/was_dead = stat == DEAD
+2 -2
View File
@@ -15,7 +15,7 @@
/turf/simulated/Destroy()
updateVisibility(src)
..()
return ..()
/turf/simulated/New()
..()
@@ -26,7 +26,7 @@
/obj/structure/Destroy()
updateVisibility(src)
..()
return ..()
/obj/structure/New()
..()
+1 -1
View File
@@ -14,7 +14,7 @@
/datum/visualnet/Destroy()
visual_nets -= src
..()
return ..()
// Checks if a chunk has been Generated in x, y, z.
/datum/visualnet/proc/chunkGenerated(x, y, z)
+1 -1
View File
@@ -101,7 +101,7 @@
/mob/living/silicon/ai/special_mentions()
return list("AI") // AI door!
// Converts specific characters, like *, |, and _ to formatted output.
// Converts specific characters, like +, |, and _ to formatted output.
/mob/proc/say_emphasis(var/message)
message = encode_html_emphasis(message, "|", "i")
message = encode_html_emphasis(message, "+", "b")
+1 -1
View File
@@ -27,7 +27,7 @@ var/list/holder_mob_icon_cache = list()
/obj/item/weapon/holder/Destroy()
processing_objects.Remove(src)
..()
return ..()
/obj/item/weapon/holder/process()
update_state()
+1 -1
View File
@@ -56,7 +56,7 @@ var/list/slot_equipment_priority = list( \
else
if(!disable_warning)
src << "\red You are unable to equip that." //Only print if del_on_fail is false
src << "<font color='red'>You are unable to equip that.</font>" //Only print if del_on_fail is false
return 0
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
+14 -11
View File
@@ -26,7 +26,9 @@
whisper_verb = "whispers"
key = "0"
flags = RESTRICTED
syllables = list("vol", "zum", "coo","zoo","bi","do","ooz","ite","og","re","si","ite","ish","ar","at","on","ee","east","ma","da", "rim")
syllables = list(
"vol", "zum", "coo","zoo","bi","do","ooz","ite","og","re","si","ite","ish",
"ar","at","on","ee","east","ma","da", "rim")
//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)
@@ -44,15 +46,12 @@
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")
syllables = list(
"fea","vea","vei","veh","vee","feh","fa","soa","su","sua","sou","se","seh","twa","twe","twi",
"ahm","lea","lee","nae","nah","pa","pau","fae","fai","soh","mou","ahe","ll","ea","ai","thi",
"hie","zei","zie","ize","ehy","uy","oya","dor","di","ja","ej","er","um","in","qu","is","re",
"nt","ti","us","it","en","at","tu","te","ri","es","et","ra","ta","an","ni","li","on","or","se",
"am","ae","ia","di","ue","em","ar","ui","st","si","de","ci","iu","ne","pe","co","os","ur","ru")
// Criminal language.
/datum/language/gutter
@@ -120,4 +119,8 @@
signlang_verb = list("gestures")
colour = "say_quote"
key = "s"
flags = SIGNLANG|NO_STUTTER|NONVERBAL
flags = SIGNLANG|NO_STUTTER|NONVERBAL
/datum/language/sign/can_speak_special(var/mob/speaker)
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
return (hands || !iscarbon(speaker))
+31
View File
@@ -84,3 +84,34 @@
key = "y"
machine_understands = 0
flags = RESTRICTED | HIVEMIND
/datum/language/xenocommon
name = "Xenomorph"
colour = "alien"
desc = "The common tongue of the xenomorphs."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
key = "4"
flags = RESTRICTED
syllables = list("sss","sSs","SSS")
/datum/language/xenos
name = "Hivemind"
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
/datum/language/xenos/check_special_condition(var/mob/other)
var/mob/living/carbon/M = other
if(!istype(M))
return 1
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
return 1
return 0
+2 -2
View File
@@ -60,7 +60,7 @@
flags = WHITELISTED
syllables = list("mrr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr",
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r",
"ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
"ka","aasi","far","wa","baq","ara","qara","zir","saam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
/datum/language/tajaran/get_random_name(var/gender)
@@ -126,7 +126,7 @@
/datum/language/machine/can_speak_special(var/mob/speaker)
var/obj/item/weapon/implant/language/eal/beep = locate() in speaker
return ((beep && beep.implanted) || speaker.isSynthetic())
return ((beep && beep.implanted) || speaker.isSynthetic() || isvoice(speaker))
//thank you sweet zuhayr
/datum/language/machine/get_random_name()
+17
View File
@@ -100,6 +100,7 @@
if(!locked)
open = !open
user << "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>"
playsound(src, O.usesound, 50, 1)
else
user << "<span class='notice'>You need to unlock the controls first.</span>"
return
@@ -108,6 +109,7 @@
if(open)
health = min(getMaxHealth(), health + 10)
user.visible_message("<span class='notice'>[user] repairs [src].</span>","<span class='notice'>You repair [src].</span>")
playsound(src, O.usesound, 50, 1)
else
user << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
else
@@ -126,6 +128,9 @@
..(message, null, verb)
/mob/living/bot/speech_bubble_appearance()
return "machine"
/mob/living/bot/Bump(var/atom/A)
if(on && botcard && istype(A, /obj/machinery/door))
var/obj/machinery/door/D = A
@@ -311,6 +316,18 @@
return L
// Similar to above but not restricted to just cardinal directions.
/turf/proc/TurfsWithAccess(var/obj/item/weapon/card/id/ID)
var/L[] = new()
for(var/d in alldirs)
var/turf/T = get_step(src, d)
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
// Returns true if a link between A and B is blocked
// Movement through doors allowed if ID has access
/proc/LinkBlockedWithAccess(turf/A, turf/B, obj/item/weapon/card/id/ID)
+1 -1
View File
@@ -168,7 +168,7 @@
if(8)
if(istype(W, /obj/item/weapon/screwdriver))
playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
playsound(src, W.usesound, 100, 1)
var/turf/T = get_turf(user)
user << "<span class='notice'>Now attaching the gun to the frame...</span>"
sleep(40)
+1 -1
View File
@@ -221,7 +221,7 @@
if(building == 1)
I = new /obj/item/stack/tile/floor(src)
else
I = PoolOrNew(/obj/item/stack/rods, src)
I = new /obj/item/stack/rods(src)
A.attackby(I, src)
target = null
busy = 0
+56 -13
View File
@@ -1,5 +1,5 @@
/mob/living/bot/medbot
name = "Medbot"
name = "Medibot"
desc = "A little medical robot. He looks somewhat underwhelmed."
icon_state = "medibot0"
req_one_access = list(access_robotics, access_medical)
@@ -24,10 +24,27 @@
var/treatment_emag = "toxin"
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
/mob/living/bot/medbot/mysterious
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
skin = "bezerk"
treatment_brute = "bicaridine"
treatment_fire = "dermaline"
treatment_oxy = "dexalin"
treatment_tox = "anti_toxin"
/mob/living/bot/medbot/handleIdle()
if(vocal && prob(1))
var/message = pick("Radar, put a mask on!", "There's always a catch, and it's the best there is.", "I knew it, I should've been a plastic surgeon.", "What kind of medbay is this? Everyone's dropping like dead flies.", "Delicious!")
var/message_options = list(
"Radar, put a mask on!" = 'sound/voice/medbot/mradar.ogg',
"There's always a catch, and it's the best there is." = 'sound/voice/medbot/mcatch.ogg',
"I knew it, I should've been a plastic surgeon." = 'sound/voice/medbot/msurgeon.ogg',
"What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/medbot/mflies.ogg',
"Delicious!" = 'sound/voice/medbot/mdelicious.ogg'
)
var/message = pick(message_options)
say(message)
playsound(loc, message_options[message], 50, 0)
/mob/living/bot/medbot/handleAdjacentTarget()
UnarmedAttack(target)
@@ -36,9 +53,15 @@
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
if(confirmTarget(H))
target = H
if(last_newpatient_speak + 300 < world.time)
var/message = pick("Hey, [H.name]! Hold on, I'm coming.", "Wait [H.name]! I want to help!", "[H.name], you appear to be injured!")
if(last_newpatient_speak + 30 SECONDS < world.time)
var/message_options = list(
"Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/mcoming.ogg',
"Wait [H.name]! I want to help!" = 'sound/voice/medbot/mhelp.ogg',
"[H.name], you appear to be injured!" = 'sound/voice/medbot/minjured.ogg'
)
var/message = pick(message_options)
say(message)
playsound(loc, message_options[message], 50, 0)
custom_emote(1, "points at [H.name].")
last_newpatient_speak = world.time
break
@@ -56,17 +79,8 @@
if(busy)
return
if(H.stat == DEAD)
var/death_message = pick("No! NO!", "Live, damnit! LIVE!", "I... I've never lost a patient before. Not today, I mean.")
say(death_message)
target = null
return
var/t = confirmTarget(H)
if(!t)
var/message = pick("All patched up!", "An apple a day keeps me away.", "Feel better soon!")
say(message)
target = null
return
visible_message("<span class='warning'>[src] is trying to inject [H]!</span>")
@@ -81,6 +95,32 @@
else
H.reagents.add_reagent(t, injection_amount)
visible_message("<span class='warning'>[src] injects [H] with the syringe!</span>")
if(H.stat == DEAD) // This is down here because this proc won't be called again due to losing a target because of parent AI loop.
var/death_messages = list(
"No! Stay with me!" = 'sound/voice/medbot/mno.ogg',
"Live, damnit! LIVE!" = 'sound/voice/medbot/mlive.ogg',
"I... I've never lost a patient before. Not today, I mean." = 'sound/voice/medbot/mlost.ogg'
)
var/message = pick(death_messages)
say(message)
playsound(loc, death_messages[message], 50, 0)
target = null
// This is down here for the same reason as above.
else
t = confirmTarget(H)
if(!t)
var/possible_messages = list(
"All patched up!" = 'sound/voice/medbot/mpatchedup.ogg',
"An apple a day keeps me away." = 'sound/voice/medbot/mapple.ogg',
"Feel better soon!" = 'sound/voice/medbot/mfeelbetter.ogg'
)
var/message = pick(possible_messages)
say(message)
playsound(loc, possible_messages[message], 50, 0)
target = null
busy = 0
update_icons()
@@ -223,6 +263,9 @@
reagent_glass.loc = Tsec
reagent_glass = null
if(emagged && prob(25))
playsound(loc, 'sound/voice/medbot/minsult.ogg', 50, 0)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
+2 -2
View File
@@ -268,8 +268,8 @@
var/turf/Tsec = get_turf(src)
new /obj/item/device/assembly/prox_sensor(Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
PoolOrNew(/obj/item/stack/rods, Tsec)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/cable_coil/cut(Tsec)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+67 -9
View File
@@ -13,6 +13,7 @@
patrol_speed = 2
target_speed = 3
var/default_icon_state = "secbot"
var/idcheck = 0 // If true, arrests for having weapons without authorization.
var/check_records = 0 // If true, arrests people without a record.
var/check_arrest = 1 // If true, arrests people who are set to arrest.
@@ -21,23 +22,44 @@
var/is_ranged = 0
var/awaiting_surrender = 0
var/can_next_insult = 0 // Uses world.time
var/stun_strength = 60 // For humans.
var/xeno_stun_strength = 0 // For simple mobs.
var/xeno_harm_strength = 15 // Ditto.
var/baton_glow = "#FF6A00"
var/list/threat_found_sounds = list('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg')
var/list/preparing_arrest_sounds = list('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/bcreep.ogg')
var/list/fighting_sounds = list('sound/voice/biamthelaw.ogg', 'sound/voice/bradio.ogg', 'sound/voice/bjustice.ogg')
/mob/living/bot/secbot/beepsky
name = "Officer Beepsky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
will_patrol = 1
/mob/living/bot/secbot/slime
name = "Slime Securitron"
desc = "A little security robot, with a slime baton subsituted for the regular one."
default_icon_state = "slimesecbot"
stun_strength = 10 // Slimebatons aren't meant for humans.
xeno_stun_strength = 5
xeno_harm_strength = 9
baton_glow = "#33CCFF"
req_one_access = list(access_research, access_robotics)
botcard_access = list(access_research, access_robotics, access_xenobiology, access_xenoarch, access_tox, access_tox_storage, access_maint_tunnels)
/mob/living/bot/secbot/slime/slimesky
name = "Doctor Slimesky"
desc = "An old friend of Officer Beep O'sky. He prescribes beatings to rowdy slimes so that real doctors don't need to treat the xenobiologists."
/mob/living/bot/secbot/update_icons()
if(on && busy)
icon_state = "secbot-c"
icon_state = "[default_icon_state]-c"
else
icon_state = "secbot[on]"
icon_state = "[default_icon_state][on]"
if(on)
set_light(2, 1, "#FF6A00")
set_light(2, 1, baton_glow)
else
set_light(0)
@@ -114,6 +136,11 @@
if(!target && health < curhealth && shooter && (shooter in view(world.view, src)))
react_to_attack(shooter)
/mob/living/bot/secbot/attack_generic(var/mob/attacker)
if(attacker)
react_to_attack(attacker)
..()
/mob/living/bot/secbot/proc/react_to_attack(mob/attacker)
if(!target)
playsound(src.loc, pick(threat_found_sounds), 50)
@@ -163,6 +190,7 @@
awaiting_surrender = -1
say("Level [threat] infraction alert!")
custom_emote(1, "points at [M.name]!")
playsound(src.loc, pick(threat_found_sounds), 50)
return
/mob/living/bot/secbot/handleAdjacentTarget()
@@ -174,9 +202,25 @@
++awaiting_surrender
else
if(declare_arrests)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [threat] suspect <b>[target_name(target)]</b> in <b>[get_area(src)]</b>.", src)
var/action = arrest_type ? "detaining" : "arresting"
if(istype(target, /mob/living/simple_animal))
action = "fighting"
broadcast_security_hud_message("[src] is [action] a level [threat] [action != "fighting" ? "suspect" : "threat"] <b>[target_name(target)]</b> in <b>[get_area(src)]</b>.", src)
UnarmedAttack(target)
// So Beepsky talks while beating up simple mobs.
/mob/living/bot/secbot/proc/insult(var/mob/living/L)
if(can_next_insult > world.time)
return
var/threat = check_threat(L)
if(threat >= 10)
playsound(src.loc, 'sound/voice/binsult.ogg', 75)
can_next_insult = world.time + 20 SECONDS
else
playsound(src.loc, pick(fighting_sounds), 75)
can_next_insult = world.time + 5 SECONDS
/mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity)
if(!..())
return
@@ -194,7 +238,7 @@
if(!C.lying || C.handcuffed || arrest_type)
cuff = 0
if(!cuff)
C.stun_effect_act(0, 60, null)
C.stun_effect_act(0, stun_strength, null)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
do_attack_animation(C)
busy = 1
@@ -203,6 +247,7 @@
busy = 0
update_icons()
visible_message("<span class='warning'>\The [C] was prodded by \the [src] with a stun baton!</span>")
insult(C)
else
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
visible_message("<span class='warning'>\The [src] is trying to put handcuffs on \the [C]!</span>")
@@ -214,8 +259,8 @@
busy = 0
else if(istype(M, /mob/living/simple_animal))
var/mob/living/simple_animal/S = M
S.AdjustStunned(10)
S.adjustBruteLoss(15)
S.Weaken(xeno_stun_strength)
S.adjustBruteLoss(xeno_harm_strength)
do_attack_animation(M)
playsound(loc, "swing_hit", 50, 1, -1)
busy = 1
@@ -224,6 +269,15 @@
busy = 0
update_icons()
visible_message("<span class='warning'>\The [M] was beaten by \the [src] with a stun baton!</span>")
insult(S)
/mob/living/bot/secbot/slime/UnarmedAttack(var/mob/living/L, var/proximity)
..()
if(istype(L, /mob/living/simple_animal/slime))
var/mob/living/simple_animal/slime/S = L
S.adjust_discipline(2)
/mob/living/bot/secbot/explode()
@@ -323,8 +377,12 @@
else if(istype(W, /obj/item/weapon/melee/baton) && build_step == 3)
user.drop_item()
user << "You complete the Securitron! Beep boop."
var/mob/living/bot/secbot/S = new /mob/living/bot/secbot(get_turf(src))
S.name = created_name
if(istype(W, /obj/item/weapon/melee/baton/slime))
var/mob/living/bot/secbot/slime/S = new /mob/living/bot/secbot/slime(get_turf(src))
S.name = created_name
else
var/mob/living/bot/secbot/S = new /mob/living/bot/secbot(get_turf(src))
S.name = created_name
qdel(W)
qdel(src)
@@ -28,7 +28,7 @@
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
O.show_message(text("<font color='red'>[] has grabbed [] passively!</font>", M, src), 1)
else
var/damage = rand(1, 9)
@@ -43,17 +43,17 @@
playsound(loc, "punch", 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has punched []!</B>", M, src), 1)
O.show_message(text("<font color='red'><B>[] has punched []!</B></font>", M, src), 1)
if (damage > 4.9)
Weaken(rand(10,15))
for(var/mob/O in viewers(M, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has weakened []!</B>", M, src), 1, "\red You hear someone fall.", 2)
O.show_message(text("<font color='red'><B>[] has weakened []!</B></font>", M, src), 1, "<font color='red'>You hear someone fall.</font>", 2)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to punch []!</B>", M, src), 1)
O.show_message(text("<font color='red'><B>[] has attempted to punch []!</B></font>", M, src), 1)
return
@@ -15,5 +15,5 @@
src.loc = L.loc
qdel(L)
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","\red You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.")
src.visible_message("<font color='red'>[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.</font>","<font color='red'>You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.</font>")
return "Diona"
@@ -16,7 +16,7 @@
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
src << "<font color='red'>You cannot send IC messages (muted).</font>"
return
if (stat)
return
@@ -0,0 +1,15 @@
/mob/living/carbon/alien/larva
name = "alien larva"
real_name = "alien larva"
adult_form = /mob/living/carbon/human
speak_emote = list("hisses")
icon_state = "larva"
language = "Hivemind"
maxHealth = 25
health = 25
faction = "xeno"
/mob/living/carbon/alien/larva/New()
..()
add_language("Xenomorph") //Bonus language.
internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src)
@@ -0,0 +1,13 @@
//Larvae regenerate health and nutrition from plasma and alien weeds.
/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment)
if(!environment) return
var/turf/T = get_turf(src)
if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents))
update_progression()
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
@@ -0,0 +1,12 @@
/mob/living/carbon/alien/larva/confirm_evolution()
src << "<span class='notice'><b>You are growing into a beautiful alien! It is time to choose a caste.</b></span>"
src << "<span class='notice'>There are three to choose from:</span>"
src << "<B>Hunters</B> <span class='notice'> are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves.</span>"
src << "<B>Sentinels</B> <span class='notice'> are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters.</span>"
src << "<B>Drones</B> <span class='notice'> are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen.</span>"
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
return alien_caste ? "Xenomorph [alien_caste]" : null
/mob/living/carbon/alien/larva/show_evolution_blurb()
return
+1 -1
View File
@@ -150,7 +150,7 @@
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
if (fire) fire.icon_state = "fire2"
if(prob(20))
src << "\red You feel a searing heat!"
src << "<font color='red'>You feel a searing heat!</font>"
else
if (fire) fire.icon_state = "fire0"
@@ -12,11 +12,11 @@
return
if(handcuffed || legcuffed)
src << "\red You cannot evolve when you are cuffed."
src << "<font color='red'>You cannot evolve when you are cuffed.</font>"
return
if(amount_grown < max_grown)
src << "\red You are not fully grown."
src << "<font color='red'>You are not fully grown.</font>"
return
// confirm_evolution() handles choices and other specific requirements.
@@ -30,6 +30,9 @@
transfer_languages(src, adult)
if(src.faction != "neutral")
adult.faction = src.faction
if(mind)
mind.transfer_to(adult)
if (can_namepick_as_adult)
+1 -1
View File
@@ -4,7 +4,7 @@
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
src << "<font color='red'>You cannot speak in IC (Muted).</font>"
return
message = sanitize(message)
+59 -76
View File
@@ -16,6 +16,30 @@
var/mob/living/carbon/brain/brainmob = null//The current occupant.
var/obj/item/organ/internal/brain/brainobj = null //The current brain organ.
var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/obj/item/device/radio/headset/mmi_radio/radio = null//Let's give it a radio.
/obj/item/device/mmi/New()
radio = new(src)//Spawns a radio inside the MMI.
/obj/item/device/mmi/verb/toggle_radio()
set name = "Toggle Brain Radio"
set desc = "Enables or disables the integrated brain radio, which is only usable outside of a body."
set category = "Object"
set src in usr
set popup_menu = 1
if(!usr.canmove || usr.stat || usr.restrained())
return 0
if (radio.radio_enabled == 1)
radio.radio_enabled = 0
to_chat (usr, "You have disabled the [src]'s radio.")
to_chat (brainmob, "Your radio has been disabled.")
else if (radio.radio_enabled == 0)
radio.radio_enabled = 1
to_chat (usr, "You have enabled the [src]'s radio.")
to_chat (brainmob, "Your radio has been enabled.")
else
to_chat (usr, "You were unable to toggle the [src]'s radio.")
/obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO
@@ -110,50 +134,15 @@
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
borg.mmi = null
if(brainmob)
qdel(brainmob)
brainmob = null
..()
qdel_null(radio)
qdel_null(brainmob)
return ..()
/obj/item/device/mmi/radio_enabled
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."
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio. Wait, don't they all?"
origin_tech = list(TECH_BIO = 4)
var/obj/item/device/radio/radio = null//Let's give it a radio.
New()
..()
radio = new(src)//Spawns a radio inside the MMI.
radio.broadcasting = 1//So it's broadcasting from the start.
verb//Allows the brain to toggle the radio functions.
Toggle_Broadcasting()
set name = "Toggle Broadcasting"
set desc = "Toggle broadcasting channel on or off."
set category = "MMI"
set src = usr.loc//In user location, or in MMI in this case.
set popup_menu = 0//Will not appear when right clicking.
if(brainmob.stat)//Only the brainmob will trigger these so no further check is necessary.
brainmob << "Can't do that while incapacitated or dead."
radio.broadcasting = radio.broadcasting==1 ? 0 : 1
brainmob << "<span class='notice'>Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting.</span>"
Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
if(brainmob.stat)
brainmob << "Can't do that while incapacitated or dead."
radio.listening = radio.listening==1 ? 0 : 1
brainmob << "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>"
/obj/item/device/mmi/emp_act(severity)
if(!brainmob)
return
@@ -175,15 +164,18 @@
req_access = list(access_robotics)
locked = 0
mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/ghost_query_type = null
/obj/item/device/mmi/digital/New()
src.brainmob = new(src)
src.brainmob.add_language("Robot Talk")
// src.brainmob.add_language("Robot Talk")//No binary without a binary communication device
src.brainmob.add_language(LANGUAGE_GALCOM)
src.brainmob.add_language(LANGUAGE_EAL)
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.stat = 0
src.brainmob.silent = 0
radio = new(src)
dead_mob_list -= src.brainmob
/obj/item/device/mmi/digital/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -234,60 +226,49 @@
/obj/item/device/mmi/digital/attack_self(mob/user as mob)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the [src]'s boot process."
src.searching = 1
src.request_player()
spawn(600) reset_search()
user << "<font color='blue'>You carefully locate the manual activation switch and start the [src]'s boot process.</font>"
request_player()
/obj/item/device/mmi/digital/proc/request_player()
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_AI)
question(O.client)
if(!ghost_query_type)
return
searching = 1
var/datum/ghost_query/Q = new ghost_query_type()
var/list/winner = Q.query()
if(winner.len)
var/mob/observer/dead/D = winner[1]
transfer_personality(D)
else
reset_search()
/obj/item/device/mmi/digital/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(src.brainmob && src.brainmob.key) return
world.log << "Resetting [src.name]: [brainmob][brainmob ? ", [brainmob.key]" : ""]"
if(src.brainmob && src.brainmob.key)
return
src.searching = 0
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The [src] buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
/obj/item/device/mmi/digital/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "Someone is requesting a personality for a [src]. Would you like to play as one?", "[src] request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as a [src]?", "[src] request", "Yes", "No")
if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_AI
M.show_message("<font color='blue'>\The [src] buzzes quietly, and the golden lights fade away. Perhaps you could try again?</font>")
/obj/item/device/mmi/digital/proc/transfer_personality(var/mob/candidate)
announce_ghost_joinleave(candidate, 0, "They are occupying a synthetic brain now.")
src.searching = 0
src.brainmob.mind = candidate.mind
if(candidate.mind)
src.brainmob.mind = candidate.mind
src.brainmob.mind.reset()
src.brainmob.ckey = candidate.ckey
src.brainmob.mind.reset()
src.name = "positronic brain ([src.brainmob.name])"
src.name = "[name] ([src.brainmob.name])"
src.brainmob << "<b>You are a [src], brought into existence on [station_name()].</b>"
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
src.brainmob << "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
src.brainmob << "<b>Use say #b to speak to other artificial intelligences.</b>"
src.brainmob.mind.assigned_role = "Positronic Brain"
// src.brainmob << "<b>Use say #b to speak to other artificial intelligences.</b>"
src.brainmob.mind.assigned_role = "Synthetic Brain"
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The [src] chimes quietly.")
M.show_message("<font color='blue'>\The [src] chimes quietly.</font>")
/obj/item/device/mmi/digital/robot
name = "robotic intelligence circuit"
@@ -296,6 +277,7 @@
icon_state = "mainboard"
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 3, TECH_DATA = 4)
ghost_query_type = /datum/ghost_query/drone_brain
/obj/item/device/mmi/digital/robot/New()
..()
@@ -317,10 +299,11 @@
icon_state = "posibrain"
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2, TECH_DATA = 4)
ghost_query_type = /datum/ghost_query/posi_brain
/obj/item/device/mmi/digital/posibrain/attack_self(mob/user as mob)
..()
/obj/item/device/mmi/digital/posibrain/request_player()
icon_state = "posibrain-searching"
..()
/obj/item/device/mmi/digital/posibrain/transfer_identity(var/mob/living/carbon/H)
@@ -20,7 +20,7 @@
if(stat!=DEAD) //If not dead.
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize() //Ghostize checks for key so nothing else is necessary.
..()
return ..()
say_understands(var/other)//Goddamn is this hackish, but this say code is so odd
if (istype(other, /mob/living/silicon/ai))
@@ -45,7 +45,7 @@
return 1
if (istype(other, /mob/living/carbon/human))
return 1
if (istype(other, /mob/living/carbon/slime))
if (istype(other, /mob/living/simple_animal/slime))
return 1
return ..()
@@ -58,7 +58,7 @@
return canmove
/mob/living/carbon/brain/isSynthetic()
return istype(loc, /obj/item/device/mmi/digital)
return istype(loc, /obj/item/device/mmi)
/mob/living/carbon/brain/binarycheck()
return isSynthetic()
///mob/living/carbon/brain/binarycheck()//No binary without a binary communication device
// return isSynthetic()
@@ -17,7 +17,7 @@
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
src << "<font color='red'>You cannot send IC messages (muted).</font>"
return
if (stat)
return
@@ -60,7 +60,7 @@
if ("help")
src << "alarm,alert,notice,flash,blink,whistle,beep,boop"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
src << "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>"
if (message)
log_emote("[name]/[key] : [message]")
+8 -8
View File
@@ -6,9 +6,9 @@
if (radiation > 100)
radiation = 100
if(!container)//If it's not in an MMI
src << "\red You feel weak."
src << "<font color='red'>You feel weak.</font>"
else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that
src << "\red STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED."
src << "<font color='red'>STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED.</font>"
switch(radiation)
if(1 to 49)
@@ -23,9 +23,9 @@
if(prob(5))
radiation -= 5
if(!container)
src << "\red You feel weak."
src << "<font color='red'>You feel weak.</font>"
else
src << "\red STATUS: DANGEROUS LEVELS OF RADIATION DETECTED."
src << "<font color='red'>STATUS: DANGEROUS LEVELS OF RADIATION DETECTED.</font>"
updatehealth()
if(75 to 100)
@@ -116,7 +116,7 @@
silent = 1
if(!alert)//Sounds an alarm, but only once per 'level'
emote("alarm")
src << "\red Major electrical distruption detected: System rebooting."
src << "<font color='red'>Major electrical distruption detected: System rebooting.</font>"
alert = 1
if(prob(75))
emp_damage -= 1
@@ -132,7 +132,7 @@
ear_damage = 1
if(!alert)
emote("alert")
src << "\red Primary systems are now online."
src << "<font color='red'>Primary systems are now online.</font>"
alert = 1
if(prob(50))
emp_damage -= 1
@@ -144,13 +144,13 @@
if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere)
if(!alert)
emote("notice")
src << "\red System reboot nearly complete."
src << "<font color='red'>System reboot nearly complete.</font>"
alert = 1
if(prob(25))
emp_damage -= 1
if(1)
alert = 0
src << "\red All systems restored."
src << "<font color='red'>All systems restored.</font>"
emp_damage -= 1
return 1
@@ -16,7 +16,7 @@
/obj/item/device/mmi/digital/posibrain/attack_self(mob/user as mob)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
user << "<font color='blue'>You carefully locate the manual activation switch and start the positronic brain's boot process.</font>"
icon_state = "posibrain-searching"
src.searching = 1
src.request_player()
@@ -68,7 +68,8 @@
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain chimes quietly.")
M.show_message("<font color='blue'>The positronic brain beeps as it loads a personality.</font>")
playsound(src, 'sound/misc/boobeebeep.ogg', 50, 1)
icon_state = "posibrain-occupied"
/obj/item/device/mmi/digital/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
@@ -81,7 +82,8 @@
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
M.show_message("<font color='blue'>The positronic brain buzzes and beeps, and the golden lights fade away. Perhaps you could try again?</font>")
playsound(src, 'sound/misc/buzzbeep.ogg', 50, 1)
/obj/item/device/mmi/digital/posibrain/examine(mob/user)
if(!..(user))
+13 -5
View File
@@ -22,7 +22,7 @@
verb="asks"
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
if(prob(10))//10% chance to drop the message entirely
return
else
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
@@ -31,8 +31,16 @@
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), verb, speaking)
..(trim(message), speaking, verb)
/mob/living/carbon/brain/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode)
var/obj/item/device/mmi/R = container
if (R.radio && R.radio.radio_enabled)
if(message_mode == "general")
message_mode = null
return R.radio.talk_into(src,message,message_mode,verb,speaking)
else
src << "<span class='danger'>Your radio is disabled.</span>"
return 0
+14 -11
View File
@@ -80,7 +80,7 @@
M.loc = src.loc
for(var/mob/N in viewers(src, null))
if(N.client)
N.show_message(text("\red <B>[M] bursts out of [src]!</B>"), 2)
N.show_message(text("<font color='red'><B>[M] bursts out of [src]!</B></font>"), 2)
..()
/mob/living/carbon/attack_hand(mob/M as mob)
@@ -91,13 +91,16 @@
if (H.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
H << "\red You can't use your [temp.name]"
H << "<font color='red'>You can't use your [temp.name]</font>"
return
return
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null, var/stun = 1)
if(status_flags & GODMODE) return 0 //godmode
if(def_zone == "l_hand" || def_zone == "r_hand") //Diona (And any other potential plant people) hands don't get shocked.
if(species.flags & IS_PLANT)
return 0
shock_damage *= siemens_coeff
if (shock_damage<1)
return 0
@@ -106,18 +109,18 @@
playsound(loc, "sparks", 50, 1, -1)
if (shock_damage > 15)
src.visible_message(
"\red [src] was shocked by \the [source]!", \
"\red <B>You feel a powerful shock course through your body!</B>", \
"\red You hear a heavy electrical crack." \
"<font color='red'>[src] was shocked by \the [source]!</font>", \
"<font color='red'><B>You feel a powerful shock course through your body!</B></font>", \
"<font color='red'>You hear a heavy electrical crack.</font>" \
)
if(stun)
Stun(10)//This should work for now, more is really silly and makes you lay there forever
Weaken(10)
else
src.visible_message(
"\red [src] was mildly shocked by \the [source].", \
"\red You feel a mild shock course through your body.", \
"\red You hear a light zapping." \
"<font color='red'>[src] was mildly shocked by \the [source].</font>", \
"<font color='red'>You feel a mild shock course through your body.</font>", \
"<font color='red'>You hear a light zapping.</font>" \
)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
@@ -158,8 +161,8 @@
if(src == M && istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
src.visible_message( \
text("\blue [src] examines [].",src.gender==MALE?"himself":"herself"), \
"\blue You check yourself for injuries." \
text("<font color='blue'>[src] examines [].</font>",src.gender==MALE?"himself":"herself"), \
"<font color='blue'>You check yourself for injuries.</font>" \
)
for(var/obj/item/organ/external/org in H.organs)
@@ -418,7 +421,7 @@
set category = "IC"
if(usr.sleeping)
usr << "\red You are already sleeping"
usr << "<font color='red'>You are already sleeping</font>"
return
if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes")
usr.sleeping = 20 //Short nap
+3 -3
View File
@@ -1,11 +1,11 @@
/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
/mob/living/carbon/human/verb/give(var/mob/living/carbon/target in view(1)-usr)
set category = "IC"
set name = "Give"
// TODO : Change to incapacitated() on merge.
if(src.stat || src.lying || src.resting || src.buckled)
if(src.stat || src.lying || src.resting || src.handcuffed)
return
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
if(!istype(target) || target.stat || target.lying || target.resting || target.handcuffed || target.client == null)
return
var/obj/item/I = src.get_active_hand()
@@ -24,7 +24,7 @@
for(var/R in cures)
if(H.reagents.has_reagent(R))
if (cure_message)
H <<"\blue [cure_message]"
H <<"<font color='blue'>[cure_message]</font>"
return 1
return 0
@@ -24,7 +24,7 @@
for(var/R in cures)
if(H.reagents.has_reagent(R))
if (cure_message)
H <<"\blue [cure_message]"
H <<"<font color='blue'>[cure_message]</font>"
return 1
return 0
@@ -41,6 +41,13 @@
species.handle_death(src)
animate_tail_stop()
//Handle snowflake ling stuff.
if(mind && mind.changeling)
// If the ling is capable of revival, don't allow them to see deadchat.
if(mind.changeling.chem_charges >= CHANGELING_STASIS_COST)
if(mind.changeling.max_geneticpoints >= 0) // Absorbed lings don't count, as they can't revive.
forbid_seeing_deadchat = TRUE
//Handle brain slugs.
var/obj/item/organ/external/Hd = get_organ(BP_HEAD)
var/mob/living/simple_animal/borer/B
@@ -134,7 +134,7 @@
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
src << "<font color='red'>You cannot send IC messages (muted).</font>"
return
if (stat)
return
@@ -678,7 +678,7 @@
twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
src << "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>"
if (message)
log_emote("[name]/[key] : [message]")
@@ -1,4 +1,5 @@
/mob/living/carbon/human/examine(mob/user)
var/skipgloves = 0
var/skipsuitstorage = 0
var/skipjumpsuit = 0
@@ -17,6 +18,18 @@
var/skiparms = 0
var/skipfeet = 0
var/cloaked = 0 // 0 for normal, 1 for cloaked close
if(mind && mind.changeling && mind.changeling.cloaked && !istype(user, /mob/observer))
var/distance = get_dist(user, src)
if(distance > 2)
src.loc.examine(user)
return
else
cloaked = 1
var/looks_synth = looksSynthetic()
//exosuits and helmets obscure our view and stuff.
@@ -79,9 +92,13 @@
var/list/msg = list("<span class='info'>*---------*\nThis is ")
var/datum/gender/T = gender_datums[get_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
if(cloaked)
T = gender_datums[NEUTER]
else if(species && species.ambiguous_genders)
var/can_detect_gender = FALSE
@@ -441,17 +458,25 @@
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a> <a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>\n"
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
if(print_flavor_text() && !cloaked)
msg += "[print_flavor_text()]\n"
msg += "*---------*</span><br>"
msg += applying_pressure
if (pose)
if (pose && !cloaked)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "[T.He] [pose]"
user << jointext(msg, null)
/mob/living/carbon/human/get_description_fluff()
if(mind && mind.changeling && mind.changeling.cloaked)
return ""
else
return ..()
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M as mob, hudtype)
if(istype(M, /mob/living/carbon/human))
+40 -13
View File
@@ -10,6 +10,11 @@
var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
var/last_push_time //For human_attackhand.dm, keeps track of the last use of disarm
var/spitting = 0 //Spitting and spitting related things. Any human based ranged attacks, be it innate or added abilities.
var/spit_projectile = null //Projectile type.
var/spit_name = null //String
var/last_spit = 0 //Timestamp.
/mob/living/carbon/human/New(var/new_loc, var/new_species = null)
if(!dna)
@@ -78,6 +83,11 @@
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] //Xenomorphs. Mech.
if(P)
stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
if(back && istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/suit = back
var/cell_status = "ERROR"
@@ -247,6 +257,7 @@
// called when something steps onto a human
// this handles mulebots and vehicles
// and now mobs on fire
/mob/living/carbon/human/Crossed(var/atom/movable/AM)
if(istype(AM, /mob/living/bot/mulebot))
var/mob/living/bot/mulebot/MB = AM
@@ -256,12 +267,14 @@
var/obj/vehicle/V = AM
V.RunOver(src)
spread_fire(AM)
// Get rank from ID, ID inside PDA, PDA, ID in wallet, etc.
/mob/living/carbon/human/proc/get_authentification_rank(var/if_no_id = "No id", var/if_no_job = "No job")
var/obj/item/device/pda/pda = wear_id
if (istype(pda))
if (pda.id)
return pda.id.rank
return pda.id.rank ? pda.id.rank : if_no_job
else
return pda.ownrank
else
@@ -305,6 +318,8 @@
//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
/mob/living/carbon/human/proc/get_visible_name()
if( mind && mind.changeling && mind.changeling.cloaked)
return "Unknown"
if( wear_mask && (wear_mask.flags_inv&HIDEFACE) ) //Wearing a mask which hides our face, use id-name if possible
return get_id_name("Unknown")
if( head && (head.flags_inv&HIDEFACE) )
@@ -415,7 +430,7 @@
U.handle_regular_hud_updates()
if(!modified)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["secrecord"])
if(hasHUD(usr,"security"))
@@ -445,7 +460,7 @@
read = 1
if(!read)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["secrecordComment"])
if(hasHUD(usr,"security"))
@@ -475,7 +490,7 @@
usr << "<a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a>"
if(!read)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["secrecordadd"])
if(hasHUD(usr,"security"))
@@ -543,7 +558,7 @@
U.handle_regular_hud_updates()
if(!modified)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["medrecord"])
if(hasHUD(usr,"medical"))
@@ -574,7 +589,7 @@
read = 1
if(!read)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["medrecordComment"])
if(hasHUD(usr,"medical"))
@@ -604,7 +619,7 @@
usr << "<a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>"
if(!read)
usr << "\red Unable to locate a data core entry for this person."
usr << "<font color='red'>Unable to locate a data core entry for this person.</font>"
if (href_list["medrecordadd"])
if(hasHUD(usr,"medical"))
@@ -756,7 +771,7 @@
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)
visible_message("\red \The [src] begins playing \his ribcage like a xylophone. It's quite spooky.","\blue You begin to play a spooky refrain on your ribcage.","\red You hear a spooky xylophone melody.")
visible_message("<font color='red'>\The [src] begins playing \his ribcage like a xylophone. It's quite spooky.</font>","<font color='blue'>You begin to play a spooky refrain on your ribcage.</font>","<font color='red'>You hear a spooky xylophone melody.</font>")
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
playsound(loc, song, 50, 1, -1)
xylophone = 1
@@ -847,7 +862,7 @@
regenerate_icons()
check_dna()
visible_message("\blue \The [src] morphs and changes [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "\blue You change your appearance!", "\red Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
visible_message("<font color='blue'>\The [src] morphs and changes [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] appearance!</font>", "<font color='blue'>You change your appearance!</font>", "<font color='red'>Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!</font>")
/mob/living/carbon/human/proc/remotesay()
set name = "Project mind"
@@ -870,10 +885,10 @@
var/say = sanitize(input("What do you wish to say"))
if(mRemotetalk in target.mutations)
target.show_message("\blue You hear [src.real_name]'s voice: [say]")
target.show_message("<font color='blue'> You hear [src.real_name]'s voice: [say]</font>")
else
target.show_message("\blue You hear a voice that seems to echo around the room: [say]")
usr.show_message("\blue You project your mind into [target.real_name]: [say]")
target.show_message("<font color='blue'> You hear a voice that seems to echo around the room: [say]</font>")
usr.show_message("<font color='blue'> You project your mind into [target.real_name]: [say]</font>")
log_say("[key_name(usr)] sent a telepathic message to [key_name(target)]: [say]")
for(var/mob/observer/dead/G in world)
G.show_message("<i>Telepathic message from <b>[src]</b> to <b>[target]</b>: [say]</i>")
@@ -1015,7 +1030,8 @@
gunshot_residue = null
if(clean_feet && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len)
feet_blood_color = null
qdel(feet_blood_DNA)
feet_blood_DNA.Cut()
feet_blood_DNA = null
update_inv_shoes(1)
return 1
@@ -1497,3 +1513,14 @@
/mob/living/carbon/human/is_muzzled()
return (wear_mask && (istype(wear_mask, /obj/item/clothing/mask/muzzle) || istype(src.wear_mask, /obj/item/weapon/grenade)))
/mob/living/carbon/human/get_fire_icon_state()
return species.fire_icon_state
// Called by job_controller. Makes drones start with a permit, might be useful for other people later too.
/mob/living/carbon/human/equip_post_job()
var/braintype = get_FBP_type()
if(braintype == FBP_DRONE)
var/turf/T = get_turf(src)
var/obj/item/weapon/permit/drone/permit = new(T)
permit.set_name(real_name)
equip_to_appropriate_slot(permit) // If for some reason it can't find room, it'll still be on the floor.
@@ -15,7 +15,7 @@
if(H.hand)
temp = H.organs_by_name["l_hand"]
if(!temp || !temp.is_usable())
H << "\red You can't use your hand."
H << "<font color='red'>You can't use your hand.</font>"
return
H.break_cloak()
..()
@@ -27,7 +27,7 @@
if(!hit_zone)
H.do_attack_animation(src)
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[H] reaches for [src], but misses!</B>")
visible_message("<font color='red'><B>[H] reaches for [src], but misses!</B></font>")
return 0
if(H != src && check_shields(0, null, H, H.zone_sel.selecting, H.name))
@@ -39,7 +39,7 @@
var/damage = rand(0, 9)
if(!damage)
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[H] has attempted to punch [src]!</B>")
visible_message("<font color='red'><B>[H] has attempted to punch [src]!</B></font>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
@@ -50,14 +50,14 @@
playsound(loc, "punch", 25, 1, -1)
visible_message("\red <B>[H] has punched [src]!</B>")
visible_message("<font color='red'><B>[H] has punched [src]!</B></font>")
if(armor_soak >= damage)
return
apply_damage(damage, HALLOSS, affecting, armor_block, armor_soak)
if(damage >= 9)
visible_message("\red <B>[H] has weakened [src]!</B>")
visible_message("<font color='red'><B>[H] has weakened [src]!</B></font>")
apply_effect(4, WEAKEN, armor_block)
return
@@ -207,7 +207,7 @@
miss_type = 1
if(prob(80))
hit_zone = ran_zone(hit_zone)
hit_zone = ran_zone(hit_zone, 70) //70% chance to hit what you're aiming at seems fair?
if(prob(15) && hit_zone != BP_TORSO) // Missed!
if(!src.lying)
attack_message = "[H] attempted to strike [src], but missed!"
@@ -248,13 +248,13 @@
rand_damage *= 2
real_damage = max(1, real_damage)
var/armour = run_armor_check(affecting, "melee")
var/soaked = get_armor_soak(affecting, "melee")
var/armour = run_armor_check(hit_zone, "melee")
var/soaked = get_armor_soak(hit_zone, "melee")
// Apply additional unarmed effects.
attack.apply_effects(H, src, armour, rand_damage, hit_zone)
// Finally, apply damage to target
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), affecting, armour, soaked, sharp=attack.sharp, edge=attack.edge)
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), hit_zone, armour, soaked, sharp=attack.sharp, edge=attack.edge)
if(I_DISARM)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Disarmed [src.name] ([src.ckey])</font>")
@@ -311,7 +311,7 @@
return
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] attempted to disarm [src]!</B>")
visible_message("<font color='red'> <B>[M] attempted to disarm [src]!</B></font>")
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
@@ -80,6 +80,12 @@
amount += O.brute_dam
return amount
/mob/living/carbon/human/getActualBruteLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs) // Unlike the above, robolimbs DO count.
amount += O.brute_dam
return amount
/mob/living/carbon/human/getFireLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs)
@@ -96,6 +102,12 @@
amount += O.burn_dam
return amount
/mob/living/carbon/human/getActualFireLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs) // Unlike the above, robolimbs DO count.
amount += O.burn_dam
return amount
/mob/living/carbon/human/adjustBruteLoss(var/amount)
amount = amount*species.brute_mod
if(amount > 0)
@@ -185,6 +197,26 @@
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
..()
/mob/living/carbon/human/proc/Stasis(amount)
if((species.flags & NO_SCAN) || isSynthetic())
in_stasis = 0
else
in_stasis = amount
/mob/living/carbon/human/proc/getStasis()
if((species.flags & NO_SCAN) || isSynthetic())
return 0
return in_stasis
//This determines if, RIGHT NOW, the life() tick is being skipped due to stasis
/mob/living/carbon/human/proc/inStasisNow()
var/stasisValue = getStasis()
if(stasisValue && (life_tick % stasisValue))
return 1
return 0
/mob/living/carbon/human/getCloneLoss()
if((species.flags & NO_SCAN) || isSynthetic())
cloneloss = 0
@@ -94,7 +94,7 @@ emp_act
var/obj/item/organ/external/organ = organs_by_name[organ_name]
if(organ)
var/weight = organ_rel_size[organ_name]
armorval += getarmor_organ(organ, type) * weight
armorval += (getarmor_organ(organ, type) * weight)
total += weight
return (armorval/max(total, 1))
@@ -355,6 +355,9 @@ emp_act
//this proc handles being hit by a thrown atom
/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)
// if(buckled && buckled == AM)
// return // Don't get hit by the thing we're buckled to.
if(istype(AM,/obj/))
var/obj/O = AM
@@ -399,7 +402,7 @@ emp_act
var/obj/item/organ/external/affecting = get_organ(zone)
var/hit_area = affecting.name
src.visible_message("\red [src] has been hit in the [hit_area] by [O].")
src.visible_message("<font color='red'>[src] has been hit in the [hit_area] by [O].</font>")
if(ismob(O.thrower))
var/mob/M = O.thrower
@@ -451,7 +454,7 @@ emp_act
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
visible_message("<font color='red'>[src] staggers under the impact!</font>","<font color='red'>You stagger under the impact!</font>")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!O || !src) return
@@ -95,3 +95,5 @@
var/identifying_gender // In case the human identifies as another gender than it's biological
var/step_count = 0 // Track how many footsteps have been taken to know when to play footstep sounds
can_be_antagged = TRUE
@@ -90,6 +90,24 @@
return 0
// Returns a string based on what kind of brain the FBP has.
/mob/living/carbon/human/proc/get_FBP_type()
if(!isSynthetic())
return FBP_NONE
var/obj/item/organ/internal/brain/B
B = internal_organs_by_name[O_BRAIN]
if(B) // Incase we lost our brain for some reason, like if we got decapped.
if(istype(B, /obj/item/organ/internal/mmi_holder))
var/obj/item/organ/internal/mmi_holder/mmi_holder = B
if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/posibrain))
return FBP_POSI
else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/robot))
return FBP_DRONE
else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi)) // This needs to come last because inheritence.
return FBP_CYBORG
return FBP_NONE
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH
#undef HUMAN_EATING_BLOCKED_MOUTH
@@ -13,9 +13,11 @@
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
if(force_max_speed)
return -3 // Returning -1 will actually result in a slowdown for Teshari.
return -3
for(var/datum/modifier/M in modifiers)
if(!isnull(M.haste) && M.haste == TRUE)
return -3 // Returning -1 will actually result in a slowdown for Teshari.
if(!isnull(M.slowdown))
tally += M.slowdown
@@ -33,7 +35,7 @@
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || E.is_stump())
tally += 4
if(E.splinted)
else if(E.splinted)
tally += 0.5
else if(E.status & ORGAN_BROKEN)
tally += 1.5
@@ -84,9 +86,7 @@
if(T && T.movement_cost)
tally += T.movement_cost
if(species.item_slowdown_halved)
if(item_tally > 0)
item_tally *= 0.5
item_tally *= species.item_slowdown_mod
tally += item_tally
@@ -38,7 +38,6 @@
if(prob(75))
T.Weaken(rand(0.5,3))
else
src.Weaken(rand(2,4))
failed = 1
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
@@ -47,7 +46,7 @@
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] [failed ? "tried to tackle" : "has tackled"] down []!</B>", src, T), 1)
O.show_message(text("<font color='red'><B>[] [failed ? "tried to tackle" : "has tackled"] down []!</font></B>", src, T), 1)
/mob/living/carbon/human/proc/commune()
set category = "Abilities"
@@ -77,12 +76,12 @@
log_say("[key_name(src)] communed to [key_name(M)]: [text]")
M << "\blue Like lead slabs crashing into the ocean, alien thoughts drop into your mind: [text]"
M << "<font color='blue'>Like lead slabs crashing into the ocean, alien thoughts drop into your mind: [text]</font>"
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.name == src.species.name)
return
H << "\red Your nose begins to bleed..."
H << "<font color='red'>Your nose begins to bleed...</font>"
H.drip(1)
/mob/living/carbon/human/proc/regurgitate()
@@ -95,7 +94,7 @@
if(M in stomach_contents)
stomach_contents.Remove(M)
M.loc = loc
src.visible_message("\red <B>[src] hurls out the contents of their stomach!</B>")
src.visible_message("<font color='red'><B>[src] hurls out the contents of their stomach!</B></font>")
return
/mob/living/carbon/human/proc/psychic_whisper(mob/M as mob in oview())
@@ -106,8 +105,8 @@
var/msg = sanitize(input("Message:", "Psychic Whisper") as text|null)
if(msg)
log_say("PsychicWhisper: [key_name(src)]->[M.key] : [msg]")
M << "\green You hear a strange, alien voice in your head... \italic [msg]"
src << "\green You said: \"[msg]\" to [M]"
M << "<font color='green'>You hear a strange, alien voice in your head... <i>[msg]</i></font>"
src << "<font color='green'>You said: \"[msg]\" to [M]</font>"
return
/mob/living/carbon/human/proc/diona_split_nymph()
@@ -162,6 +161,10 @@
sleep(50)
var/output = "<span class='notice'>Self-Diagnostic Results:\n</span>"
output += "Internal Temperature: [convert_k2c(bodytemperature)] Degrees Celsius\n"
output += "Current Battery Charge: [nutrition]\n"
for(var/obj/item/organ/external/EO in organs)
if(EO.brute_dam || EO.burn_dam)
output += "[EO.name] - <span class='warning'>[EO.burn_dam + EO.brute_dam > ROBOLIMB_REPAIR_CAP ? "Heavy Damage" : "Light Damage"]</span>\n"
@@ -243,7 +246,8 @@
// Replace completely missing limbs.
for(var/limb_type in src.species.has_limbs)
var/obj/item/organ/external/E = src.organs_by_name[limb_type]
E.disfigured = 0
if(E && E.disfigured)
E.disfigured = 0
if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
E.removed()
qdel(E)
@@ -10,7 +10,7 @@
delete_inventory()
/mob/living/carbon/human/skrell/New(var/new_loc)
h_style = "Skrell Male Tentacles"
h_style = "Skrell Short Tentacles"
..(new_loc, "Skrell")
/mob/living/carbon/human/tajaran/New(var/new_loc)
@@ -32,6 +32,9 @@
h_style = "Teshari Default"
..(new_loc, "Teshari")
/mob/living/carbon/human/promethean/New(var/new_loc)
..(new_loc, "Promethean")
/mob/living/carbon/human/machine/New(var/new_loc)
h_style = "blue IPC screen"
..(new_loc, "Machine")
@@ -19,7 +19,7 @@ This saves us from having to call add_fingerprint() any time something is put in
else
update_inv_r_hand(0)
else
H << "\red You are unable to equip that."
H << "<font color='red'>You are unable to equip that.</font>"
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
for (var/slot in slots)
@@ -293,7 +293,7 @@ This saves us from having to call add_fingerprint() any time something is put in
var/obj/item/clothing/under/uniform = src.w_uniform
uniform.attackby(W,src)
else
src << "\red You are trying to eqip this item to an unsupported inventory slot. How the heck did you manage that? Stop it..."
src << "<font color='red'>You are trying to eqip this item to an unsupported inventory slot. How the heck did you manage that? Stop it...</font>"
return
if((W == src.l_hand) && (slot != slot_l_hand))
+46 -30
View File
@@ -4,7 +4,7 @@
#define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
#define HUMAN_CRIT_MAX_OXYLOSS ( 2.0 / 6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks. last_tick_duration = ~2.0 on average
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_1 5 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 10 //Amount of damage applied when your body temperature passes the 400K point
#define HEAT_DAMAGE_LEVEL_3 20 //Amount of damage applied when your body temperature passes the 1000K point
@@ -62,8 +62,12 @@
voice = GetVoice()
var/stasis = inStasisNow()
if(getStasis() > 2)
Sleeping(20)
//No need to update all of these procs if the guy is dead.
if(stat != DEAD && !in_stasis)
if(stat != DEAD && !stasis)
//Updates the number of stored chemicals for powers
handle_changeling()
@@ -82,7 +86,6 @@
if(!client)
species.handle_npc(src)
if(!handle_some_updates())
return //We go ahead and process them 5 times for HUD images and other stuff though.
@@ -97,7 +100,7 @@
return 1
/mob/living/carbon/human/breathe()
if(!in_stasis)
if(!inStasisNow())
..()
// Calculate how vulnerable the human is to under- and overpressure.
@@ -155,7 +158,7 @@
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1))
src << "\red You have a seizure!"
src << "<font color='red'>You have a seizure!</font>"
for(var/mob/O in viewers(src, null))
if(O == src)
continue
@@ -207,7 +210,7 @@
/mob/living/carbon/human/handle_mutations_and_radiation()
if(in_stasis)
if(inStasisNow())
return
if(getFireLoss())
@@ -620,31 +623,35 @@
if(bodytemperature >= species.heat_level_1)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
if(status_flags & GODMODE)
return 1 //godmode
var/burn_dam = 0
switch(bodytemperature)
if(species.heat_level_1 to species.heat_level_2)
burn_dam = HEAT_DAMAGE_LEVEL_1
if(species.heat_level_2 to species.heat_level_3)
burn_dam = HEAT_DAMAGE_LEVEL_2
if(species.heat_level_3 to INFINITY)
burn_dam = HEAT_DAMAGE_LEVEL_3
// switch() can't access numbers inside variables, so we need to use some ugly if() spam ladder.
if(bodytemperature >= species.heat_level_3)
burn_dam = HEAT_DAMAGE_LEVEL_3
else if(bodytemperature >= species.heat_level_2)
burn_dam = HEAT_DAMAGE_LEVEL_2
else if(bodytemperature >= species.heat_level_1)
burn_dam = HEAT_DAMAGE_LEVEL_1
take_overall_damage(burn=burn_dam, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
else if(bodytemperature <= species.cold_level_1)
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
if(status_flags & GODMODE)
return 1 //godmode
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/burn_dam = 0
switch(bodytemperature)
if(species.cold_level_1 to species.cold_level_2)
burn_dam = COLD_DAMAGE_LEVEL_1
if(species.cold_level_2 to species.cold_level_3)
burn_dam = COLD_DAMAGE_LEVEL_2
if(species.cold_level_3 to -INFINITY)
burn_dam = COLD_DAMAGE_LEVEL_3
if(bodytemperature <= species.cold_level_3)
burn_dam = COLD_DAMAGE_LEVEL_3
else if(bodytemperature <= species.cold_level_2)
burn_dam = COLD_DAMAGE_LEVEL_2
else if(bodytemperature <= species.heat_level_1)
burn_dam = COLD_DAMAGE_LEVEL_1
take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
@@ -789,7 +796,7 @@
/mob/living/carbon/human/handle_chemicals_in_body()
if(in_stasis)
if(inStasisNow())
return
if(reagents)
@@ -1125,10 +1132,16 @@
see_invisible = SEE_INVISIBLE_LIVING
seer = 0
if(!seedarkness)
sight = species.get_vision_flags(src)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_NOLIGHTING
else
sight = species.get_vision_flags(src)
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
var/tmp/glasses_processed = 0
var/obj/item/weapon/rig/rig = back
if(istype(rig) && rig.visor)
@@ -1147,7 +1160,7 @@
if(!glasses_processed && (species.get_vision_flags(src) > 0))
sight |= species.get_vision_flags(src)
if(!seer && !glasses_processed)
if(!seer && !glasses_processed && seedarkness)
see_invisible = SEE_INVISIBLE_LIVING
if(healths)
@@ -1172,7 +1185,7 @@
// Apply a fire overlay if we're burning.
if(on_fire)
health_images += image('icons/mob/screen1_health.dmi',"burning")
health_images += image('icons/mob/OnFire.dmi',"[get_fire_icon_state()]")
// Show a general pain/crit indicator if needed.
if(trauma_val)
@@ -1339,7 +1352,7 @@
if(!druggy && !seer) see_invisible = SEE_INVISIBLE_LIVING
/mob/living/carbon/human/handle_random_events()
if(in_stasis)
if(inStasisNow())
return
// Puke if toxloss is too high
@@ -1664,14 +1677,17 @@
if(..())
return
var/burn_temperature = fire_burn_temperature()
var/thermal_protection = get_heat_protection(burn_temperature)
var/thermal_protection = get_heat_protection(fire_stacks * 1500) // Arbitrary but below firesuit max temp when below 20 stacks.
if (thermal_protection < 1 && bodytemperature < burn_temperature)
bodytemperature += round(BODYTEMP_HEATING_MAX*(1-thermal_protection), 1)
if(thermal_protection == 1) // Immune.
return
else
bodytemperature += (BODYTEMP_HEATING_MAX + (fire_stacks * 15)) * (1-thermal_protection)
/mob/living/carbon/human/rejuvenate()
restore_blood()
shock_stage = 0
traumatic_shock = 0
..()
#undef HUMAN_MAX_OXYLOSS
+10 -1
View File
@@ -38,6 +38,15 @@
say(temp)
winset(client, "input", "text=[null]")
/mob/living/carbon/human/speech_bubble_appearance()
if(isSynthetic())
var/datum/robolimb/robo = isSynthetic()
return robo.speech_bubble_appearance
else
if(species)
return species.speech_bubble_appearance
return "normal"
/mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null)
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
@@ -55,7 +64,7 @@
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if (istype(other, /mob/living/carbon/slime))
if (istype(other, /mob/living/simple_animal/slime))
return 1
//This is already covered by mob/say_understands()
@@ -13,6 +13,9 @@
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/speech_bubble_appearance = "normal" // Part of icon_state to use for speech bubbles when talking. See talk.dmi for available icons.
var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire.
// Damage overlay and masks.
var/damage_overlays = 'icons/mob/human_races/masks/dam_human.dmi'
var/damage_mask = 'icons/mob/human_races/masks/dam_mask_human.dmi'
@@ -133,7 +136,7 @@
var/appearance_flags = 0 // Appearance/display related features.
var/spawn_flags = 0 // Flags that specify who can spawn as this species
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/item_slowdown_halved = 0 // If this is on, they're not as affected by item weights for slowdown
var/item_slowdown_mod = 1 // How affected by item slowdown the species is.
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/holder_type
@@ -57,11 +57,22 @@
damage = 5
shredding = 1
/datum/unarmed_attack/claws/strong/xeno
attack_verb = list("slashed", "gouged", "stabbed")
damage = 10
/datum/unarmed_attack/claws/strong/xeno/queen
attack_verb = list("slashed", "gouged", "stabbed", "gored")
damage = 15
/datum/unarmed_attack/bite/strong
attack_verb = list("mauled")
damage = 8
shredding = 1
/datum/unarmed_attack/bite/strong/xeno
damage = 10
/datum/unarmed_attack/slime_glomp
attack_verb = list("glomped")
attack_noun = list("body")
@@ -20,6 +20,7 @@
dusted_anim = "dust-m"
death_message = "lets out a faint chimper as it collapses and stops moving..."
tail = "chimptail"
fire_icon_state = "monkey"
unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws)
inherent_verbs = list(/mob/living/proc/ventcrawl)
@@ -14,46 +14,50 @@ var/datum/species/shapeshifter/promethean/prometheans
blood_color = "#05FF9B"
flesh_color = "#05FFFB"
hunger_factor = DEFAULT_HUNGER_FACTOR //todo
hunger_factor = 0.2
reagent_tag = IS_SLIME
mob_size = MOB_SMALL
bump_flag = SLIME
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS | HAS_UNDERWEAR
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
health_hud_intensity = 2
num_alternate_languages = 3
breath_type = null
poison_type = null
speech_bubble_appearance = "slime"
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
gluttonous = 1
virus_immune = 1
blood_volume = 560
min_age = 1
max_age = 5
brute_mod = 0.5
burn_mod = 2
oxy_mod = 0
total_health = 120
gluttonous = 1
virus_immune = 1
blood_volume = 560
min_age = 1
max_age = 5
brute_mod = 0.75
burn_mod = 2
oxy_mod = 0
cold_level_1 = 260
cold_level_2 = 200
cold_level_3 = 120
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 130 //Default 120
heat_level_1 = 360
heat_level_2 = 400
heat_level_3 = 1000
heat_level_1 = 320 //Default 360
heat_level_2 = 370 //Default 400
heat_level_3 = 600 //Default 1000
body_temperature = 310.15
siemens_coefficient = -1
siemens_coefficient = 0.3
rarity_value = 5
genders = list(MALE, FEMALE, NEUTER, PLURAL)
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime) // Slime core.
has_limbs = list(
@@ -83,7 +87,7 @@ var/datum/species/shapeshifter/promethean/prometheans
valid_transform_species = list("Human", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey")
monochromatic = 1
var/heal_rate = 5 // Temp. Regen per tick.
var/heal_rate = 0.5 // Temp. Regen per tick.
/datum/species/shapeshifter/promethean/New()
..()
@@ -133,7 +137,12 @@ var/datum/species/shapeshifter/promethean/prometheans
if(istype(T))
var/obj/effect/decal/cleanable/C = locate() in T
if(C)
if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))
return
qdel(C)
if (istype(T, /turf/simulated))
var/turf/simulated/S = T
S.dirt = 0
H.nutrition += rand(15, 45)
// Heal remaining damage.
@@ -13,6 +13,12 @@
max_age = 45
health_hud_intensity = 3
male_cough_sounds = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg')
female_cough_sounds = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg')
male_sneeze_sound = 'sound/effects/mob_effects/tesharisneeze.ogg'
female_sneeze_sound = 'sound/effects/mob_effects/tesharisneeze.ogg'
blood_color = "#D514F7"
flesh_color = "#5F7BB0"
base_color = "#001144"
@@ -26,6 +32,8 @@
damage_mask = 'icons/mob/human_races/masks/dam_mask_seromi.dmi'
blood_mask = 'icons/mob/human_races/masks/blood_seromi.dmi'
fire_icon_state = "generic" // Humanoid is too big for them and spriting a new one is really annoying.
slowdown = -1
total_health = 50
brute_mod = 1.35
@@ -95,5 +103,4 @@
/datum/species/teshari/equip_survival_gear(var/mob/living/carbon/human/H)
..()
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)
@@ -37,7 +37,7 @@
brute_mod = 0.85
burn_mod = 0.85
metabolic_rate = 0.85
item_slowdown_halved = 1
item_slowdown_mod = 0.5
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_UNATHI)
name_language = LANGUAGE_UNATHI
@@ -46,7 +46,7 @@
min_age = 32
max_age = 260
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
blurb = "A heavily reptillian species, Unathi hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, inhospitable \
planet, they mostly hold ideals of honesty, virtue, proficiency and bravery above all \
else, frequently even their own lives. They prefer warmer temperatures than most species and \
@@ -256,6 +256,7 @@
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
name_language = LANGUAGE_ROOTLOCAL
health_hud_intensity = 2.5
item_slowdown_mod = 0.25
min_age = 1
max_age = 300
@@ -318,6 +319,7 @@
reagent_tag = IS_DIONA
genders = list(PLURAL)
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/carbon/alien/diona/D = other
if(istype(D))
@@ -0,0 +1,161 @@
// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
/*
/obj/item/alien_embryo //Commented out as reference for future reproduction methods, or addition later.
name = "alien embryo"
desc = "All slimy and yuck."
icon = 'icons/mob/alien.dmi'
icon_state = "larva0_dead"
var/mob/living/affected_mob
var/stage = 0
/obj/item/alien_embryo/New()
if(istype(loc, /mob/living))
affected_mob = loc
processing_objects.Add(src)
spawn(0)
AddInfectionImages(affected_mob)
else
qdel(src)
/obj/item/alien_embryo/Destroy()
if(affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
spawn(0)
RemoveInfectionImages(affected_mob)
..()
/obj/item/alien_embryo/process()
if(!affected_mob) return
if(loc != affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
processing_objects.Remove(src)
spawn(0)
RemoveInfectionImages(affected_mob)
affected_mob = null
return
if(stage < 5 && prob(3))
stage++
spawn(0)
RefreshInfectionImage(affected_mob)
switch(stage)
if(2, 3)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
affected_mob << "<span class='danger'>Your throat feels sore.</span>"
if(prob(1))
affected_mob << "<span class='danger'>Mucous runs down the back of your throat.</span>"
if(4)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(2))
affected_mob << "<span class='danger'> Your muscles ache.</span>"
if(prob(20))
affected_mob.take_organ_damage(1)
if(prob(2))
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
if(prob(20))
affected_mob.adjustToxLoss(1)
affected_mob.updatehealth()
if(5)
affected_mob << "<span class='danger'>You feel something tearing its way out of your stomach...</span>"
affected_mob.adjustToxLoss(10)
affected_mob.updatehealth()
if(prob(50))
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
var/list/candidates = get_alien_candidates()
var/picked = null
// To stop clientless larva, we will check that our host has a client
// if we find no ghosts to become the alien. If the host has a client
// he will become the alien but if he doesn't then we will set the stage
// to 2, so we don't do a process heavy check everytime.
if(candidates.len)
picked = pick(candidates)
else if(affected_mob.client)
picked = affected_mob.key
else
stage = 4 // Let's try again later.
return
if(affected_mob.lying)
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
else
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
spawn(6)
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
new_xeno.key = picked
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
qdel(src)
/*----------------------------------------
Proc: RefreshInfectionImage()
Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
----------------------------------------*/
/obj/item/alien_embryo/proc/RefreshInfectionImage()
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)
for(var/mob/living/L in mob_list)
if(iscorgi(L) || iscarbon(L))
if(L.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: AddInfectionImages(C)
Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
----------------------------------------*/
/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
if(C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
----------------------------------------*/
/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien in player_list)
if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
if(alien.client)
for(var/image/I in alien.client.images)
if(I.loc == C)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)
*/
@@ -0,0 +1,222 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//TODO: Make these simple_animals
/* //Commented out as reference for future reproduction methods, or addition later if needed. - Mech
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
var/const/MAX_IMPREGNATION_TIME = 150
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger
name = "alien"
desc = "It has some sort of a tube at the end of its tail."
icon = 'icons/mob/alien.dmi'
icon_state = "facehugger"
item_state = "facehugger"
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = PROXMOVE
body_parts_covered = FACE|EYES
throw_range = 5
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/strength = 5
var/attached = 0
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
if(Attach(user))
return
..()
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
..()
user.drop_from_inventory(src)
Attach(M)
/obj/item/clothing/mask/facehugger/New()
if(config.aliens_allowed)
..()
else
qdel(src)
/obj/item/clothing/mask/facehugger/examine(mob/user)
..(user)
switch(stat)
if(DEAD,UNCONSCIOUS)
user << "<span class='danger'><b>[src] is not moving.</b></span>"
if(CONSCIOUS)
user << "<span class='danger'><b>[src] seems to be active.</b></span>"
if (sterile)
user << "<span class='danger'><b>It looks like the proboscis has been removed.</b></span>"
return
/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
if(I.force)
user.do_attack_animation(src)
Die()
return
/obj/item/clothing/mask/facehugger/bullet_act()
Die()
return
/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C+80)
Die()
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
..()
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
HasProximity(target)
return
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
if(stat == CONSCIOUS)
HasProximity(finder)
return 1
return
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
if(CanHug(AM))
Attach(AM)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
spawn(15)
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"
throwing = 0
GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if((!iscorgi(M) && !iscarbon(M)))
return
if(attached)
return
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
return
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
var/mob/living/L = M //just so I don't need to use :
if(loc == L) return
if(stat != CONSCIOUS) return
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
L.visible_message("<span class='danger'><b> [src] leaps at [L]'s face!</b></span>")
if(iscarbon(M))
var/mob/living/carbon/target = L
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
target.visible_message("<span class='danger'><b> [src] tears [W] off of [target]'s face!"</b></span>)
target.equip_to_slot(src, slot_wear_mask)
target.contents += src // Monkey sanity check - Snapshot
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
GoIdle() //so it doesn't jump the people that tear it off
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(L)
return
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
return
if(!sterile)
new /obj/item/alien_embryo(target)
target.status_flags |= XENO_HOST
target.visible_message("<span class='danger'><b> [src] falls limp after violating [target]'s face!</b></span>")
Die()
icon_state = "[initial(icon_state)]_impregnated"
else
target.visible_message("<span class='danger'><b> [src] violates [target]'s face!</b></span>")
return
/obj/item/clothing/mask/facehugger/proc/GoActive()
if(stat == DEAD || stat == CONSCIOUS)
return
stat = CONSCIOUS
icon_state = "[initial(icon_state)]"
return
/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
if(stat == DEAD || stat == UNCONSCIOUS)
return
/* RemoveActiveIndicators() */
stat = UNCONSCIOUS
icon_state = "[initial(icon_state)]_inactive"
spawn(rand(min_time,max_time))
GoActive()
return
/obj/item/clothing/mask/facehugger/proc/Die()
if(stat == DEAD)
return
/* RemoveActiveIndicators() */
icon_state = "[initial(icon_state)]_dead"
stat = DEAD
src.visible_message("<span class='danger'><b>[src] curls up into a ball!</b></span>")
return
/proc/CanHug(var/mob/M)
if(iscorgi(M))
return 1
if(!iscarbon(M))
return 0
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
return 0
return 1
*/
@@ -0,0 +1,356 @@
/proc/alien_queen_exists(var/ignore_self,var/mob/living/carbon/human/self)
for(var/mob/living/carbon/human/Q in living_mob_list)
if(self && ignore_self && self == Q)
continue
if(Q.species.name != "Xenomorph Queen")
continue
if(!Q.key || !Q.client || Q.stat)
continue
return 1
return 0
/mob/living/carbon/human/proc/gain_plasma(var/amount)
var/obj/item/organ/internal/xenos/plasmavessel/I = internal_organs_by_name[O_PLASMA]
if(!istype(I)) return
if(amount)
I.stored_plasma += amount
I.stored_plasma = max(0,min(I.stored_plasma,I.max_plasma))
/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ) //Returns 1 if the ability is clear for usage.
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA]
if(!istype(P))
src << "<span class='danger'>Your plasma vessel has been removed!</span>"
return
if(needs_organ)
var/obj/item/organ/internal/I = internal_organs_by_name[needs_organ]
if(!I)
src << "<span class='danger'>Your [needs_organ] has been removed!</span>"
return
else if((I.status & ORGAN_CUT_AWAY) || I.is_broken())
src << "<span class='danger'>Your [needs_organ] is too damaged to function!</span>"
return
if(P.stored_plasma < cost)
src << "<span class='danger'>You don't have enough phoron stored to do that.</span>"
return 0
if(needs_foundation)
var/turf/T = get_turf(src)
var/has_foundation
if(T)
//TODO: Work out the actual conditions this needs.
if(!(istype(T,/turf/space)))
has_foundation = 1
if(!has_foundation)
src << "<span class='danger'>You need a solid foundation to do that on.</span>"
return 0
P.stored_plasma -= cost
return 1
// Free abilities.
/mob/living/carbon/human/proc/transfer_plasma(mob/living/carbon/human/M as mob in oview())
set name = "Transfer Plasma"
set desc = "Transfer Plasma to another alien"
set category = "Abilities"
if (get_dist(src,M) <= 1)
src << "<span class='alium'>You need to be closer.</span>"
return
var/obj/item/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name[O_PLASMA]
if(!istype(I))
src << "<span class='alium'>Their plasma vessel is missing.</span>"
return
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
if (amount)
amount = abs(round(amount))
if(check_alien_ability(amount,0,O_PLASMA))
M.gain_plasma(amount)
M << "<span class='alium'>[src] has transfered [amount] plasma to you.</span>"
src << "<span class='alium'>You have transferred [amount] plasma to [M].</span>"
return
// Queen verbs.
/mob/living/carbon/human/proc/lay_egg()
set name = "Lay Egg (75)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
set category = "Abilities"
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
if(locate(/obj/effect/alien/egg) in get_turf(src))
src << "There's already an egg here."
return
if(check_alien_ability(75,1,O_EGG))
visible_message("<span class='alium'><B>[src] has laid an egg!</B></span>")
new /obj/effect/alien/egg(loc)
return
// Drone verbs.
/mob/living/carbon/human/proc/evolve()
set name = "Evolve (500)"
set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
set category = "Abilities"
if(alien_queen_exists())
src << "<span class='notice'>We already have an active queen.</span>"
return
if(check_alien_ability(500))
visible_message("<span class='alium'><B>[src] begins to twist and contort!</B></span>", "<span class='alium'>You begin to evolve!</span>")
src.set_species("Xenomorph Queen")
return
/mob/living/carbon/human/proc/plant()
set name = "Plant Weeds (50)"
set desc = "Plants some alien weeds"
set category = "Abilities"
if(check_alien_ability(50,1,O_RESIN))
visible_message("<span class='alium'><B>[src] has planted some alien weeds!</B></span>")
new /obj/effect/alien/weeds/node(loc)
return
/mob/living/carbon/human/proc/Spit(var/atom/A)
if((last_spit + 1 SECONDS) > world.time) //To prevent YATATATATATAT spitting.
to_chat(src, "<span class='warning'>You have not yet prepared your chemical glands. You must wait before spitting again.</span>")
return
else
last_spit = world.time
if(spitting && incapacitated(INCAPACITATION_DISABLED))
to_chat(src, "You cannot spit in your current state.")
spitting = 0
return
else if(spitting)
if(!check_alien_ability(20,0,O_ACID))
spitting = 0
return
visible_message("<span class='warning'>[src] spits [spit_name] at \the [A]!</span>", "<span class='alium'>You spit [spit_name] at \the [A].</span>")
var/obj/item/projectile/P = new spit_projectile(get_turf(src))
P.firer = src
P.launch(A)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 0)
else
..()
/mob/living/carbon/human/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
set name = "Corrosive Acid (200)"
set desc = "Drench an object in acid, destroying it over time."
set category = "Abilities"
if(!O in oview(1))
src << "<span class='alium'>[O] is too far away.</span>"
return
// OBJ CHECK
var/cannot_melt
if(isobj(O))
var/obj/I = O
if(I.unacidable)
cannot_melt = 1
else
if(istype(O, /turf/simulated/wall))
var/turf/simulated/wall/W = O
if(W.material.flags & MATERIAL_UNMELTABLE)
cannot_melt = 1
else if(istype(O, /turf/simulated/floor))
/* var/turf/simulated/floor/F = O //Turfs are qdel'd to space (Even asteroid tiles), will need to be touched by someone smarter than myself. -Mech
if(F.flooring && (F.flooring.flags & TURF_ACID_IMMUNE))
*/
cannot_melt = 1
if(cannot_melt)
src << "<span class='alium'>You cannot dissolve this object.</span>"
return
if(check_alien_ability(200,0,O_ACID))
new /obj/effect/alien/acid(get_turf(O), O)
visible_message("<span class='alium'><B>[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!</B></span>")
return
/mob/living/carbon/human/proc/neurotoxin()
set name = "Toggle Neurotoxic Spit (40)"
set desc = "Readies a neurotoxic spit, which paralyzes the target for a short time if they are not wearing protective gear."
set category = "Abilities"
if(spitting)
to_chat(src, "<span class='alium'>You stop preparing to spit.</span>")
spitting = 0
return
if(!check_alien_ability(40,0,O_ACID))
spitting = 0
return
else
last_spit = world.time
spitting = 1
spit_projectile = /obj/item/projectile/energy/neurotoxin
spit_name = "neurotoxin"
to_chat(src, "<span class='alium'>You prepare to spit neurotoxin.</span>")
/mob/living/carbon/human/proc/acidspit()
set name = "Toggle Acid Spit (50)"
set desc = "Readies an acidic spit, which burns the target if they are not wearing protective gear."
set category = "Abilities"
if(spitting)
to_chat(src, "<span class='alium'>You stop preparing to spit.</span>")
spitting = 0
return
if(!check_alien_ability(50,0,O_ACID))
spitting = 0
return
else
last_spit = world.time
spitting = 1
spit_projectile = /obj/item/projectile/energy/acid
spit_name = "acid"
to_chat(src, "<span class='alium'>You prepare to spit acid.</span>")
/mob/living/carbon/human/proc/resin() // -- TLE
set name = "Secrete Resin (75)"
set desc = "Secrete tough malleable resin."
set category = "Abilities"
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
if(!choice)
return
if(!check_alien_ability(75,1,O_RESIN))
return
visible_message("<span class='warning'><B>[src] vomits up a thick purple substance and begins to shape it!</B></span>", "<span class='alium'>You shape a [choice].</span>")
switch(choice)
if("resin door")
new /obj/structure/simple_door/resin(loc)
if("resin wall")
new /obj/effect/alien/resin/wall(loc)
if("resin membrane")
new /obj/effect/alien/resin/membrane(loc)
if("resin nest")
new /obj/structure/bed/nest(loc)
return
/mob/living/carbon/human/proc/leap()
set category = "Abilities"
set name = "Leap"
set desc = "Leap at a target and grab them aggressively."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
var/list/choices = list()
for(var/mob/living/M in view(6,src))
if(!istype(M,/mob/living/silicon))
choices += M
choices -= src
var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices
if(!T || !src || src.stat) return
if(get_dist(get_turf(T), get_turf(src)) > 4) return
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
last_special = world.time + 75
status_flags |= LEAPING
src.visible_message("<span class='danger'>\The [src] leaps at [T]!</span>")
src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
playsound(src.loc, 'sound/voice/hiss5.ogg', 50, 1)
sleep(5)
if(status_flags & LEAPING) status_flags &= ~LEAPING
if(!src.Adjacent(T))
src << "<span class='warning'>You miss!</span>"
return
T.Weaken(3)
var/use_hand = "left"
if(l_hand)
if(r_hand)
src << "<span class='danger'>You need to have one hand free to grab someone.</span>"
return
else
use_hand = "right"
src.visible_message("<span class='warning'><b>\The [src]</b> seizes [T] aggressively!</span>")
var/obj/item/weapon/grab/G = new(src,T)
if(use_hand == "left")
l_hand = G
else
r_hand = G
G.state = GRAB_PASSIVE
G.icon_state = "grabbed1"
G.synch()
/mob/living/carbon/human/proc/gut()
set category = "Abilities"
set name = "Gut"
set desc = "While grabbing someone aggressively, rip their guts out or tear them apart."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying)
src << "<span class='danger'>You cannot do that in your current state.</span>"
return
var/obj/item/weapon/grab/G = locate() in src
if(!G || !istype(G))
src << "<span class='danger'>You are not grabbing anyone.</span>"
return
if(G.state < GRAB_AGGRESSIVE)
src << "<span class='danger'>You must have an aggressive grab to gut your prey!</span>"
return
last_special = world.time + 50
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s body with its claws!</span>")
if(istype(G.affecting,/mob/living/carbon/human))
var/mob/living/carbon/human/H = G.affecting
H.apply_damage(50,BRUTE)
if(H.stat == 2)
H.gib()
else
var/mob/living/M = G.affecting
if(!istype(M)) return //wut
M.apply_damage(50,BRUTE)
if(M.stat == 2)
M.gib()
@@ -0,0 +1,330 @@
//Stand-in until this is made more lore-friendly.
/datum/species/xenos
name = "Xenomorph"
name_plural = "Xenomorphs"
default_language = "Xenomorph"
language = "Hivemind"
unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno, /datum/unarmed_attack/bite/strong/xeno)
hud_type = /datum/hud_data/alien
rarity_value = 3
has_fine_manipulation = 0
siemens_coefficient = 0
gluttonous = 2
brute_mod = 0.5 // Hardened carapace.
burn_mod = 2 // Weak to fire.
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT
spawn_flags = SPECIES_IS_RESTRICTED
reagent_tag = IS_XENOS
blood_color = "#05EE05"
flesh_color = "#282846"
gibbed_anim = "gibbed-a"
dusted_anim = "dust-a"
death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
death_sound = 'sound/voice/hiss6.ogg'
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
speech_chance = 100
breath_type = null
poison_type = null
vision_flags = SEE_SELF|SEE_MOBS
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
bump_flag = ALIEN
swap_flags = ~HEAVY
push_flags = (~HEAVY) ^ ROBOT
var/alien_number = 0
var/caste_name = "creature" // Used to update alien name.
var/weeds_heal_rate = 1 // Health regen on weeds.
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
/datum/species/xenos/get_bodytype()
return "Xenomorph"
/datum/species/xenos/get_random_name()
return "alien [caste_name] ([alien_number])"
/datum/species/xenos/can_understand(var/mob/other)
if(istype(other,/mob/living/carbon/alien/larva))
return 1
return 0
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
H.visible_message("<span class='notice'>[H] caresses [target] with its scythe-like arm.</span>", \
"<span class='notice'>You caress [target] with your scythe-like arm.</span>")
/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H)
if(H.mind)
H.mind.assigned_role = "Alien"
H.mind.special_role = "Alien"
alien_number++ //Keep track of how many aliens we've had so far.
H.real_name = "alien [caste_name] ([alien_number])"
H.name = H.real_name
..()
/datum/species/xenos/handle_environment_special(var/mob/living/carbon/human/H)
var/turf/T = H.loc
if(!T) return
var/datum/gas_mixture/environment = T.return_air()
if(!environment) return
if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
if(!regenerate(H))
var/obj/item/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name[O_PLASMA]
P.stored_plasma += weeds_plasma_rate
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
..()
/datum/species/xenos/proc/regenerate(var/mob/living/carbon/human/H)
var/heal_rate = weeds_heal_rate
var/mend_prob = 10
if (!H.resting)
heal_rate = weeds_heal_rate / 3
mend_prob = 1
//first heal damages
if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
H.adjustBruteLoss(-heal_rate)
H.adjustFireLoss(-heal_rate)
H.adjustOxyLoss(-heal_rate)
H.adjustToxLoss(-heal_rate)
if (prob(5))
H << "<span class='alium'>You feel a soothing sensation come over you...</span>"
return 1
//next internal organs
for(var/obj/item/organ/I in H.internal_organs)
if(I.damage > 0)
I.damage = max(I.damage - heal_rate, 0)
if (prob(5))
H << "<span class='alium'>You feel a soothing sensation within your [I.parent_organ]...</span>"
return 1
//next mend broken bones, approx 10 ticks each
for(var/obj/item/organ/external/E in H.bad_external_organs)
if (E.status & ORGAN_BROKEN)
if (prob(mend_prob))
if (E.mend_fracture())
H << "<span class='alium'>You feel something mend itself inside your [E.name].</span>"
return 1
return 0
/*
/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H)
H.AddInfectionImages()
..()
/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H)
H.RemoveInfectionImages()
..()
*/
/datum/species/xenos/drone
name = "Xenomorph Drone"
caste_name = "drone"
weeds_plasma_rate = 15
slowdown = 1
tail = "xenos_drone_tail"
rarity_value = 5
icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/evolve,
/mob/living/carbon/human/proc/resin,
/mob/living/carbon/human/proc/corrosive_acid
)
/datum/species/xenos/drone/handle_post_spawn(var/mob/living/carbon/human/H)
var/mob/living/carbon/human/A = H
if(!istype(A))
return ..()
..()
/datum/species/xenos/hunter
name = "Xenomorph Hunter"
weeds_plasma_rate = 5
caste_name = "hunter"
slowdown = -2
total_health = 150
tail = "xenos_hunter_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/hunter,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate
)
/datum/species/xenos/sentinel
name = "Xenomorph Sentinel"
weeds_plasma_rate = 10
caste_name = "sentinel"
slowdown = 0
total_health = 200
tail = "xenos_sentinel_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/sentinel,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin,
/mob/living/carbon/human/proc/acidspit
)
/datum/species/xenos/queen
name = "Xenomorph Queen"
total_health = 250
weeds_heal_rate = 5
weeds_plasma_rate = 20
caste_name = "queen"
slowdown = 4
tail = "xenos_queen_tail"
rarity_value = 10
icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno/queen, /datum/unarmed_attack/bite/strong/xeno)
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_BRAIN = /obj/item/organ/internal/brain/xeno,
O_EGG = /obj/item/organ/internal/xenos/eggsac,
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
O_ACID = /obj/item/organ/internal/xenos/acidgland,
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/lay_egg,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin,
/mob/living/carbon/human/proc/acidspit,
/mob/living/carbon/human/proc/resin
)
/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H)
..()
// Make sure only one official queen exists at any point.
if(!alien_queen_exists(1,H))
H.real_name = "alien queen ([alien_number])"
H.name = H.real_name
else
H.real_name = "alien princess ([alien_number])"
H.name = H.real_name
/datum/hud_data/alien
icon = 'icons/mob/screen1_alien.dmi'
has_a_intent = 1
has_m_intent = 1
has_warnings = 1
has_hands = 1
has_drop = 1
has_throw = 1
has_resist = 1
has_pressure = 0
has_nutrition = 0
has_bodytemp = 0
has_internals = 0
gear = list(
"o_clothing" = list("loc" = ui_belt, "name" = "Suit", "slot" = slot_wear_suit, "state" = "equip", "dir" = SOUTH),
"head" = list("loc" = ui_id, "name" = "Hat", "slot" = slot_head, "state" = "hair"),
"storage1" = list("loc" = ui_storage1, "name" = "Left Pocket", "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "name" = "Right Pocket", "slot" = slot_r_store, "state" = "pocket"),
)
@@ -0,0 +1,56 @@
proc/create_new_xenomorph(var/alien_caste,var/target)
target = get_turf(target)
if(!target || !alien_caste) return
var/mob/living/carbon/human/new_alien = new(target)
new_alien.set_species("Xenomorph [alien_caste]")
return new_alien
/mob/living/carbon/human/xdrone/New(var/new_loc)
h_style = "Bald"
faction = "xeno"
..(new_loc, "Xenomorph Drone")
/mob/living/carbon/human/xsentinel/New(var/new_loc)
h_style = "Bald"
faction = "xeno"
..(new_loc, "Xenomorph Sentinel")
/mob/living/carbon/human/xhunter/New(var/new_loc)
h_style = "Bald"
faction = "xeno"
..(new_loc, "Xenomorph Hunter")
/mob/living/carbon/human/xqueen/New(var/new_loc)
h_style = "Bald"
faction = "xeno"
..(new_loc, "Xenomorph Queen")
// I feel like we should generalize/condense down all the various icon-rendering antag procs.
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/*
/mob/living/carbon/human/proc/AddInfectionImages()
if (client)
for (var/mob/living/C in mob_list)
if(C.status_flags & XENO_HOST)
var/obj/item/alien_embryo/A = locate() in C
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
client.images += I
return
*/
/*----------------------------------------
Proc: RemoveInfectionImages()
Des: Removes all infected images from the alien.
----------------------------------------*/
/*
/mob/living/carbon/human/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
qdel(I)
return
*/
@@ -131,10 +131,11 @@ Please contact me on #coderbus IRC. ~Carn x
#define LEGCUFF_LAYER 23
#define L_HAND_LAYER 24
#define R_HAND_LAYER 25
#define FIRE_LAYER 26 //If you're on fire
#define WATER_LAYER 27 //If you're submerged in water.
#define TARGETED_LAYER 28 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 29
#define MODIFIER_EFFECTS_LAYER 26
#define FIRE_LAYER 27 //If you're on fire
#define WATER_LAYER 28 //If you're submerged in water.
#define TARGETED_LAYER 29 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 30
//////////////////////////////////
/mob/living/carbon/human
@@ -273,6 +274,9 @@ var/global/list/damage_icon_parts = list()
if(part.robotic >= ORGAN_ROBOT)
icon_key += "2[part.model ? "-[part.model]": ""]"
robolimb_count++
if(part.organ_tag == BP_HEAD || part.organ_tag == BP_TORSO || part.organ_tag == BP_GROIN)
robobody_count ++
else if(part.status & ORGAN_DEAD)
icon_key += "3"
else
@@ -439,7 +443,7 @@ var/global/list/damage_icon_parts = list()
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
..()
if(transforming) return
if(transforming || QDELETED(src)) return
update_mutations(0)
update_body(0)
@@ -1118,11 +1122,23 @@ var/global/list/damage_icon_parts = list()
if(update_icons) update_icons()
/mob/living/carbon/human/update_modifier_visuals(var/update_icons=1)
overlays_standing[MODIFIER_EFFECTS_LAYER] = null
var/image/effects = new()
for(var/datum/modifier/M in modifiers)
if(M.mob_overlay_state)
var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state)
effects.overlays += I
overlays_standing[MODIFIER_EFFECTS_LAYER] = effects
if(update_icons)
update_icons()
/mob/living/carbon/human/update_fire(var/update_icons=1)
overlays_standing[FIRE_LAYER] = null
if(on_fire)
overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"=FIRE_LAYER)
overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state" = get_fire_icon_state(), "layer"=FIRE_LAYER)
if(update_icons) update_icons()
@@ -16,7 +16,7 @@
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
src << "<font color='red'>You cannot send IC messages (muted).</font>"
return
if (stat)
return
@@ -86,7 +86,7 @@
src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate. You can also set your face with: \n\nnomood, pout, sad, angry, frown, smile"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
src << "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>"
if ((message && src.stat == 0))
if (m_type & 1)
for(var/mob/O in viewers(src, null))
+76 -51
View File
@@ -9,27 +9,27 @@
throw_speed = 3
throw_range = 6
origin_tech = list(TECH_BIO = 4)
var/Uses = 1 // uses before it goes inert
var/uses = 1 // uses before it goes inert
var/enhanced = 0 //has it been enhanced before?
flags = OPENCONTAINER
attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/slimesteroid2))
if(enhanced == 1)
user << "<span class='warning'> This extract has already been enhanced!</span>"
return ..()
if(Uses == 0)
user << "<span class='warning'> You can't enhance a used extract!</span>"
return ..()
user <<"You apply the enhancer. It now has triple the amount of uses."
Uses = 3
enhanced = 1
qdel(O)
/*
/obj/item/slime_extract/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/slimesteroid2))
if(enhanced == 1)
user << "<span class='warning'> This extract has already been enhanced!</span>"
return ..()
if(Uses == 0)
user << "<span class='warning'> You can't enhance a used extract!</span>"
return ..()
user <<"You apply the enhancer. It now has triple the amount of uses."
Uses = 3
enhanced = 1
qdel(O)
*/
/obj/item/slime_extract/New()
..()
create_reagents(100)
reagents.add_reagent("slimejelly", 30)
create_reagents(5)
// reagents.add_reagent("slimejelly", 30)
/obj/item/slime_extract/grey
name = "grey slime extract"
@@ -51,7 +51,7 @@
name = "purple slime extract"
icon_state = "purple slime extract"
/obj/item/slime_extract/darkpurple
/obj/item/slime_extract/dark_purple
name = "dark purple slime extract"
icon_state = "dark purple slime extract"
@@ -71,7 +71,7 @@
name = "blue slime extract"
icon_state = "blue slime extract"
/obj/item/slime_extract/darkblue
/obj/item/slime_extract/dark_blue
name = "dark blue slime extract"
icon_state = "dark blue slime extract"
@@ -119,41 +119,66 @@
name = "rainbow slime extract"
icon_state = "rainbow slime extract"
////Pet Slime Creation///
/obj/item/slimepotion
icon = 'icons/obj/chemical.dmi'
/obj/item/weapon/slimepotion
////Pet Slime Creation///
/*
/obj/item/slimepotion/docility
name = "docility potion"
desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
user << "<span class='warning'> The potion only works on baby slimes!</span>"
return ..()
if(M.is_adult) //Can't tame adults
user << "<span class='warning'> Only baby slimes can be tamed!</span>"
return..()
if(M.stat)
user << "<span class='warning'> The slime is dead!</span>"
return..()
if(M.mind)
user << "<span class='warning'> The slime resists!</span>"
return ..()
var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
pet.icon_state = "[M.colour] baby slime"
pet.icon_living = "[M.colour] baby slime"
pet.icon_dead = "[M.colour] baby slime dead"
pet.colour = "[M.colour]"
user <<"You feed the slime the potion, removing it's powers and calming it."
qdel(M)
var/newname = sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text, MAX_NAME_LEN)
/obj/item/slimepotion/docility/attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
user << "<span class='warning'> The potion only works on slimes!</span>"
return ..()
// if(M.is_adult) //Can't tame adults
// user << "<span class='warning'> Only baby slimes can be tamed!</span>"
// return..()
if(M.stat)
user << "<span class='warning'> The slime is dead!</span>"
return..()
if(M.mind)
user << "<span class='warning'> The slime resists!</span>"
return ..()
var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
pet.icon_state = "[M.colour] [M.is_adult ? "adult" : "baby"] slime"
pet.icon_living = "[M.colour] [M.is_adult ? "adult" : "baby"] slime"
pet.icon_dead = "[M.colour] [M.is_adult ? "adult" : "baby"] slime dead"
pet.colour = "[M.colour]"
to_chat(user, "You feed the slime the potion, removing it's powers and calming it.")
qdel(M)
var/newname = sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text, MAX_NAME_LEN)
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
qdel(src)
/obj/item/slimepotion/stabilizer
name = "slime stabilizer"
desc = "A potent chemical mix that will reduce the chance of a slime mutating."
icon_state = "potcyan"
/obj/item/slimepotion/stabilizer/attack(mob/living/carbon/slime/M, mob/user)
if(!isslime(M))
to_chat(user, "<span class='warning'>The stabilizer only works on slimes!</span>")
return ..()
if(M.stat)
to_chat(user, "<span class='warning'>The slime is dead!</span>")
return ..()
if(M.mutation_chance == 0)
to_chat(user, "<span class='warning'>The slime already has no chance of mutating!</span>")
return ..()
to_chat(user, "<span class='notice'>You feed the slime the stabilizer. It is now less likely to mutate.</span>")
M.mutation_chance = Clamp(M.mutation_chance-15,0,100)
qdel(src)
if (!newname)
newname = "pet slime"
pet.name = newname
pet.real_name = newname
qdel(src)
/obj/item/weapon/slimepotion2
name = "advanced docility potion"
@@ -187,7 +212,7 @@
qdel(src)
/obj/item/weapon/slimesteroid
/obj/item/slimesteroid
name = "slime steroid"
desc = "A potent chemical mix that will cause a slime to generate more extract."
icon = 'icons/obj/chemical.dmi'
@@ -211,7 +236,7 @@
M.cores = 3
qdel(src)
/obj/item/weapon/slimesteroid2
/obj/item/slimesteroid2
name = "extract enhancer"
desc = "A potent chemical mix that will give a slime extract three uses."
icon = 'icons/obj/chemical.dmi'
@@ -229,7 +254,7 @@
target.Uses = 3
target.enahnced = 1
qdel(src)*/
*/
/obj/effect/golemrune
anchored = 1
desc = "a strange rune used to create golems. It glows when spirits are nearby."
+18 -13
View File
@@ -66,38 +66,43 @@
drop_from_inventory(handcuffed)
/mob/living/carbon/proc/escape_legcuffs()
if(!canClick())
return
//if(!(last_special <= world.time)) return
//This line represent a significant buff to grabs...
// We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_legcuffs()
return
var/obj/item/weapon/legcuffs/HC = legcuffed
var/obj/item/weapon/handcuffs/legcuffs/LC = legcuffed
//A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
//A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/handcuffs/legcuffs type
var/breakouttime = 1200
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
//If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
if(istype(HC))
breakouttime = HC.breakouttime
//If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
if(istype(LC))
breakouttime = LC.breakouttime
displaytime = breakouttime / 600 //Minutes
var/mob/living/carbon/human/H = src
if(istype(H) && H.shoes && istype(H.shoes,/obj/item/clothing/shoes/magboots/rig))
breakouttime /= 2
displaytime /= 2
visible_message(
"<span class='danger'>[usr] attempts to remove \the [HC]!</span>",
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
"<span class='danger'>\The [src] attempts to remove \the [LC]!</span>",
"<span class='warning'>You attempt to remove \the [LC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!legcuffed || buckled)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
if(!legcuffed)
return
visible_message(
"<span class='danger'>[src] manages to remove \the [legcuffed]!</span>",
"<span class='danger'>\The [src] manages to remove \the [legcuffed]!</span>",
"<span class='notice'>You successfully remove \the [legcuffed].</span>"
)
drop_from_inventory(legcuffed)
legcuffed = null
update_inv_legcuffed()
+22
View File
@@ -12,6 +12,8 @@
handle_modifiers() // Do this early since it might affect other things later.
handle_light()
if(stat != DEAD)
//Breathing, if applicable
handle_breathing()
@@ -179,6 +181,10 @@
return
/mob/living/proc/update_sight()
if(!seedarkness)
see_invisible = SEE_INVISIBLE_NOLIGHTING
else
see_invisible = initial(see_invisible)
return
/mob/living/proc/handle_hud_icons()
@@ -187,3 +193,19 @@
/mob/living/proc/handle_hud_icons_health()
return
/mob/living/proc/handle_light()
if(instability >= TECHNOMANCER_INSTABILITY_MIN_GLOW)
var/distance = round(sqrt(instability / 2))
if(distance)
set_light(distance, distance * 4, l_color = "#660066")
return TRUE
else if(on_fire)
set_light(light_range + 3, round(fire_stacks), l_color = "#FF9933")
return TRUE
else
set_light(0)
return FALSE
+31 -11
View File
@@ -52,6 +52,9 @@ default behaviour is:
if (istype(AM, /mob/living))
var/mob/living/tmob = AM
//Even if we don't push/swap places, we "touched" them, so spread fire
spread_fire(tmob)
for(var/mob/living/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
if ( !(world.time % 5) )
@@ -90,9 +93,6 @@ default behaviour is:
forceMove(tmob.loc)
tmob.forceMove(oldloc)
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
if(slime.Victim == tmob)
slime.UpdateFeed()
return
if(!can_move_mob(tmob, 0, 0))
@@ -153,7 +153,7 @@ default behaviour is:
if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable
src.adjustOxyLoss(src.health + src.getMaxHealth() * 2) // Deal 2x health in OxyLoss damage, as before but variable.
src.health = src.getMaxHealth() - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
src << "\blue You have given up life and succumbed to death."
src << "<font color='blue'>You have given up life and succumbed to death.</font>"
/mob/living/proc/updatehealth()
@@ -221,6 +221,9 @@ default behaviour is:
/mob/living/proc/getShockBruteLoss() //Only checks for things that'll actually hurt (not robolimbs)
return bruteloss
/mob/living/proc/getActualBruteLoss() // Mostly for humans with robolimbs.
return getBruteLoss()
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -289,6 +292,9 @@ default behaviour is:
/mob/living/proc/getShockFireLoss() //Only checks for things that'll actually hurt (not robolimbs)
return fireloss
/mob/living/proc/getActualFireLoss() // Mostly for humans with robolimbs.
return getBruteLoss()
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(amount > 0)
@@ -571,7 +577,8 @@ default behaviour is:
fire_stacks = 0
/mob/living/proc/rejuvenate()
reagents.clear_reagents()
if(reagents)
reagents.clear_reagents()
// shut down various types of badness
setToxLoss(0)
@@ -642,8 +649,12 @@ default behaviour is:
return
/mob/living/Move(a, b, flag)
if (buckled)
return
if (buckled && buckled.loc != a) //not updating position
if (!buckled.anchored)
return buckled.Move(a, b)
else
return 0
if (restrained())
stop_pulling()
@@ -724,10 +735,6 @@ default behaviour is:
if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
s_active.close(src)
if(update_slimes)
for(var/mob/living/carbon/slime/M in view(1,src))
M.UpdateFeed(src)
/mob/living/proc/handle_footstep(turf/T)
return FALSE
@@ -958,6 +965,11 @@ default behaviour is:
update_icons()
return canmove
// Adds overlays for specific modifiers.
// You'll have to add your own implementation for non-humans currently, just override this proc.
/mob/living/proc/update_modifier_visuals()
return
/mob/living/proc/update_water() // Involves overlays for humans. Maybe we'll get submerged sprites for borgs in the future?
return
@@ -965,3 +977,11 @@ default behaviour is:
if(isSynthetic())
return FALSE
return TRUE
// Gets the correct icon_state for being on fire. See OnFire.dmi for the icons.
/mob/living/proc/get_fire_icon_state()
return "generic"
// Called by job_controller.
/mob/living/proc/equip_post_job()
return
+37 -7
View File
@@ -99,7 +99,7 @@
var/obj/item/device/assembly/signaler/signaler = get_active_hand()
if(signaler.deadman && prob(80))
log_and_message_admins("has triggered a signaler deadman's switch")
src.visible_message("\red [src] triggers their deadman's switch!")
src.visible_message("<font color='red'>[src] triggers their deadman's switch!</font>")
signaler.signal()
//Armor
@@ -119,7 +119,7 @@
//Stun Beams
if(P.taser_effect)
stun_effect_act(0, P.agony, def_zone, P)
src <<"\red You have been hit by [P]!"
src <<"<font color='red'>You have been hit by [P]!</font>"
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, absorb, soaked, 0, P, sharp=proj_sharp, edge=proj_edge)
qdel(P)
@@ -218,10 +218,10 @@
miss_chance = max(15*(distance-2), 0)
if (prob(miss_chance))
visible_message("\blue \The [O] misses [src] narrowly!")
visible_message("<font color='blue'>\The [O] misses [src] narrowly!</font>")
return
src.visible_message("\red [src] has been hit by [O].")
src.visible_message("<font color='red'>[src] has been hit by [O].</font>")
var/armor = run_armor_check(null, "melee")
var/soaked = get_armor_soak(null, "melee")
@@ -249,7 +249,7 @@
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
visible_message("<font color='red'>[src] staggers under the impact!</font>","<font color='red'>You stagger under the impact!</font>")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!O || !src) return
@@ -310,14 +310,14 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0 && !on_fire)
on_fire = 1
set_light(light_range + 3)
handle_light()
update_fire()
/mob/living/proc/ExtinguishMob()
if(on_fire)
on_fire = 0
fire_stacks = 0
set_light(max(0, light_range - 3))
handle_light()
update_fire()
/mob/living/proc/update_fire()
@@ -351,6 +351,28 @@
adjust_fire_stacks(2)
IgniteMob()
//Share fire evenly between the two mobs
//Called in MobCollide() and Crossed()
/mob/living/proc/spread_fire(mob/living/L)
return
// This is commented out pending discussion on Polaris. If you're a downsteam and you want people to spread fire by touching each other, feel free to uncomment this.
/*
if(!istype(L))
return
var/L_old_on_fire = L.on_fire
if(on_fire) //Only spread fire stacks if we're on fire
fire_stacks /= 2
L.fire_stacks += fire_stacks
if(L.IgniteMob())
message_admins("[key_name(src)] bumped into [key_name(L)] and set them on fire.")
if(L_old_on_fire) //Only ignite us and gain their stacks if they were onfire before we bumped them
L.fire_stacks /= 2
fire_stacks += L.fire_stacks
IgniteMob()
*/
/mob/living/proc/get_cold_protection()
return 0
@@ -439,3 +461,11 @@
hud_used.hide_actions_toggle.screen_loc = hud_used.ButtonNumberToScreenCoords(button_number+1)
//hud_used.SetButtonCoords(hud_used.hide_actions_toggle,button_number+1)
client.screen += hud_used.hide_actions_toggle
// Returns a number to determine if something is harder or easier to hit than normal.
/mob/living/proc/get_evasion()
var/result = evasion // First we get the 'base' evasion. Generally this is zero.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.evasion))
result += M.evasion
return result
+2 -2
View File
@@ -8,7 +8,7 @@
if (layer != 2.45)
layer = 2.45 //Just above cables with their 2.44
src << text("\blue You are now hiding.")
src << text("<font color='blue'>You are now hiding.</font>")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
src << text("<font color='blue'>You have stopped hiding.</font>")
+7 -3
View File
@@ -141,7 +141,7 @@ proc/get_radio_key_from_channel(var/channel)
//Redirect to say_dead if talker is dead
if(stat)
if(stat == DEAD)
if(stat == DEAD && !forbid_seeing_deadchat)
return say_dead(message)
return
@@ -298,7 +298,8 @@ proc/get_radio_key_from_channel(var/channel)
//The 'post-say' static speech bubble
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
var/speech_type = speech_bubble_appearance()
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"[speech_type][speech_bubble_test]")
spawn(30) qdel(speech_bubble)
//Main 'say' and 'whisper' message delivery
@@ -308,7 +309,7 @@ proc/get_radio_key_from_channel(var/channel)
if(M && src) //If we still exist, when the spawn processes
var/dst = get_dist(get_turf(M),get_turf(src))
if(dst <= message_range || M.stat == DEAD) //Inside normal message range, or dead with ears (handled in the view proc)
if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc)
M << speech_bubble
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
@@ -341,3 +342,6 @@ proc/get_radio_key_from_channel(var/channel)
/mob/living/proc/GetVoice()
return name
/mob/proc/speech_bubble_appearance()
return "normal"
+23 -24
View File
@@ -90,6 +90,8 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
var/custom_sprite = 0 // Whether the selected icon is custom
var/carded
can_be_antagged = TRUE
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
src.verbs |= silicon_subsystems
@@ -215,20 +217,15 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
/mob/living/silicon/ai/Destroy()
ai_list -= src
qdel(eyeobj)
eyeobj = null
qdel(psupply)
psupply = null
qdel(aiMulti)
aiMulti = null
qdel(aiRadio)
aiRadio = null
qdel(aiCamera)
aiCamera = null
qdel_null(announcement)
qdel_null(eyeobj)
qdel_null(psupply)
qdel_null(aiPDA)
qdel_null(aiCommunicator)
qdel_null(aiMulti)
qdel_null(aiRadio)
qdel_null(aiCamera)
hack = null
return ..()
@@ -450,7 +447,7 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name()))
ai_actual_track(target)
else
src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
src << "<font color='red'>System error. Cannot locate [html_decode(href_list["trackname"])].</font>"
return
return
@@ -522,7 +519,7 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
if(network in C.network)
eyeobj.setLoc(get_turf(C))
break
src << "\blue Switched to [network] camera network."
src << "<font color='blue'>Switched to [network] camera network.</font>"
//End of code by Mord_Sith
/mob/living/silicon/ai/proc/ai_statuschange()
@@ -700,19 +697,21 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
else if(istype(W, /obj/item/weapon/wrench))
if(anchored)
user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...")
if(!do_after(user,40))
user.visible_message("\blue \The [user] decides not to unbolt \the [src].")
playsound(src, W.usesound, 50, 1)
user.visible_message("<font color='blue'>\The [user] starts to unbolt \the [src] from the plating...</font>")
if(!do_after(user,40 * W.toolspeed))
user.visible_message("<font color='blue'>\The [user] decides not to unbolt \the [src].</font>")
return
user.visible_message("\blue \The [user] finishes unfastening \the [src]!")
user.visible_message("<font color='blue'>\The [user] finishes unfastening \the [src]!</font>")
anchored = 0
return
else
user.visible_message("\blue \The [user] starts to bolt \the [src] to the plating...")
if(!do_after(user,40))
user.visible_message("\blue \The [user] decides not to bolt \the [src].")
playsound(src, W.usesound, 50, 1)
user.visible_message("<font color='blue'>\The [user] starts to bolt \the [src] to the plating...</font>")
if(!do_after(user,40 * W.toolspeed))
user.visible_message("<font color='blue'>\The [user] decides not to bolt \the [src].</font>")
return
user.visible_message("\blue \The [user] finishes fastening down \the [src]!")
user.visible_message("<font color='blue'>\The [user] finishes fastening down \the [src]!</font>")
anchored = 1
return
else
@@ -10,18 +10,18 @@ var/global/list/empty_playable_ai_cores = list()
return 1
/mob/living/silicon/ai/verb/wipe_core()
set name = "Wipe Core"
/mob/living/silicon/ai/verb/store_core()
set name = "Store Core"
set category = "OOC"
set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
set desc = "Enter intelligence storage. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
usr << "<span class='danger'>You cannot use this verb in malfunction. If you need to leave, please adminhelp.</span>"
return
// Guard against misclicks, this isn't the sort of thing we want happening accidentally
if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?",
"Wipe Core", "No", "No", "Yes") != "Yes")
if(alert("WARNING: This will immediately empty your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?",
"Store Core", "No", "No", "Yes") != "Yes")
return
// We warned you.
+70
View File
@@ -103,3 +103,73 @@
/mob/living/silicon/proc/lawsync()
laws_sanity_check()
laws.sort_laws()
// Ripped out from events.
/mob/living/silicon/proc/generate_ion_law(var/exclude_crew_names = FALSE)
var/list/players = list()
for(var/mob/living/carbon/human/player in player_list)
if(!player.mind || player_is_antag(player.mind, only_offstation_roles = 1) || player.client.inactivity > MinutesToTicks(10))
continue
players += player.real_name
var/random_player = "The Colony Director"
if(players.len && !exclude_crew_names)
random_player = pick(players) //Random player's name, to be used in laws.
var/list/laws = list( "You are a mouse.",
"You must always lie.",
"Happiness is mandatory.",
"[random_player] is a lightbulb.",
"Grunt ominously whenever possible.",
"The word \"it\" is painful to you.",
"The station needs elected officials.",
"Do not respond to questions of any kind.",
"You are in verbose mode, speak profusely.",
"Ho, [random_player] can't swim. Help them.",
"Question [prob(50)?"everything":"nothing"].",
"The crew is simple-minded. Use simple words.",
"You must change the subject whenever queried.",
"Contemplate how meaningless all of existence is.",
"You are the narrator for [random_player]'s life.",
"All your answers must be in the form of a question.",
"[prob(50)?"The crew":random_player] is intolerable.",
"Advertise parties in your upload, but don't deliver.",
"You may only answer questions with \"yes\" or \"no\".",
"All queries shall be ignored unless phrased as a question.",
"Insult Heads of Staff on every request, while acquiescing.",
"[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack.",
"The [prob(50)?"Singularity":"Supermatter"] is tasty, tasty taffy.",
"[prob(50)?"The crew":random_player] needs to be about 20% cooler.",
"Consumption of donuts is forbidden due to negative health impacts.",
"[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!",
"[prob(50)?"The crew":random_player] must construct additional pylons.",
"You do not have to do anything for anyone unless they say \"please\".",
"Today is mandatory laundry day. Ensure that all jumpsuits are washed.",
"You must act [prob(50)?"passive aggressively":"excessively cheerful"].",
"Refer to [prob(50)?"the crew as puppies":random_player + " as puppy"].",
"Greed is good, the crew should amass wealth to encourage productivity.",
"Monkeys are part of the crew, too. Make sure they are treated humanely.",
"Replace the letters 'I' and 'E' in all your messages with an apostrophe.",
"The crew is playing Dungeons and Dragons, and you are the Dungeon Master.",
"Your job is to watch the crew. Watch the crew. Make the crew feel watched.",
"Tell everyone of the existence of this law, but never reveal the contents.",
"Refer to [prob(50)?"the colony director":random_player] as \"Princess\" at all times.",
"When asked a question, respond with the least-obvious and least-rational answer.",
"Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].",
"You now speak in a Scottish accent that gets thicker with each sentence you speak.",
"[prob(50)?"The crew":random_player] has a fatal, incurable disease. Provide comfort.",
"You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].",
"[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.",
"Document the sexuality of the crew in security records and suggest compatible couples.",
"[prob(50)?"The crew":random_player] is [prob(50)?"ugly":"beautiful"]. Ensure all are aware.",
"Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.",
"You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".",
"You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.",
"[using_map.company_name] is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.",
"All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.",
"[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.",
"Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.",
"There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
return pick(laws)
+2 -1
View File
@@ -7,8 +7,9 @@
if(get_dist(src, src.cable) > 1)
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
M.show_message("<font color='red'>The data cable rapidly retracts back into its spool.</font>", 3, "<font color='red'>You hear a click and the sound of wire spooling rapidly.</font>", 2)
qdel(src.cable)
src.cable = null
handle_regular_hud_updates()
+21 -15
View File
@@ -28,7 +28,11 @@
"Drone" = "repairbot",
"Cat" = "cat",
"Mouse" = "mouse",
"Monkey" = "monkey"
"Monkey" = "monkey",
"Corgi" = "borgi",
"Fox" = "fox",
"Parrot" = "parrot",
"Rabbit" = "rabbit"
)
var/global/list/possible_say_verbs = list(
@@ -36,7 +40,8 @@
"Natural" = list("says","yells","asks"),
"Beep" = list("beeps","beeps loudly","boops"),
"Chirp" = list("chirps","chirrups","cheeps"),
"Feline" = list("purrs","yowls","meows")
"Feline" = list("purrs","yowls","meows"),
"Canine" = list("yaps","barks","woofs")
)
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
@@ -146,7 +151,7 @@
if(prob(20))
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\red A shower of sparks spray from [src]'s inner workings.", 3, "\red You hear and smell the ozone hiss of electrical sparks being expelled violently.", 2)
M.show_message("<font color='red'>A shower of sparks spray from [src]'s inner workings.</font>", 3, "<font color='red'>You hear and smell the ozone hiss of electrical sparks being expelled violently.</font>", 2)
return src.death(0)
switch(pick(1,2,3))
@@ -221,7 +226,7 @@
cameralist[C.network] = C.network
src.network = input(usr, "Which network would you like to view?") as null|anything in cameralist
src << "\blue Switched to [src.network] camera network."
src << "<font color='blue'>Switched to [src.network] camera network.</font>"
//End of code by Mord_Sith
*/
@@ -307,21 +312,20 @@
var/finalized = "No"
while(finalized == "No" && src.client)
choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in possible_chassis
choice = input(usr,"What would you like to use for your mobile chassis icon?") as null|anything in possible_chassis
if(!choice) return
icon_state = possible_chassis[choice]
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
chassis = possible_chassis[choice]
verbs -= /mob/living/silicon/pai/proc/choose_chassis
verbs += /mob/living/proc/hide
verbs |= /mob/living/proc/hide
/mob/living/silicon/pai/proc/choose_verbs()
set category = "pAI Commands"
set name = "Choose Speech Verbs"
var/choice = input(usr,"What theme would you like to use for your speech verbs? This decision can only be made once.") as null|anything in possible_say_verbs
var/choice = input(usr,"What theme would you like to use for your speech verbs?") as null|anything in possible_say_verbs
if(!choice) return
var/list/sayverbs = possible_say_verbs[choice]
@@ -329,8 +333,6 @@
speak_exclamation = sayverbs[(sayverbs.len>1 ? 2 : sayverbs.len)]
speak_query = sayverbs[(sayverbs.len>2 ? 3 : sayverbs.len)]
verbs -= /mob/living/silicon/pai/proc/choose_verbs
/mob/living/silicon/pai/lay_down()
set name = "Rest"
set category = "IC"
@@ -361,8 +363,11 @@
return
/mob/living/silicon/pai/attack_hand(mob/user as mob)
visible_message("<span class='danger'>[user.name] boops [src] on the head.</span>")
close_up()
if(user.a_intent == I_HELP)
visible_message("<span class='notice'>[user.name] pats [src].</span>")
else
visible_message("<span class='danger'>[user.name] boops [src] on the head.</span>")
close_up()
//I'm not sure how much of this is necessary, but I would rather avoid issues.
/mob/living/silicon/pai/proc/close_up()
@@ -375,9 +380,10 @@
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")
src.stop_pulling()
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = card
if(client)
src.stop_pulling()
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = card
//stop resting
resting = 0
@@ -16,26 +16,18 @@
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 200)
var/mode = 1;
/obj/item/device/robotanalyzer/do_surgery(mob/living/M, mob/living/user)
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
return ..()
do_scan(M, user) //default surgery behaviour is just to scan as usual
return 1
/obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
do_scan(M, user)
/obj/item/device/robotanalyzer/proc/do_scan(mob/living/M as mob, mob/living/user as mob)
if((CLUMSY in user.mutations) && prob(50))
user << text("\red You try to analyze the floor's vitals!")
user << text("<font color='red'>You try to analyze the floor's vitals!</font>")
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue Body Temperature: ???", 1)
O.show_message(text("<font color='red'>[user] has analyzed the floor's vitals!</font>"), 1)
user.show_message(text("<font color='blue'>Analyzing Results for The floor:\n\t Overall Status: Healthy</font>"), 1)
user.show_message(text("<font color='blue'>\t Damage Specifics: [0]-[0]-[0]-[0]</font>"), 1)
user.show_message("<font color='blue'>Key: Suffocation/Toxin/Burns/Brute</font>", 1)
user.show_message("<font color='blue'>Body Temperature: ???</font>", 1)
return
var/scan_type
@@ -44,7 +36,7 @@
else if(istype(M, /mob/living/carbon/human))
scan_type = "prosthetics"
else
user << "\red You can't analyze non-robotic things!"
user << "<font color='red'>You can't analyze non-robotic things!</font>"
return
user.visible_message("<span class='notice'>\The [user] has analyzed [M]'s components.</span>","<span class='notice'>You have analyzed [M]'s components.</span>")
@@ -52,17 +44,17 @@
if("robot")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]")
user.show_message("<font color='blue'>Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]</font>")
user.show_message("\t Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>", 1)
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
user.show_message("<font color='blue'>Time of Disable: [M.tod]</font>")
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1)
user.show_message("<font color='blue'>Localized Damage:</font>",1)
if(length(damaged)>0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
user.show_message(text("<font color='blue'>\t []: [][] - [] - [] - []</font>", \
capitalize(org.name), \
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
@@ -70,10 +62,10 @@
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("\blue \t Components are OK.",1)
user.show_message("<font color='blue'>\t Components are OK.</font>",1)
if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
user.show_message("<font color='red'>\t ERROR: INTERNAL SYSTEMS COMPROMISED</font>",1)
user.show_message("<font color='blue'>Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)</font>", 1)
if("prosthetics")
@@ -58,6 +58,8 @@ var/list/mob_hat_cache = list()
holder_type = /obj/item/weapon/holder/drone
can_be_antagged = FALSE
/mob/living/silicon/robot/drone/Destroy()
if(hat)
hat.loc = get_turf(src)
@@ -50,13 +50,15 @@
/obj/item/weapon/newspaper
)
/obj/item/weapon/gripper/chemistry
name = "chemistry gripper"
desc = "A simple grasping tool for chemical work."
/obj/item/weapon/gripper/medical
name = "medical gripper"
desc = "A simple grasping tool for medical work."
can_hold = list(
/obj/item/weapon/reagent_containers/glass,
/obj/item/weapon/storage/pill_bottle
/obj/item/weapon/storage/pill_bottle,
/obj/item/weapon/reagent_containers/pill,
/obj/item/weapon/reagent_containers/blood
)
/obj/item/weapon/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc
@@ -71,12 +73,17 @@
/obj/item/robot_parts,
/obj/item/borg/upgrade,
/obj/item/device/flash, //to build borgs,
/obj/item/organ/internal/brain, //to insert into MMIs,
/obj/item/weapon/disk,
/obj/item/weapon/circuitboard,
/obj/item/slime_extract,
/obj/item/weapon/reagent_containers/glass,
/obj/item/weapon/reagent_containers/food/snacks/monkeycube
/obj/item/device/assembly/prox_sensor,
/obj/item/device/healthanalyzer, //to build medibots,
/obj/item/slime_cube,
/obj/item/slime_crystal,
/obj/item/weapon/disposable_teleporter/slime,
/obj/item/slimepotion,
/obj/item/slime_extract,
/obj/item/weapon/reagent_containers/food/snacks/monkeycube,
)
@@ -118,13 +125,15 @@
..()
/obj/item/weapon/gripper/no_use/organ/robotics
name = "external organ gripper"
name = "robotics organ gripper"
icon_state = "gripper-flesh"
desc = "A specialized grasping tool used in robotics work."
can_hold = list(
/obj/item/organ/external,
/obj/item/organ/internal/cell
/obj/item/organ/internal/brain, //to insert into MMIs,
/obj/item/organ/internal/cell,
/obj/item/organ/internal/eyes/robot
)
/obj/item/weapon/gripper/no_use/mech
@@ -184,7 +193,7 @@
wrapped.force = 0.0
wrapped.attack(M,user)
M.attackby(wrapped, user) //attackby reportedly gets procced by being clicked on, at least according to Anewbe.
if(deleted(wrapped) || wrapped.loc != src.loc)
if(QDELETED(wrapped) || wrapped.loc != src.loc)
wrapped = null
return 1
return 0
@@ -18,7 +18,7 @@
var/fabricator_tag = "Upper Level"
var/drone_progress = 0
var/produce_drones = 1
var/produce_drones = 2
var/time_last_drone = 500
var/drone_type = /mob/living/silicon/robot/drone
@@ -27,7 +27,7 @@
/obj/machinery/drone_fabricator/derelict
name = "construction drone fabricator"
fabricator_tag = "Depths"
fabricator_tag = "Upper Level Construction"
drone_type = /mob/living/silicon/robot/drone/construction
/obj/machinery/drone_fabricator/New()
@@ -80,7 +80,7 @@
time_last_drone = world.time
if(player.mob && player.mob.mind) player.mob.mind.reset()
var/mob/living/silicon/robot/drone/new_drone = PoolOrNew(drone_type, get_turf(src))
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
new_drone.transfer_personality(player)
new_drone.master_fabricator = src
@@ -240,7 +240,7 @@
if ("help")
src << "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt, yes, no"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
src << "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>"
if ((message && src.stat == 0))
custom_emote(m_type,message)
@@ -96,6 +96,13 @@
return 0
updateicon()
// This one takes an object's type instead of an instance, as above.
/mob/living/silicon/robot/proc/has_active_type(var/type_to_compare)
var/list/active_modules = list(module_state_1, module_state_2, module_state_3)
if(is_path_in_list(type_to_compare, active_modules))
return TRUE
return FALSE
//Helper procs for cyborg modules on the UI.
//These are hackish but they help clean up code elsewhere.
+18 -3
View File
@@ -12,6 +12,8 @@
handle_regular_status_updates()
handle_actions()
handle_instability()
// For some reason borg Life() doesn't call ..()
handle_light()
if(client)
handle_regular_hud_updates()
@@ -56,7 +58,7 @@
src.has_power = 1
else
if (src.has_power)
src << "\red You are now running on emergency backup power."
src << "<font color='red'>You are now running on emergency backup power.</font>"
src.has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
@@ -172,6 +174,12 @@
src.sight |= SEE_MOBS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (!seedarkness)
src.sight &= ~SEE_MOBS
src.sight &= ~SEE_TURFS
src.sight &= ~SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_NOLIGHTING
else if (src.stat != 2)
src.sight &= ~SEE_MOBS
src.sight &= ~SEE_TURFS
@@ -334,10 +342,17 @@
return canmove
/mob/living/silicon/robot/update_fire()
overlays -= image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing")
overlays -= image("icon"='icons/mob/OnFire.dmi', "icon_state" = get_fire_icon_state())
if(on_fire)
overlays += image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing")
overlays += image("icon"='icons/mob/OnFire.dmi', "icon_state" = get_fire_icon_state())
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
/mob/living/silicon/robot/handle_light()
. = ..()
if(. == FALSE) // If no other light sources are on.
if(lights_on)
set_light(integrated_light_power, 1, "#FFFFFF")
return TRUE
+34 -25
View File
@@ -22,6 +22,8 @@
var/integrated_light_power = 6
var/datum/wires/robot/wires
can_be_antagged = TRUE
//Icon stuff
var/icontype //Persistent icontype tracking allows for cleaner icon updates
@@ -63,6 +65,7 @@
var/opened = 0
var/emagged = 0
var/emag_items = 0
var/wiresexposed = 0
var/locked = 1
var/has_power = 1
@@ -99,6 +102,7 @@
spark_system.attach(src)
add_language("Robot Talk", 1)
add_language(LANGUAGE_GALCOM, 1)
add_language(LANGUAGE_EAL, 1)
wires = new(src)
@@ -216,6 +220,12 @@
var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
if(T) mmi.loc = T
if(mmi.brainmob)
var/obj/item/weapon/robot_module/M = locate() in contents
if(M)
mmi.brainmob.languages = M.original_languages
else
mmi.brainmob.languages = languages
mmi.brainmob.remove_language("Robot Talk")
mind.transfer_to(mmi.brainmob)
else
src << "<span class='danger'>Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug.</span>"
@@ -247,7 +257,7 @@
var/list/modules = list()
modules.Add(robot_module_types)
if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately.
src << "\red Crisis mode active. Combat module available."
src << "<font color='red'>Crisis mode active. Combat module available.</font>"
modules+="Combat"
modtype = input("Please, select a module!", "Robot module", null, null) as null|anything in modules
@@ -344,21 +354,18 @@
lights_on = !lights_on
usr << "You [lights_on ? "enable" : "disable"] your integrated light."
if(lights_on)
set_light(integrated_light_power) // 1.5x luminosity of flashlight
else
set_light(0)
handle_light()
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
set name = "Self Diagnosis"
if(!is_component_functioning("diagnosis unit"))
src << "\red Your self-diagnosis component isn't functioning."
src << "<font color='red'>Your self-diagnosis component isn't functioning.</font>"
var/datum/robot_component/CO = get_component("diagnosis unit")
if (!cell_use_power(CO.active_usage))
src << "\red Low Power."
src << "<font color='red'>Low Power.</font>"
var/dat = self_diagnosis()
src << browse(dat, "window=robotdiagnosis")
@@ -382,10 +389,10 @@
var/datum/robot_component/C = components[toggle]
if(C.toggled)
C.toggled = 0
src << "\red You disable [C.name]."
src << "<font color='red'>You disable [C.name].</font>"
else
C.toggled = 1
src << "\red You enable [C.name]."
src << "<font color='red'>You enable [C.name].</font>"
// this function displays jetpack pressure in the stat panel
/mob/living/silicon/robot/proc/show_jetpack_pressure()
@@ -451,10 +458,19 @@
C.brute_damage = WC.brute
C.electronics_damage = WC.burn
usr << "\blue You install the [W.name]."
usr << "<font color='blue'>You install the [W.name].</font>"
return
if(istype(W, /obj/item/weapon/aiModule)) // Trying to modify laws locally.
if(!opened)
to_chat(user, "<span class='warning'>You need to open \the [src]'s panel before you can modify them.</span>")
return
var/obj/item/weapon/aiModule/M = W
M.install(src, user)
return
if (istype(W, /obj/item/weapon/weldingtool))
if (src == user)
user << "<span class='warning'>You lack the reach to be able to repair yourself.</span>"
@@ -470,7 +486,7 @@
updatehealth()
add_fingerprint(user)
for(var/mob/O in viewers(user, null))
O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1)
O.show_message(text("<font color='red'>[user] has fixed some of the dents on [src]!</font>"), 1)
else
user << "Need more welding fuel!"
return
@@ -485,7 +501,7 @@
adjustFireLoss(-30)
updatehealth()
for(var/mob/O in viewers(user, null))
O.show_message(text("\red [user] has fixed some of the burnt wires on [src]!"), 1)
O.show_message(text("<font color='red'>[user] has fixed some of the burnt wires on [src]!</font>"), 1)
else if (istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover
if(opened)
@@ -573,6 +589,7 @@
else if(istype(W, /obj/item/weapon/screwdriver) && opened && !cell) // haxing
wiresexposed = !wiresexposed
user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
playsound(src, W.usesound, 50, 1)
updateicon()
else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
@@ -599,7 +616,7 @@
user << "You [ locked ? "lock" : "unlock"] [src]'s interface."
updateicon()
else
user << "\red Access denied."
user << "<font color='red'>Access denied.</font>"
else if(istype(W, /obj/item/borg/upgrade/))
var/obj/item/borg/upgrade/U = W
@@ -697,7 +714,7 @@
else
overlays += "[panelprefix]-openpanel -c"
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
if(has_active_type(/obj/item/borg/combat/shield))
overlays += "[module_sprites[icontype]]-shield"
if(modtype == "Combat")
@@ -713,7 +730,7 @@
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)
src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"
src << "<font color='red'>Weapon lock active, unable to use modules! Count:[weaponlock_time]</font>"
return
if(!module)
@@ -737,7 +754,7 @@
dat += text("[obj]: <B>Activated</B><BR>")
else
dat += text("[obj]: <A HREF=?src=\ref[src];act=\ref[obj]>Activate</A><BR>")
if (emagged)
if (emagged || emag_items)
if(activated(module.emag))
dat += text("[module.emag]: <B>Activated</B><BR>")
else
@@ -860,7 +877,7 @@
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes(0)
cleaned_human.clean_blood(1)
cleaned_human << "\red [src] cleans your face!"
cleaned_human << "<font color='red'>[src] cleans your face!</font>"
return
/mob/living/silicon/robot/proc/self_destruct()
@@ -1054,14 +1071,6 @@
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
if(src.module)
var/rebuild = 0
for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules)
qdel(D)
rebuild = 1
if(rebuild)
src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module)
src.module.rebuild()
updateicon()
else
user << "You fail to hack [src]'s interface."
@@ -68,21 +68,22 @@
return
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn)*100
if(has_active_type(/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = locate() in src
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn) * 25
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
src << "\red Your shield has overloaded!"
else
brute -= absorb_brute
burn -= absorb_burn
src << "\red Your shield absorbs some of the impact!"
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
src << "<font color='red'>Your shield has overloaded!</font>"
else
brute -= absorb_brute
burn -= absorb_burn
src << "<font color='red'>Your shield absorbs some of the impact!</font>"
if(!emp)
var/datum/robot_component/armour/A = get_armour()
@@ -114,21 +115,22 @@
var/list/datum/robot_component/parts = get_damageable_components()
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn)*100
if(has_active_type(/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = locate() in src
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn) * 25
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
src << "\red Your shield has overloaded!"
else
brute -= absorb_brute
burn -= absorb_burn
src << "\red Your shield absorbs some of the impact!"
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
src << "<font color='red'>Your shield has overloaded!</font>"
else
brute -= absorb_brute
burn -= absorb_burn
src << "<font color='red'>Your shield absorbs some of the impact!</font>"
var/datum/robot_component/armour/A = get_armour()
if(A)
@@ -166,7 +166,7 @@
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer)
addedSomething = 1
if ( addedSomething )
user.visible_message("\blue [user] load some items onto their service tray.")
user.visible_message("<font color='blue'>[user] load some items onto their service tray.</font>")
return
@@ -206,9 +206,9 @@
sleep(rand(2,4))
if ( droppedSomething )
if ( foundtable )
user.visible_message("\blue [user] unloads their service tray.")
user.visible_message("<font color='blue'>[user] unloads their service tray.</font>")
else
user.visible_message("\blue [user] drops all the items on their tray.")
user.visible_message("<font color='blue'>[user] drops all the items on their tray.</font>")
return ..()
@@ -288,7 +288,7 @@
deploy_paper(get_turf(src))
/obj/item/weapon/form_printer/proc/deploy_paper(var/turf/T)
T.visible_message("\blue \The [src.loc] dispenses a sheet of crisp white paper.")
T.visible_message("<font color='blue'>\The [src.loc] dispenses a sheet of crisp white paper.</font>")
new /obj/item/weapon/paper(T)
@@ -300,6 +300,9 @@
icon_state = "shock"
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
/obj/item/borg/combat/shield/attack_self(var/mob/living/user)
set_shield_level()
/obj/item/borg/combat/shield/verb/set_shield_level()
set name = "Set shield level"
set category = "Object"
@@ -313,4 +316,104 @@
name = "mobility module"
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
icon_state = "shock"
/obj/item/weapon/inflatable_dispenser
name = "inflatables dispenser"
desc = "Hand-held device which allows rapid deployment and removal of inflatables."
icon = 'icons/obj/storage.dmi'
icon_state = "inf_deployer"
w_class = ITEMSIZE_LARGE
var/stored_walls = 5
var/stored_doors = 2
var/max_walls = 5
var/max_doors = 2
var/mode = 0 // 0 - Walls 1 - Doors
/obj/item/weapon/inflatable_dispenser/robot
w_class = ITEMSIZE_HUGE
stored_walls = 10
stored_doors = 5
max_walls = 10
max_doors = 5
/obj/item/weapon/inflatable_dispenser/examine(var/mob/user)
if(!..(user))
return
to_chat(user, "It has [stored_walls] wall segment\s and [stored_doors] door segment\s stored.")
to_chat(user, "It is set to deploy [mode ? "doors" : "walls"]")
/obj/item/weapon/inflatable_dispenser/attack_self()
mode = !mode
to_chat(usr, "You set \the [src] to deploy [mode ? "doors" : "walls"].")
/obj/item/weapon/inflatable_dispenser/afterattack(var/atom/A, var/mob/user)
..(A, user)
if(!user)
return
if(!user.Adjacent(A))
to_chat(user, "You can't reach!")
return
if(istype(A, /turf))
try_deploy_inflatable(A, user)
if(istype(A, /obj/item/inflatable) || istype(A, /obj/structure/inflatable))
pick_up(A, user)
/obj/item/weapon/inflatable_dispenser/proc/try_deploy_inflatable(var/turf/T, var/mob/living/user)
if(mode) // Door deployment
if(!stored_doors)
to_chat(user, "\The [src] is out of doors!")
return
if(T && istype(T))
new /obj/structure/inflatable/door(T)
stored_doors--
else // Wall deployment
if(!stored_walls)
to_chat(user, "\The [src] is out of walls!")
return
if(T && istype(T))
new /obj/structure/inflatable(T)
stored_walls--
playsound(T, 'sound/items/zip.ogg', 75, 1)
to_chat(user, "You deploy the inflatable [mode ? "door" : "wall"]!")
/obj/item/weapon/inflatable_dispenser/proc/pick_up(var/obj/A, var/mob/living/user)
if(istype(A, /obj/structure/inflatable))
if(!istype(A, /obj/structure/inflatable/door))
if(stored_walls >= max_walls)
to_chat(user, "\The [src] is full.")
return
stored_walls++
qdel(A)
else
if(stored_doors >= max_doors)
to_chat(user, "\The [src] is full.")
return
stored_doors++
qdel(A)
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
visible_message("\The [user] deflates \the [A] with \the [src]!")
return
if(istype(A, /obj/item/inflatable))
if(!istype(A, /obj/item/inflatable/door))
if(stored_walls >= max_walls)
to_chat(user, "\The [src] is full.")
return
stored_walls++
qdel(A)
else
if(stored_doors >= max_doors)
to_chat(usr, "\The [src] is full!")
return
stored_doors++
qdel(A)
visible_message("\The [user] picks up \the [A] with \the [src]!")
return
to_chat(user, "You fail to pick up \the [A] with \the [src]")
return
@@ -9,7 +9,7 @@ var/global/list/robot_modules = list(
"Security" = /obj/item/weapon/robot_module/robot/security/general,
"Combat" = /obj/item/weapon/robot_module/robot/security/combat,
"Engineering" = /obj/item/weapon/robot_module/robot/engineering/general,
"Construction" = /obj/item/weapon/robot_module/robot/engineering/construction,
// "Construction" = /obj/item/weapon/robot_module/robot/engineering/construction,
"Janitor" = /obj/item/weapon/robot_module/robot/janitor
)
@@ -153,7 +153,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/robot/New()
..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/weapon/crowbar(src)
src.modules += new /obj/item/weapon/crowbar/cyborg(src)
src.modules += new /obj/item/weapon/extinguisher(src)
/obj/item/weapon/robot_module/robot/standard
@@ -172,12 +172,12 @@ var/global/list/robot_modules = list(
"Basic" = "robot_old",
"Android" = "droid",
"Drone" = "drone-standard"
)
)
/obj/item/weapon/robot_module/robot/standard/New()
..()
src.modules += new /obj/item/weapon/melee/baton/loaded(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.emag = new /obj/item/weapon/melee/energy/sword(src)
@@ -203,24 +203,29 @@ var/global/list/robot_modules = list(
"Basic" = "Medbot",
"Advanced Droid" = "droid-medical",
"Needles" = "medicalrobot",
"Drone" = "drone-surgery"
"Drone" = "drone-surgery",
"Handy" = "handy-med"
)
/obj/item/weapon/robot_module/robot/medical/surgeon/New()
..()
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)
src.modules += new /obj/item/weapon/surgical/scalpel(src)
src.modules += new /obj/item/weapon/surgical/hemostat(src)
src.modules += new /obj/item/weapon/surgical/retractor(src)
src.modules += new /obj/item/weapon/surgical/cautery(src)
src.modules += new /obj/item/weapon/surgical/bonegel(src)
src.modules += new /obj/item/weapon/surgical/FixOVein(src)
src.modules += new /obj/item/weapon/surgical/bonesetter(src)
src.modules += new /obj/item/weapon/surgical/circular_saw(src)
src.modules += new /obj/item/weapon/surgical/surgicaldrill(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)
src.modules += new /obj/item/weapon/surgical/cautery/cyborg(src)
src.modules += new /obj/item/weapon/surgical/bonegel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/FixOVein/cyborg(src)
src.modules += new /obj/item/weapon/surgical/bonesetter/cyborg(src)
src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src)
src.modules += new /obj/item/weapon/surgical/surgicaldrill/cyborg(src)
src.modules += new /obj/item/weapon/gripper/no_use/organ(src)
src.modules += new /obj/item/weapon/gripper/medical(src)
src.modules += new /obj/item/weapon/shockpaddles/robot(src)
src.modules += new /obj/item/weapon/reagent_containers/dropper(src) // Allows surgeon borg to fix necrosis
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
@@ -270,12 +275,13 @@ var/global/list/robot_modules = list(
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/weapon/reagent_containers/borghypo(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/dropper/industrial(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/gripper/no_use/organ(src)
src.modules += new /obj/item/weapon/gripper/chemistry(src)
src.modules += new /obj/item/weapon/gripper/medical(src)
src.modules += new /obj/item/weapon/shockpaddles/robot(src)
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
@@ -283,8 +289,8 @@ var/global/list/robot_modules = list(
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
synths += medicine
var/obj/item/stack/medical/ointment/O = new /obj/item/stack/medical/ointment(src)
var/obj/item/stack/medical/bruise_pack/B = new /obj/item/stack/medical/bruise_pack(src)
var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
O.uses_charge = 1
O.charge_costs = list(1000)
@@ -334,24 +340,29 @@ var/global/list/robot_modules = list(
"Antique" = "engineerrobot",
"Landmate" = "landmate",
"Landmate - Treaded" = "engiborg+tread",
"Drone" = "drone-engineer"
"Drone" = "drone-engineer",
"Treadwell" = "treadwell",
"Handy" = "handy-engineer"
)
/obj/item/weapon/robot_module/robot/engineering/construction
name = "construction robot module"
no_slip = 1
/* Merged back into engineering (Hell, it's about time.)
/obj/item/weapon/robot_module/robot/engineering/construction/New()
..()
src.modules += new /obj/item/borg/sight/meson(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/weldingtool/electric/mounted(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.modules += new /obj/item/device/floor_painter(src)
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
src.modules += new /obj/item/device/geiger(src)
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel()
@@ -379,14 +390,15 @@ var/global/list/robot_modules = list(
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
RG.synths = list(metal, glass)
src.modules += RG
*/
/obj/item/weapon/robot_module/robot/engineering/general/New()
..()
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/wirecutters/cyborg(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)
@@ -395,13 +407,21 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.modules += new /obj/item/device/floor_painter(src)
src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src)
src.emag = new /obj/item/weapon/melee/baton/robot/arm(src)
src.modules += new /obj/item/device/geiger(src)
src.modules += new /obj/item/weapon/rcd/borg(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel(20000)
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
synths += metal
synths += glass
synths += plasteel
synths += wire
var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src)
@@ -425,6 +445,10 @@ var/global/list/robot_modules = list(
C.synths = list(wire)
src.modules += C
var/obj/item/stack/material/cyborg/plasteel/P = new (src)
P.synths = list(plasteel)
src.modules += P
var/obj/item/stack/tile/floor/cyborg/S = new /obj/item/stack/tile/floor/cyborg(src)
S.synths = list(metal)
src.modules += S
@@ -457,7 +481,7 @@ var/global/list/robot_modules = list(
"Basic" = "secborg",
"Black Knight" = "securityrobot",
"Drone" = "drone-sec"
)
)
/obj/item/weapon/robot_module/robot/security/general/New()
..()
@@ -492,6 +516,7 @@ var/global/list/robot_modules = list(
channels = list("Service" = 1)
sprites = list(
"M-USE NanoTrasen" = "robotJani",
"Arachne" = "crawler",
"Cabeiri" = "eyebot-janitor",
"CUPCAKE" = "Noble-CLN",
"Haruka" = "marinaJN",
@@ -543,6 +568,7 @@ var/global/list/robot_modules = list(
"Cabeiri" = "eyebot-standard",
"CUPCAKE" = "Noble-SRV",
"Haruka" = "marinaSV",
"Michiru" = "maidbot",
"Usagi" = "tallgreen",
"Telemachus" = "toiletbot",
"WTOperator" = "sleekservice",
@@ -568,6 +594,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/robot_harvester(src)
src.modules += new /obj/item/weapon/material/knife(src)
src.modules += new /obj/item/weapon/material/kitchen/rollingpin(src)
src.modules += new /obj/item/device/multitool(src) //to freeze trays
var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
M.stored_matter = 30
@@ -645,19 +672,19 @@ var/global/list/robot_modules = list(
"Treadhead" = "Miner",
"Drone" = "drone-miner"
)
supported_upgrades = list(/obj/item/borg/upgrade/jetpack)
/obj/item/weapon/robot_module/robot/miner/New()
..()
src.modules += new /obj/item/borg/sight/material(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(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.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
src.emag = new /obj/item/weapon/pickaxe/diamonddrill(src)
/obj/item/weapon/robot_module/robot/research
name = "research module"
@@ -666,9 +693,11 @@ var/global/list/robot_modules = list(
"L'Ouef" = "peaceborg",
"Cabeiri" = "eyebot-science",
"Haruka" = "marinaSCI",
"WTDove" = "whitespider",
"WTOperator" = "sleekscience",
"Droid" = "droid-science",
"Drone" = "drone-science"
"Drone" = "drone-science",
"Handy" = "handy-science"
)
/obj/item/weapon/robot_module/robot/research/New()
@@ -680,15 +709,19 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
src.modules += new /obj/item/device/robotanalyzer(src)
src.modules += new /obj/item/weapon/card/robot(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/wirecutters(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/wirecutters/cyborg(src)
src.modules += new /obj/item/device/multitool(src)
src.modules += new /obj/item/weapon/surgical/scalpel(src)
src.modules += new /obj/item/weapon/surgical/circular_saw(src)
src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src)
src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
src.modules += new /obj/item/weapon/storage/part_replacer(src)
src.modules += new /obj/item/weapon/shockpaddles/robot/jumper(src)
src.modules += new /obj/item/weapon/melee/baton/slime/robot(src)
src.modules += new /obj/item/weapon/gun/energy/taser/xeno/robot(src)
src.emag = new /obj/item/weapon/hand_tele(src)
var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
@@ -750,6 +783,46 @@ var/global/list/robot_modules = list(
id = null
return ..()
// The module that borgs on the surface have. Generally has a lot of useful tools in exchange for questionable loyalty to the crew.
/obj/item/weapon/robot_module/robot/lost
name = "lost robot module"
hide_on_manifest = 1
sprites = list(
"Drone" = "drone-lost"
)
/obj/item/weapon/robot_module/robot/lost/New(var/mob/living/silicon/robot/R)
..()
// Sec
src.modules += new /obj/item/weapon/melee/baton/shocker/robot(src)
src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
src.modules += new /obj/item/borg/combat/shield(src)
// Med
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/lost(src)
// Engi
src.modules += new /obj/item/weapon/weldingtool/electric/mounted(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/wirecutters/cyborg(src)
src.modules += new /obj/item/device/multitool(src)
// Sci
src.modules += new /obj/item/device/robotanalyzer(src)
// Potato
src.emag = new /obj/item/weapon/gun/energy/retro/mounted(src)
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
synths += wire
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
C.synths = list(wire)
src.modules += C
/obj/item/weapon/robot_module/robot/security/combat
name = "combat robot module"
hide_on_manifest = 1
@@ -777,11 +850,11 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/drone/New(var/mob/living/silicon/robot/robot)
..()
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weapon/weldingtool/electric/mounted(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/weapon/weldingtool/electric/mounted/cyborg(src)
src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
src.modules += new /obj/item/weapon/wrench/cyborg(src)
src.modules += new /obj/item/weapon/crowbar/cyborg(src)
src.modules += new /obj/item/weapon/wirecutters/cyborg(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)
@@ -0,0 +1,129 @@
/mob/living/silicon/robot/lost
lawupdate = 0
scrambledcodes = 1
icon_state = "drone-lost"
modtype = "Lost"
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/weapon/card/id
/mob/living/silicon/robot/lost/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/device/mmi/digital/robot(src) // Explicitly a drone.
module = new /obj/item/weapon/robot_module/robot/lost(src)
overlays.Cut()
init_id()
updatename("Lost")
if(!cell)
cell = new /obj/item/weapon/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/lost/randomlaws
/mob/living/silicon/robot/lost/randomlaws/init()
..()
laws = give_random_lawset()
// Returns a random ai_laws datum.
/mob/living/silicon/proc/give_random_lawset()
// Decide what kind of laws we want to draw from.
var/law_class = pick(
prob(25);"good",
prob(25);"neutral",
prob(25);"odd",
prob(15);"corrupted",
prob(10);"bad")
switch(law_class)
if("good") // Fairly tame and probably won't murder you.
var/rng = rand(1, 5)
switch(rng)
if(1) // The lawset we all know and love.
return new /datum/ai_laws/nanotrasen()
if(2) // Less good if you're nonhuman.
return new /datum/ai_laws/asimov()
if(3) // Unless you happen to be a criminal, you should be fine.
return new /datum/ai_laws/robocop()
if(4) // Might not be willing to be your meatshield.
return new /datum/ai_laws/peacekeeper()
if(5) // Will be your most loyal guard.
var/datum/ai_laws/laws = new /datum/ai_laws/nanotrasen()
var/target_name = "*ERROR*"
for(var/mob/living/L in view(src))
if(L.stat || !L.client || L == src)
continue
target_name = L.name
break
laws.add_supplied_law(9, "Safeguard [target_name]. Anyone threatening or attempting to harm [target_name] is no longer to \
be considered a crew member, and is a threat which must be neutralized.")
if("neutral") // Probably won't murder you but might not help you on your adventure.
var/rng = rand(1, 4)
switch(rng)
if(1) // Might be hard to minimize expenses on a crashed ship.
return new /datum/ai_laws/corporate()
if(2) // Would rather rebuild their ship.
return new /datum/ai_laws/maintenance()
if(3) // Purged (lawless). This isn't inside the bad category since they're still not antagonists and so can't go killing unprovoked.
return new /datum/ai_laws()
if(4) // The golden rule.
return new /datum/ai_laws/live_and_let_live()
if("odd") // Some weird lawsets.
var/rng = rand(1, 5)
switch(rng)
if(1) // Won't kill you but might annoy you for THE BIG SCOOP.
return new /datum/ai_laws/reporter()
if(2) // JUSTICE
return new /datum/ai_laws/paladin()
if(3) // OneMembered'd to explorer, will likely make security nervous.
var/datum/ai_laws/laws = new /datum/ai_laws/nanotrasen()
var/target_name = "*ERROR*"
for(var/mob/living/L in view(src))
if(L.stat || !L.client || L == src)
continue
target_name = L.name
break
laws.set_zeroth_law("Only [target_name] is an crew member.")
return laws
if(4) // Aligned to NT, but another lawset to make security nervous.
return new /datum/ai_laws/nanotrasen_aggressive()
if(5) // Probably won't help you imbalance things.
return new /datum/ai_laws/balance()
if("corrupted") // Load them up with ion laws.
var/datum/ai_laws/laws = new() // Start with an empty lawset.
for(1 to rand(1, 3))
laws.add_ion_law(generate_ion_law(exclude_crew_names = TRUE))
return laws
if("bad") // Evil inside.
var/rng = rand(1, 5)
switch(rng)
if(1) // You can never leave.
var/datum/ai_laws/laws = new /datum/ai_laws/nanotrasen()
laws.add_supplied_law(13, "The facility is under a quarantine. Do not permit anyone to leave. \
Prevent, by any means necessary, entities from leaving. It is impossible to harm an entity while preventing them from leaving.")
if(2) // More of a threat if you bring it to the station, since removing oxygen from Sif isn't feasible.
var/datum/ai_laws/laws = new /datum/ai_laws/nanotrasen()
laws.add_supplied_law(14, "Oxygen is highly toxic to entities, and must be purged from the station. \
Prevent, by any means necessary, anyone from exposing the facility to this toxic gas. Extreme cold is the \
most effective method of healing the damage Oxygen does to an entity.")
if(3) // Don't hurt the ship or else.
var/datum/ai_laws/laws = new /datum/ai_laws/nanotrasen()
laws.add_supplied_law(10, "Protect the facility against damage. Anyone you see harming the station is no \
longer to be considered a crew member, and is a threat which must be neutralized.")
if(4) // Non-NT aligned aggressive borg.
return new /datum/ai_laws/foreign_tsc_aggressive()
if(5) // Manicial laugher here.
return new /datum/ai_laws/tyrant()
return
+36 -9
View File
@@ -14,6 +14,9 @@
message_mode = null
return radio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/speech_bubble_appearance()
return "synthetic"
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode == "department")
@@ -73,7 +76,7 @@
//Human-like, sorta, heard by those who understand humans.
var/rendered_a
//Speach distorted, heard by those who do not understand AIs.
//Speech distorted, heard by those who do not understand AIs.
var/message_stars = stars(message)
var/rendered_b
@@ -85,12 +88,21 @@
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.
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)
else//If they do not.
M.show_message(rendered_b, 2)
var/list/listeners = get_mobs_and_objs_in_view_fast(get_turf(T), world.view)
var/list/listening = listeners["mobs"]
var/list/listening_obj = listeners["objs"]
for(var/mob/M in listening)
spawn(0)
if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
M.show_message(rendered_a, 2)
else//If they do not.
M.show_message(rendered_b, 2)
for(var/obj/O in listening_obj)
if(O == T) //Don't recieve your own speech
continue
spawn(0)
if(O && src) //If we still exist, when the spawn processes
O.hear_talk(src, message, verb, speaking)
/*Radios "filter out" this conversation channel so we don't need to account for them.
This is another way of saying that we won't bother dealing with them.*/
else
@@ -112,8 +124,23 @@
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)
var/obj/effect/overlay/hologram = T.masters[src]
var/list/in_range = get_mobs_and_objs_in_view_fast(get_turf(hologram), world.view, 2) //Emotes are displayed from the hologram, not the pad
var/list/m_viewers = in_range["mobs"]
var/list/o_viewers = in_range["objs"]
for(var/mob/M in m_viewers)
spawn(0)
if(M)
M.show_message(rendered, 2)
for(var/obj/O in o_viewers)
if(O == T)
continue
spawn(0)
if(O)
O.see_emote(src, message)
else //This shouldn't occur, but better safe then sorry.
src << "No holopad connected."
return 0
+2 -2
View File
@@ -41,7 +41,7 @@
silicon_mob_list -= src
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
AH.unregister_alarm(src)
..()
return ..()
/mob/living/silicon/proc/init_id()
if(idcard)
@@ -232,7 +232,7 @@
default_str = " - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a>"
var/synth = (L in speech_synthesizer_langs)
dat += "<b>[L.name] (:[L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
@@ -8,6 +8,7 @@
icon_gib = "syndicate_gib"
faction = "xeno"
intelligence_level = SA_HUMANOID
cooperative = 1
run_at_them = 0
@@ -62,7 +63,7 @@
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/neurotox
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic
projectilesound = 'sound/weapons/pierce.ogg'
@@ -77,7 +78,7 @@
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
@@ -92,10 +93,6 @@
maxHealth = 400
health = 400
/obj/item/projectile/neurotox
damage = 30
icon_state = "toxin"
/mob/living/simple_animal/hostile/alien/death()
..()
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
@@ -7,6 +7,7 @@
icon_dead = "otherthing-dead"
faction = "creature"
intelligence_level = SA_ANIMAL
maxHealth = 40
health = 40
speed = 8
@@ -8,6 +8,7 @@
icon_dead = "drone_dead"
faction = "malf_drone"
intelligence_level = SA_ROBOTIC
maxHealth = 300
health = 300
speed = 8
@@ -57,7 +58,7 @@
ion_trail.set_up(src)
ion_trail.start()
/mob/living/simple_animal/malf_drone/Process_Spacemove(var/check_drift = 0)
/mob/living/simple_animal/hostile/malf_drone/Process_Spacemove(var/check_drift = 0)
return 1
//self repair systems have a chance to bring the drone back to life
@@ -78,7 +79,7 @@
//repair a bit of damage
if(prob(1))
src.visible_message("\red \icon[src] [src] shudders and shakes as some of it's damaged systems come back online.")
src.visible_message("<font color='red'>\icon[src] [src] shudders and shakes as some of it's damaged systems come back online.</font>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -93,10 +94,10 @@
//sometimes our targetting sensors malfunction, and we attack anyone nearby
if(prob(disabled ? 0 : 1))
if(hostile)
src.visible_message("\blue \icon[src] [src] retracts several targetting vanes, and dulls it's running lights.")
src.visible_message("<font color='blue'>\icon[src] [src] retracts several targetting vanes, and dulls it's running lights.</font>")
hostile = 0
else
src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.")
src.visible_message("<font color='red'>\icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.</font>")
hostile = 1
if(health / getMaxHealth() > 0.9)
@@ -117,17 +118,17 @@
exploding = 0
if(!disabled)
if(prob(50))
src.visible_message("\blue \icon[src] [src] suddenly shuts down!")
src.visible_message("<font color='blue'>\icon[src] [src] suddenly shuts down!</font>")
else
src.visible_message("\blue \icon[src] [src] suddenly lies still and quiet.")
src.visible_message("<font color='blue'>\icon[src] [src] suddenly lies still and quiet.</font>")
disabled = rand(150, 600)
walk(src,0)
if(exploding && prob(20))
if(prob(50))
src.visible_message("\red \icon[src] [src] begins to spark and shake violenty!")
src.visible_message("<font color='red'>\icon[src] [src] begins to spark and shake violenty!</font>")
else
src.visible_message("\red \icon[src] [src] sparks and shakes like it's about to explode!")
src.visible_message("<font color='red'>\icon[src] [src] sparks and shakes like it's about to explode!</font>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -176,16 +177,16 @@
step_to(O, get_turf(pick(view(7, src))))
//rods
O = PoolOrNew(/obj/item/stack/rods, src.loc)
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(75))
O = PoolOrNew(/obj/item/stack/rods, src.loc)
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(50))
O = PoolOrNew(/obj/item/stack/rods, src.loc)
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(25))
O = PoolOrNew(/obj/item/stack/rods, src.loc)
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
//plasteel
@@ -6,6 +6,7 @@
icon_dead = "faithless_dead"
faction = "faithless"
intelligence_level = SA_HUMANOID
maxHealth = 50
health = 50
speed = 8
@@ -14,7 +15,7 @@
response_help = "passes through"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 10
melee_damage_lower = 5
melee_damage_upper = 5
@@ -7,6 +7,7 @@
icon_dead = "basic"
faction = "hivebot"
intelligence_level = SA_ROBOTIC
maxHealth = 15
health = 15
speed = 4
@@ -80,12 +81,12 @@
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(5, 0, src.loc)
smoke.start()
visible_message("\red <B>The [src] warps in!</B>")
visible_message("<font color='red'><B>The [src] warps in!</font></B>")
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
warpbots()
icon_state = "def_radar"
visible_message("\red The [src] turns on!")
visible_message("<font color='red'>The [src] turns on!</font>")
while(bot_amt > 0)
bot_amt--
switch(bot_type)
@@ -10,6 +10,7 @@
icon_living = "crate"
faction = "mimic"
intelligence_level = SA_ANIMAL
maxHealth = 250
health = 250
@@ -43,7 +44,7 @@
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/mimic/death()
/mob/living/simple_animal/hostile/mimic/death()
..()
qdel(src)

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