mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-22 12:46:40 +01:00
Merge branch 'master' into AI_langs
This commit is contained in:
@@ -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)]°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)]°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(!..())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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]°C ([M.bodytemperature*1.8-459.67]°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]°C ([M.bodytemperature*1.8-459.67]°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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user