mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
cl Qustinnus / Floyd / Ethereal sprites by Space, is that it? / Alerts and food sprites by MrDroppodBringer
add: Adds Ethereal; a race which lives off of electricity and shines bright. If they are healthy they shine a bright green light, and the more damaged they are, the less they shine and the greyer they become. Their punches do burn damage and they are weak to blunt attacks!
They dont need to eat normal food and dont have nutrition, Instead they gain charge by going into borg rechargers, eating ethereal food or doign specific interactions.
refactor: all nutrition changes now go through a proc so we can override behavior
/cl
Adds Ethereal. A race which is essentialy inspired by Zoltan but then with different mechanics to make it fit with SS13 more. I'm trying to stay away from making them actually provide power but the change from nutrition to electricity seemed kind of fun.
They have the following specifications:
They are walking lights; and shine bright and green if healthy, and get greyer and darker the more damaged they are. When dead they are just a grey unlit corpse.
They do burn punch damage instead of blunt.
They are weaker to blunt; especially when low on charge
They have charge instead of nutrition. Charge is gained by some interactions or by going into a borg charger. or eating new ethereal food.
They are slightly stronger to shock damage, and gain charge from it a bit; however, it is still deadly to them and thus they aren't free insulated gloves.
1040 lines
43 KiB
Plaintext
1040 lines
43 KiB
Plaintext
/mob/living/carbon/human
|
|
name = "Unknown"
|
|
real_name = "Unknown"
|
|
icon = 'icons/mob/human.dmi'
|
|
icon_state = "caucasian_m"
|
|
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
|
|
|
|
/mob/living/carbon/human/Initialize()
|
|
verbs += /mob/living/proc/mob_sleep
|
|
verbs += /mob/living/proc/lay_down
|
|
|
|
//initialize limbs first
|
|
create_bodyparts()
|
|
|
|
//initialize dna. for spawned humans; overwritten by other code
|
|
create_dna(src)
|
|
randomize_human(src)
|
|
dna.initialize_dna()
|
|
|
|
if(dna.species)
|
|
set_species(dna.species.type)
|
|
|
|
//initialise organs
|
|
create_internal_organs() //most of it is done in set_species now, this is only for parent call
|
|
physiology = new()
|
|
|
|
handcrafting = new()
|
|
|
|
. = ..()
|
|
|
|
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
|
|
|
|
|
|
/mob/living/carbon/human/ComponentInitialize()
|
|
. = ..()
|
|
if(!CONFIG_GET(flag/disable_human_mood))
|
|
AddComponent(/datum/component/mood)
|
|
|
|
/mob/living/carbon/human/Destroy()
|
|
QDEL_NULL(physiology)
|
|
return ..()
|
|
|
|
|
|
/mob/living/carbon/human/OpenCraftingMenu()
|
|
handcrafting.ui_interact(src)
|
|
|
|
/mob/living/carbon/human/prepare_data_huds()
|
|
//Update med hud images...
|
|
..()
|
|
//...sec hud images...
|
|
sec_hud_set_ID()
|
|
sec_hud_set_implants()
|
|
sec_hud_set_security_status()
|
|
//...and display them.
|
|
add_to_all_human_data_huds()
|
|
|
|
/mob/living/carbon/human/Stat()
|
|
..()
|
|
|
|
if(statpanel("Status"))
|
|
stat(null, "Intent: [a_intent]")
|
|
stat(null, "Move Mode: [m_intent]")
|
|
if (internal)
|
|
if (!internal.air_contents)
|
|
qdel(internal)
|
|
else
|
|
stat("Internal Atmosphere Info", internal.name)
|
|
stat("Tank Pressure", internal.air_contents.return_pressure())
|
|
stat("Distribution Pressure", internal.distribute_pressure)
|
|
|
|
if(mind)
|
|
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
|
if(changeling)
|
|
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
|
|
stat("Absorbed DNA", changeling.absorbedcount)
|
|
var/datum/antagonist/hivemind/hivemind = mind.has_antag_datum(/datum/antagonist/hivemind)
|
|
if(hivemind)
|
|
stat("Hivemind Vessels", hivemind.hive_size)
|
|
|
|
//NINJACODE
|
|
if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja.
|
|
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
|
|
if(statpanel("SpiderOS"))
|
|
stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]")
|
|
stat("Current Time:", "[station_time_timestamp()]")
|
|
if(SN.s_initialized)
|
|
//Suit gear
|
|
stat("Energy Charge:", "[round(SN.cell.charge/100)]%")
|
|
stat("Smoke Bombs:", "\Roman [SN.s_bombs]")
|
|
//Ninja status
|
|
stat("Fingerprints:", "[md5(dna.uni_identity)]")
|
|
stat("Unique Identity:", "[dna.unique_enzymes]")
|
|
stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]")
|
|
stat("Nutrition Status:", "[nutrition]")
|
|
stat("Oxygen Loss:", "[getOxyLoss()]")
|
|
stat("Toxin Levels:", "[getToxLoss()]")
|
|
stat("Burn Severity:", "[getFireLoss()]")
|
|
stat("Brute Trauma:", "[getBruteLoss()]")
|
|
stat("Radiation Levels:","[radiation] rad")
|
|
stat("Body Temperature:","[bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)")
|
|
|
|
//Diseases
|
|
if(diseases.len)
|
|
stat("Viruses:", null)
|
|
for(var/thing in diseases)
|
|
var/datum/disease/D = thing
|
|
stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]")
|
|
|
|
|
|
/mob/living/carbon/human/show_inv(mob/user)
|
|
user.set_machine(src)
|
|
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
|
var/list/obscured = check_obscured_slots()
|
|
var/list/dat = list()
|
|
|
|
dat += "<table>"
|
|
for(var/i in 1 to held_items.len)
|
|
var/obj/item/I = get_item_for_held_index(i)
|
|
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=[REF(src)];item=[SLOT_HANDS];hand_index=[i]'>[(I && !(I.item_flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
|
dat += "<tr><td> </td></tr>"
|
|
|
|
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[REF(src)];item=[SLOT_BACK]'>[(back && !(back.item_flags & ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
|
if(has_breathable_mask && istype(back, /obj/item/tank))
|
|
dat += " <A href='?src=[REF(src)];internal=[SLOT_BACK]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
|
|
|
dat += "</td></tr><tr><td> </td></tr>"
|
|
|
|
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[REF(src)];item=[SLOT_HEAD]'>[(head && !(head.item_flags & ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_WEAR_MASK in obscured)
|
|
dat += "<tr><td><font color=grey><B>Mask:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_MASK]'>[(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_NECK in obscured)
|
|
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=[REF(src)];item=[SLOT_NECK]'>[(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_GLASSES in obscured)
|
|
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=[REF(src)];item=[SLOT_GLASSES]'>[(glasses && !(glasses.item_flags & ABSTRACT)) ? glasses : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_EARS in obscured)
|
|
dat += "<tr><td><font color=grey><B>Ears:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Ears:</B></td><td><A href='?src=[REF(src)];item=[SLOT_EARS]'>[(ears && !(ears.item_flags & ABSTRACT)) ? ears : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
dat += "<tr><td> </td></tr>"
|
|
|
|
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_SUIT]'>[(wear_suit && !(wear_suit.item_flags & ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
if(wear_suit)
|
|
if(SLOT_S_STORE in obscured)
|
|
dat += "<tr><td><font color=grey> ↳<B>Suit Storage:</B></font></td></tr>"
|
|
else
|
|
dat += "<tr><td> ↳<B>Suit Storage:</B></td><td><A href='?src=[REF(src)];item=[SLOT_S_STORE]'>[(s_store && !(s_store.item_flags & ABSTRACT)) ? s_store : "<font color=grey>Empty</font>"]</A>"
|
|
if(has_breathable_mask && istype(s_store, /obj/item/tank))
|
|
dat += " <A href='?src=[REF(src)];internal=[SLOT_S_STORE]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
|
dat += "</td></tr>"
|
|
else
|
|
dat += "<tr><td><font color=grey> ↳<B>Suit Storage:</B></font></td></tr>"
|
|
|
|
if(SLOT_SHOES in obscured)
|
|
dat += "<tr><td><font color=grey><B>Shoes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=[REF(src)];item=[SLOT_SHOES]'>[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_GLOVES in obscured)
|
|
dat += "<tr><td><font color=grey><B>Gloves:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=[REF(src)];item=[SLOT_GLOVES]'>[(gloves && !(gloves.item_flags & ABSTRACT)) ? gloves : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if(SLOT_W_UNIFORM in obscured)
|
|
dat += "<tr><td><font color=grey><B>Uniform:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
|
else
|
|
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=[REF(src)];item=[SLOT_W_UNIFORM]'>[(w_uniform && !(w_uniform.item_flags & ABSTRACT)) ? w_uniform : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (SLOT_W_UNIFORM in obscured))
|
|
dat += "<tr><td><font color=grey> ↳<B>Pockets:</B></font></td></tr>"
|
|
dat += "<tr><td><font color=grey> ↳<B>ID:</B></font></td></tr>"
|
|
dat += "<tr><td><font color=grey> ↳<B>Belt:</B></font></td></tr>"
|
|
else
|
|
dat += "<tr><td> ↳<B>Belt:</B></td><td><A href='?src=[REF(src)];item=[SLOT_BELT]'>[(belt && !(belt.item_flags & ABSTRACT)) ? belt : "<font color=grey>Empty</font>"]</A>"
|
|
if(has_breathable_mask && istype(belt, /obj/item/tank))
|
|
dat += " <A href='?src=[REF(src)];internal=[SLOT_BELT]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
|
dat += "</td></tr>"
|
|
dat += "<tr><td> ↳<B>Pockets:</B></td><td><A href='?src=[REF(src)];pockets=left'>[(l_store && !(l_store.item_flags & ABSTRACT)) ? "Left (Full)" : "<font color=grey>Left (Empty)</font>"]</A>"
|
|
dat += " <A href='?src=[REF(src)];pockets=right'>[(r_store && !(r_store.item_flags & ABSTRACT)) ? "Right (Full)" : "<font color=grey>Right (Empty)</font>"]</A></td></tr>"
|
|
dat += "<tr><td> ↳<B>ID:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_ID]'>[(wear_id && !(wear_id.item_flags & ABSTRACT)) ? wear_id : "<font color=grey>Empty</font>"]</A></td></tr>"
|
|
|
|
// yogs start - show bandaged parts
|
|
for (var/obj/item/bodypart/org in bodyparts)
|
|
if (org.bandaged)
|
|
dat += "<tr><td><i>[org.name]</i> wrapped with:</td><td><a href='byond://?src=\ref[src];unwrap=\ref[org.bandaged]'>[org.bandaged]</a></td></tr>"
|
|
// yogs end
|
|
|
|
if(handcuffed)
|
|
dat += "<tr><td><B>Handcuffed:</B> <A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Remove</A></td></tr>"
|
|
if(legcuffed)
|
|
dat += "<tr><td><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A></td></tr>"
|
|
|
|
dat += {"</table>
|
|
<A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
|
"}
|
|
|
|
var/datum/browser/popup = new(user, "mob[REF(src)]", "[src]", 440, 510)
|
|
popup.set_content(dat.Join())
|
|
popup.open()
|
|
|
|
// called when something steps onto a human
|
|
// this could be made more general, but for now just handle mulebot
|
|
/mob/living/carbon/human/Crossed(atom/movable/AM)
|
|
var/mob/living/simple_animal/bot/mulebot/MB = AM
|
|
if(istype(MB))
|
|
MB.RunOver(src)
|
|
|
|
spreadFire(AM)
|
|
|
|
|
|
/mob/living/carbon/human/Topic(href, href_list)
|
|
if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
|
var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts
|
|
if(!L)
|
|
return
|
|
var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects
|
|
if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore
|
|
return
|
|
var/time_taken = I.embedding.embedded_unsafe_removal_time*I.w_class
|
|
usr.visible_message("<span class='warning'>[usr] attempts to remove [I] from [usr.p_their()] [L.name].</span>","<span class='notice'>You attempt to remove [I] from your [L.name]... (It will take [DisplayTimeText(time_taken)].)</span>")
|
|
if(do_after(usr, time_taken, needhand = 1, target = src))
|
|
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
|
|
return
|
|
L.embedded_objects -= I
|
|
L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
|
|
I.forceMove(get_turf(src))
|
|
usr.put_in_hands(I)
|
|
usr.emote("scream")
|
|
usr.visible_message("[usr] successfully rips [I] out of [usr.p_their()] [L.name]!","<span class='notice'>You successfully remove [I] from your [L.name].</span>")
|
|
if(!has_embedded_objects())
|
|
clear_alert("embeddedobject")
|
|
SEND_SIGNAL(usr, COMSIG_CLEAR_MOOD_EVENT, "embedded")
|
|
return
|
|
|
|
if(href_list["item"]) //canUseTopic check for this is handled by mob/Topic()
|
|
var/slot = text2num(href_list["item"])
|
|
if(slot in check_obscured_slots())
|
|
to_chat(usr, "<span class='warning'>You can't reach that! Something is covering it.</span>")
|
|
return
|
|
|
|
if(href_list["pockets"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) //TODO: Make it match (or intergrate it into) strippanel so you get 'item cannot fit here' warnings if mob_can_equip fails
|
|
var/pocket_side = href_list["pockets"]
|
|
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
|
|
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
|
|
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
|
|
|
|
var/delay_denominator = 1
|
|
if(pocket_item && !(pocket_item.item_flags & ABSTRACT))
|
|
if(pocket_item.item_flags & NODROP)
|
|
to_chat(usr, "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>")
|
|
to_chat(usr, "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>")
|
|
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT))
|
|
to_chat(usr, "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>")
|
|
delay_denominator = 4
|
|
else
|
|
return
|
|
|
|
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster
|
|
if(pocket_item)
|
|
if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search
|
|
dropItemToGround(pocket_item)
|
|
else
|
|
if(place_item)
|
|
if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE))
|
|
usr.temporarilyRemoveItemFromInventory(place_item, TRUE)
|
|
equip_to_slot(place_item, pocket_id, TRUE)
|
|
//do nothing otherwise
|
|
//updating inv screen after handled by living/Topic()
|
|
else
|
|
// Display a warning if the user mocks up
|
|
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
|
|
|
///////HUDs///////
|
|
if(href_list["hud"])
|
|
if(ishuman(usr))
|
|
var/mob/living/carbon/human/H = usr
|
|
var/perpname = get_face_name(get_id_name(""))
|
|
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud))
|
|
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general)
|
|
if(href_list["photo_front"] || href_list["photo_side"])
|
|
if(R)
|
|
if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
|
|
return
|
|
var/obj/item/photo/P = null
|
|
if(href_list["photo_front"])
|
|
P = R.fields["photo_front"]
|
|
else if(href_list["photo_side"])
|
|
P = R.fields["photo_side"]
|
|
if(P)
|
|
P.show(H)
|
|
|
|
if(href_list["hud"] == "m")
|
|
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
|
|
if(href_list["p_stat"])
|
|
var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
|
|
if(R)
|
|
if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
|
|
return
|
|
if(health_status && health_status != "Cancel")
|
|
R.fields["p_stat"] = health_status
|
|
return
|
|
if(href_list["m_stat"])
|
|
var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
|
|
if(R)
|
|
if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/medical))
|
|
return
|
|
if(health_status && health_status != "Cancel")
|
|
R.fields["m_stat"] = health_status
|
|
return
|
|
if(href_list["evaluation"])
|
|
if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20)
|
|
to_chat(usr, "<span class='notice'>No external injuries detected.</span><br>")
|
|
return
|
|
var/span = "notice"
|
|
var/status = ""
|
|
if(getBruteLoss())
|
|
to_chat(usr, "<b>Physical trauma analysis:</b>")
|
|
for(var/X in bodyparts)
|
|
var/obj/item/bodypart/BP = X
|
|
var/brutedamage = BP.brute_dam
|
|
if(brutedamage > 0)
|
|
status = "received minor physical injuries."
|
|
span = "notice"
|
|
if(brutedamage > 20)
|
|
status = "been seriously damaged."
|
|
span = "danger"
|
|
if(brutedamage > 40)
|
|
status = "sustained major trauma!"
|
|
span = "userdanger"
|
|
if(brutedamage)
|
|
to_chat(usr, "<span class='[span]'>[BP] appears to have [status]</span>")
|
|
if(getFireLoss())
|
|
to_chat(usr, "<b>Analysis of skin burns:</b>")
|
|
for(var/X in bodyparts)
|
|
var/obj/item/bodypart/BP = X
|
|
var/burndamage = BP.burn_dam
|
|
if(burndamage > 0)
|
|
status = "signs of minor burns."
|
|
span = "notice"
|
|
if(burndamage > 20)
|
|
status = "serious burns."
|
|
span = "danger"
|
|
if(burndamage > 40)
|
|
status = "major burns!"
|
|
span = "userdanger"
|
|
if(burndamage)
|
|
to_chat(usr, "<span class='[span]'>[BP] appears to have [status]</span>")
|
|
if(getOxyLoss())
|
|
to_chat(usr, "<span class='danger'>Patient has signs of suffocation, emergency treatment may be required!</span>")
|
|
if(getToxLoss() > 20)
|
|
to_chat(usr, "<span class='danger'>Gathered data is inconsistent with the analysis, possible cause: poisoning.</span>")
|
|
|
|
if(href_list["hud"] == "s")
|
|
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
|
|
return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
|
|
// Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
|
|
var/allowed_access = null
|
|
var/obj/item/clothing/glasses/hud/security/G = H.glasses
|
|
if(istype(G) && (G.obj_flags & EMAGGED))
|
|
allowed_access = "@%&ERROR_%$*"
|
|
else //Implant and standard glasses check access
|
|
if(H.wear_id)
|
|
var/list/access = H.wear_id.GetAccess()
|
|
if(ACCESS_SEC_DOORS in access)
|
|
allowed_access = H.get_authentification_name()
|
|
|
|
if(!allowed_access)
|
|
to_chat(H, "<span class='warning'>ERROR: Invalid Access</span>")
|
|
return
|
|
|
|
if(perpname)
|
|
R = find_record("name", perpname, GLOB.data_core.security)
|
|
if(R)
|
|
if(href_list["status"])
|
|
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged", "Cancel")
|
|
if(setcriminal != "Cancel")
|
|
if(R)
|
|
if(H.canUseHUD())
|
|
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
investigate_log("[key_name(src)] has been set from [R.fields["criminal"]] to [setcriminal] by [key_name(usr)].", INVESTIGATE_RECORDS)
|
|
R.fields["criminal"] = setcriminal
|
|
sec_hud_set_security_status()
|
|
return
|
|
|
|
if(href_list["view"])
|
|
if(R)
|
|
if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
return
|
|
to_chat(usr, "<b>Name:</b> [R.fields["name"]] <b>Criminal Status:</b> [R.fields["criminal"]]")
|
|
to_chat(usr, "<b>Minor Crimes:</b>")
|
|
for(var/datum/data/crime/c in R.fields["mi_crim"])
|
|
to_chat(usr, "<b>Crime:</b> [c.crimeName]")
|
|
to_chat(usr, "<b>Details:</b> [c.crimeDetails]")
|
|
to_chat(usr, "Added by [c.author] at [c.time]")
|
|
to_chat(usr, "----------")
|
|
to_chat(usr, "<b>Major Crimes:</b>")
|
|
for(var/datum/data/crime/c in R.fields["ma_crim"])
|
|
to_chat(usr, "<b>Crime:</b> [c.crimeName]")
|
|
to_chat(usr, "<b>Details:</b> [c.crimeDetails]")
|
|
to_chat(usr, "Added by [c.author] at [c.time]")
|
|
to_chat(usr, "----------")
|
|
to_chat(usr, "<b>Notes:</b> [R.fields["notes"]]")
|
|
return
|
|
|
|
if(href_list["add_crime"])
|
|
switch(alert("What crime would you like to add?","Security HUD","Minor Crime","Major Crime","Cancel"))
|
|
if("Minor Crime")
|
|
if(R)
|
|
var/t1 = stripped_input("Please input minor crime names:", "Security HUD", "", null)
|
|
var/t2 = stripped_multiline_input("Please input minor crime details:", "Security HUD", "", null)
|
|
if(R)
|
|
if (!t1 || !t2 || !allowed_access)
|
|
return
|
|
else if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
return
|
|
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, station_time_timestamp())
|
|
GLOB.data_core.addMinorCrime(R.fields["id"], crime)
|
|
investigate_log("New Minor Crime: <strong>[t1]</strong>: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
|
|
to_chat(usr, "<span class='notice'>Successfully added a minor crime.</span>")
|
|
return
|
|
if("Major Crime")
|
|
if(R)
|
|
var/t1 = stripped_input("Please input major crime names:", "Security HUD", "", null)
|
|
var/t2 = stripped_multiline_input("Please input major crime details:", "Security HUD", "", null)
|
|
if(R)
|
|
if (!t1 || !t2 || !allowed_access)
|
|
return
|
|
else if (!H.canUseHUD())
|
|
return
|
|
else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
return
|
|
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, station_time_timestamp())
|
|
GLOB.data_core.addMajorCrime(R.fields["id"], crime)
|
|
investigate_log("New Major Crime: <strong>[t1]</strong>: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
|
|
to_chat(usr, "<span class='notice'>Successfully added a major crime.</span>")
|
|
return
|
|
|
|
if(href_list["view_comment"])
|
|
if(R)
|
|
if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
return
|
|
to_chat(usr, "<b>Comments/Log:</b>")
|
|
var/counter = 1
|
|
while(R.fields[text("com_[]", counter)])
|
|
to_chat(usr, R.fields[text("com_[]", counter)])
|
|
to_chat(usr, "----------")
|
|
counter++
|
|
return
|
|
|
|
if(href_list["add_comment"])
|
|
if(R)
|
|
var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null)
|
|
if(R)
|
|
if (!t1 || !allowed_access)
|
|
return
|
|
else if(!H.canUseHUD())
|
|
return
|
|
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
|
|
return
|
|
var/counter = 1
|
|
while(R.fields[text("com_[]", counter)])
|
|
counter++
|
|
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, station_time_timestamp(), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
|
|
to_chat(usr, "<span class='notice'>Successfully added comment.</span>")
|
|
return
|
|
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
|
|
|
..() //end of this massive fucking chain. TODO: make the hud chain not spooky.
|
|
|
|
|
|
/mob/living/carbon/human/proc/canUseHUD()
|
|
return (mobility_flags & MOBILITY_USE)
|
|
|
|
/mob/living/carbon/human/can_inject(mob/user, error_msg, target_zone, var/penetrate_thick = 0)
|
|
. = 1 // Default to returning true.
|
|
if(user && !target_zone)
|
|
target_zone = user.zone_selected
|
|
if(has_trait(TRAIT_PIERCEIMMUNE))
|
|
. = 0
|
|
// If targeting the head, see if the head item is thin enough.
|
|
// If targeting anything else, see if the wear suit is thin enough.
|
|
if (!penetrate_thick)
|
|
if(above_neck(target_zone))
|
|
if(head && istype(head, /obj/item/clothing))
|
|
var/obj/item/clothing/CH = head
|
|
if (CH.clothing_flags & THICKMATERIAL)
|
|
. = 0
|
|
else
|
|
if(wear_suit && istype(wear_suit, /obj/item/clothing))
|
|
var/obj/item/clothing/CS = wear_suit
|
|
if (CS.clothing_flags & THICKMATERIAL)
|
|
. = 0
|
|
if(!. && error_msg && user)
|
|
// Might need re-wording.
|
|
to_chat(user, "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].</span>")
|
|
|
|
/mob/living/carbon/human/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
|
|
if(judgement_criteria & JUDGE_EMAGGED)
|
|
return 10 //Everyone is a criminal!
|
|
|
|
var/threatcount = 0
|
|
|
|
//Lasertag bullshit
|
|
if(lasercolor)
|
|
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
|
if(istype(wear_suit, /obj/item/clothing/suit/redtag))
|
|
threatcount += 4
|
|
if(is_holding_item_of_type(/obj/item/gun/energy/laser/redtag))
|
|
threatcount += 4
|
|
if(istype(belt, /obj/item/gun/energy/laser/redtag))
|
|
threatcount += 2
|
|
|
|
if(lasercolor == "r")
|
|
if(istype(wear_suit, /obj/item/clothing/suit/bluetag))
|
|
threatcount += 4
|
|
if(is_holding_item_of_type(/obj/item/gun/energy/laser/bluetag))
|
|
threatcount += 4
|
|
if(istype(belt, /obj/item/gun/energy/laser/bluetag))
|
|
threatcount += 2
|
|
|
|
return threatcount
|
|
|
|
//Check for ID
|
|
var/obj/item/card/id/idcard = get_idcard(FALSE)
|
|
if( (judgement_criteria & JUDGE_IDCHECK) && !idcard && name=="Unknown")
|
|
threatcount += 4
|
|
|
|
//Check for weapons
|
|
if( (judgement_criteria & JUDGE_WEAPONCHECK) && weaponcheck)
|
|
if(!idcard || !(ACCESS_WEAPONS in idcard.access))
|
|
for(var/obj/item/I in held_items) //if they're holding a gun
|
|
if(weaponcheck.Invoke(I))
|
|
threatcount += 4
|
|
if(weaponcheck.Invoke(belt) || weaponcheck.Invoke(back)) //if a weapon is present in the belt or back slot
|
|
threatcount += 2 //not enough to trigger look_for_perp() on it's own unless they also have criminal status.
|
|
|
|
//Check for arrest warrant
|
|
if(judgement_criteria & JUDGE_RECORDCHECK)
|
|
var/perpname = get_face_name(get_id_name())
|
|
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security)
|
|
if(R && R.fields["criminal"])
|
|
switch(R.fields["criminal"])
|
|
if("*Arrest*")
|
|
threatcount += 5
|
|
if("Incarcerated")
|
|
threatcount += 2
|
|
if("Paroled")
|
|
threatcount += 2
|
|
|
|
//Check for dresscode violations
|
|
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
|
|
threatcount += 2
|
|
|
|
//Check for nonhuman scum
|
|
if(dna && dna.species.id && dna.species.id != "human")
|
|
threatcount += 1
|
|
|
|
//mindshield implants imply trustworthyness
|
|
if(has_trait(TRAIT_MINDSHIELD))
|
|
threatcount -= 1
|
|
|
|
//Agent cards lower threatlevel.
|
|
if(istype(idcard, /obj/item/card/id/syndicate))
|
|
threatcount -= 5
|
|
|
|
return threatcount
|
|
|
|
|
|
//Used for new human mobs created by cloning/goleming/podding
|
|
/mob/living/carbon/human/proc/set_cloned_appearance()
|
|
if(gender == MALE)
|
|
facial_hair_style = "Full Beard"
|
|
else
|
|
facial_hair_style = "Shaved"
|
|
hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
|
|
underwear = "Nude"
|
|
update_body()
|
|
update_hair()
|
|
|
|
/mob/living/carbon/human/singularity_pull(S, current_size)
|
|
..()
|
|
if(current_size >= STAGE_THREE)
|
|
for(var/obj/item/hand in held_items)
|
|
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand))
|
|
step_towards(hand, src)
|
|
to_chat(src, "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>")
|
|
rad_act(current_size * 3)
|
|
|
|
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
|
|
CHECK_DNA_AND_SPECIES(C)
|
|
|
|
if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH)))
|
|
to_chat(src, "<span class='warning'>[C.name] is dead!</span>")
|
|
return
|
|
if(is_mouth_covered())
|
|
to_chat(src, "<span class='warning'>Remove your mask first!</span>")
|
|
return 0
|
|
if(C.is_mouth_covered())
|
|
to_chat(src, "<span class='warning'>Remove [p_their()] mask first!</span>")
|
|
return 0
|
|
|
|
if(C.cpr_time < world.time + 30)
|
|
visible_message("<span class='notice'>[src] is trying to perform CPR on [C.name]!</span>", \
|
|
"<span class='notice'>You try to perform CPR on [C.name]... Hold still!</span>")
|
|
if(!do_mob(src, C))
|
|
to_chat(src, "<span class='warning'>You fail to perform CPR on [C]!</span>")
|
|
return 0
|
|
|
|
var/they_breathe = !C.has_trait(TRAIT_NOBREATH)
|
|
var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
|
|
|
|
if(C.health > C.crit_threshold)
|
|
return
|
|
|
|
src.visible_message("[src] performs CPR on [C.name]!", "<span class='notice'>You perform CPR on [C.name].</span>")
|
|
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "perform_cpr", /datum/mood_event/perform_cpr)
|
|
C.cpr_time = world.time
|
|
log_combat(src, C, "CPRed")
|
|
|
|
if(they_breathe && they_lung)
|
|
var/suff = min(C.getOxyLoss(), 7)
|
|
C.adjustOxyLoss(-suff)
|
|
C.updatehealth()
|
|
to_chat(C, "<span class='unconscious'>You feel a breath of fresh air enter your lungs... It feels good...</span>")
|
|
else if(they_breathe && !they_lung)
|
|
to_chat(C, "<span class='unconscious'>You feel a breath of fresh air... but you don't feel any better...</span>")
|
|
else
|
|
to_chat(C, "<span class='unconscious'>You feel a breath of fresh air... which is a sensation you don't recognise...</span>")
|
|
|
|
/mob/living/carbon/human/cuff_resist(obj/item/I)
|
|
if(dna && dna.check_mutation(HULK))
|
|
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
|
|
if(..(I, cuff_break = FAST_CUFFBREAK))
|
|
dropItemToGround(I)
|
|
else
|
|
if(..())
|
|
dropItemToGround(I)
|
|
|
|
/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
|
|
if(strength < CLEAN_STRENGTH_BLOOD)
|
|
return
|
|
if(gloves)
|
|
if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
|
|
update_inv_gloves()
|
|
else
|
|
if(bloody_hands)
|
|
bloody_hands = 0
|
|
update_inv_gloves()
|
|
|
|
/mob/living/carbon/human/wash_cream()
|
|
if(creamed) //clean both to prevent a rare bug
|
|
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
|
|
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human"))
|
|
creamed = FALSE
|
|
|
|
//Turns a mob black, flashes a skeleton overlay
|
|
//Just like a cartoon!
|
|
/mob/living/carbon/human/proc/electrocution_animation(anim_duration)
|
|
//Handle mutant parts if possible
|
|
if(dna && dna.species)
|
|
add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY)
|
|
var/static/mutable_appearance/electrocution_skeleton_anim
|
|
if(!electrocution_skeleton_anim)
|
|
electrocution_skeleton_anim = mutable_appearance(icon, "electrocuted_base")
|
|
electrocution_skeleton_anim.appearance_flags |= RESET_COLOR|KEEP_APART
|
|
add_overlay(electrocution_skeleton_anim)
|
|
addtimer(CALLBACK(src, .proc/end_electrocution_animation, electrocution_skeleton_anim), anim_duration)
|
|
|
|
else //or just do a generic animation
|
|
flick_overlay_view(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), src, anim_duration)
|
|
|
|
/mob/living/carbon/human/proc/end_electrocution_animation(mutable_appearance/MA)
|
|
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
|
|
cut_overlay(MA)
|
|
|
|
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
|
if(!(mobility_flags & MOBILITY_UI))
|
|
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
|
|
return FALSE
|
|
if(!Adjacent(M) && (M.loc != src))
|
|
if((be_close == 0) || (!no_tk && (dna.check_mutation(TK) && tkMaxRangeCheck(src, M))))
|
|
return TRUE
|
|
to_chat(src, "<span class='warning'>You are too far away!</span>")
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/carbon/human/resist_restraints()
|
|
if(wear_suit && wear_suit.breakouttime)
|
|
changeNext_move(CLICK_CD_BREAKOUT)
|
|
last_special = world.time + CLICK_CD_BREAKOUT
|
|
cuff_resist(wear_suit)
|
|
else
|
|
..()
|
|
|
|
/mob/living/carbon/human/replace_records_name(oldname,newname) // Only humans have records right now, move this up if changed.
|
|
for(var/list/L in list(GLOB.data_core.general,GLOB.data_core.medical,GLOB.data_core.security,GLOB.data_core.locked))
|
|
var/datum/data/record/R = find_record("name", oldname, L)
|
|
if(R)
|
|
R.fields["name"] = newname
|
|
|
|
/mob/living/carbon/human/get_total_tint()
|
|
. = ..()
|
|
if(glasses)
|
|
. += glasses.tint
|
|
|
|
/mob/living/carbon/human/update_health_hud()
|
|
if(!client || !hud_used)
|
|
return
|
|
if(dna.species.update_health_hud())
|
|
return
|
|
else
|
|
if(hud_used.healths)
|
|
var/health_amount = health - getStaminaLoss()
|
|
if(..(health_amount)) //not dead
|
|
switch(hal_screwyhud)
|
|
if(SCREWYHUD_CRIT)
|
|
hud_used.healths.icon_state = "health6"
|
|
if(SCREWYHUD_DEAD)
|
|
hud_used.healths.icon_state = "health7"
|
|
if(SCREWYHUD_HEALTHY)
|
|
hud_used.healths.icon_state = "health0"
|
|
if(hud_used.healthdoll)
|
|
hud_used.healthdoll.cut_overlays()
|
|
if(stat != DEAD)
|
|
hud_used.healthdoll.icon_state = "healthdoll_OVERLAY"
|
|
for(var/X in bodyparts)
|
|
var/obj/item/bodypart/BP = X
|
|
var/damage = BP.burn_dam + BP.brute_dam
|
|
var/comparison = (BP.max_damage/5)
|
|
var/icon_num = 0
|
|
if(damage)
|
|
icon_num = 1
|
|
if(damage > (comparison))
|
|
icon_num = 2
|
|
if(damage > (comparison*2))
|
|
icon_num = 3
|
|
if(damage > (comparison*3))
|
|
icon_num = 4
|
|
if(damage > (comparison*4))
|
|
icon_num = 5
|
|
if(hal_screwyhud == SCREWYHUD_HEALTHY)
|
|
icon_num = 0
|
|
if(icon_num)
|
|
hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[BP.body_zone][icon_num]"))
|
|
for(var/t in get_missing_limbs()) //Missing limbs
|
|
hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]6"))
|
|
for(var/t in get_disabled_limbs()) //Disabled limbs
|
|
hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]7"))
|
|
else
|
|
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
|
|
|
|
/mob/living/carbon/human/fully_heal(admin_revive = 0)
|
|
dna?.species.spec_fully_heal(src)
|
|
if(admin_revive)
|
|
regenerate_limbs()
|
|
regenerate_organs()
|
|
remove_all_embedded_objects()
|
|
set_heartattack(FALSE)
|
|
drunkenness = 0
|
|
for(var/datum/mutation/human/HM in dna.mutations)
|
|
if(HM.quality != POSITIVE)
|
|
dna.remove_mutation(HM.name)
|
|
..()
|
|
|
|
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
|
|
. = ..()
|
|
if (dna && dna.species)
|
|
. += dna.species.check_weakness(weapon, attacker)
|
|
|
|
/mob/living/carbon/human/is_literate()
|
|
return TRUE
|
|
|
|
/mob/living/carbon/human/can_hold_items()
|
|
return TRUE
|
|
|
|
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
|
|
if(dna && dna.species) //prevents a runtime while a human is being monkeyfied
|
|
override = dna.species.override_float
|
|
..()
|
|
|
|
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
|
|
if(blood && (NOBLOOD in dna.species.species_traits))
|
|
if(message)
|
|
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
|
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
|
if(stun)
|
|
Paralyze(200)
|
|
return 1
|
|
..()
|
|
|
|
/mob/living/carbon/human/vv_get_dropdown()
|
|
. = ..()
|
|
. += "---"
|
|
.["Make monkey"] = "?_src_=vars;[HrefToken()];makemonkey=[REF(src)]"
|
|
.["Set Species"] = "?_src_=vars;[HrefToken()];setspecies=[REF(src)]"
|
|
.["Make cyborg"] = "?_src_=vars;[HrefToken()];makerobot=[REF(src)]"
|
|
.["Make alien"] = "?_src_=vars;[HrefToken()];makealien=[REF(src)]"
|
|
.["Make slime"] = "?_src_=vars;[HrefToken()];makeslime=[REF(src)]"
|
|
.["Toggle Purrbation"] = "?_src_=vars;[HrefToken()];purrbation=[REF(src)]"
|
|
.["Copy outfit"] = "?_src_=vars;[HrefToken()];copyoutfit=[REF(src)]"
|
|
.["Make Cluwne"] = "?_src_=vars;[HrefToken()];cluwneing=[REF(src)]" // yogs -- make cluwne
|
|
|
|
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
|
|
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
|
|
if(user == target && can_piggyback(target) && pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
|
|
buckle_mob(target,TRUE,TRUE)
|
|
. = ..()
|
|
|
|
//Can C try to piggyback at all.
|
|
/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C)
|
|
if(istype(C) && C.stat == CONSCIOUS)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
|
|
if(!force)//humans are only meant to be ridden through piggybacking and special cases
|
|
return
|
|
if(!is_type_in_typecache(M, can_ride_typecache))
|
|
M.visible_message("<span class='warning'>[M] really can't seem to mount [src]...</span>")
|
|
return
|
|
var/datum/component/riding/human/riding_datum = LoadComponent(/datum/component/riding/human)
|
|
riding_datum.ride_check_rider_incapacitated = TRUE
|
|
riding_datum.ride_check_rider_restrained = TRUE
|
|
riding_datum.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4)))
|
|
if(buckled_mobs && ((M in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled || (M.stat != CONSCIOUS))
|
|
return
|
|
if(can_piggyback(M))
|
|
riding_datum.ride_check_ridden_incapacitated = TRUE
|
|
visible_message("<span class='notice'>[M] starts to climb onto [src]...</span>")
|
|
if(do_after(M, 15, target = src))
|
|
if(can_piggyback(M))
|
|
if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
|
M.visible_message("<span class='warning'>[M] can't hang onto [src]!</span>")
|
|
return
|
|
if(!riding_datum.equip_buckle_inhands(M, 2)) //MAKE SURE THIS IS LAST!!
|
|
M.visible_message("<span class='warning'>[M] can't climb onto [src]!</span>")
|
|
return
|
|
. = ..(M, force, check_loc)
|
|
stop_pulling()
|
|
else
|
|
visible_message("<span class='warning'>[M] fails to climb onto [src]!</span>")
|
|
else
|
|
. = ..(M,force,check_loc)
|
|
stop_pulling()
|
|
|
|
/mob/living/carbon/human/do_after_coefficent()
|
|
. = ..()
|
|
. *= physiology.do_after_speed
|
|
|
|
/mob/living/carbon/human/updatehealth()
|
|
. = ..()
|
|
dna?.species.spec_updatehealth(src)
|
|
|
|
/mob/living/carbon/human/adjust_nutrition(var/change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
|
|
if(has_trait(TRAIT_NOHUNGER))
|
|
return FALSE
|
|
return ..()
|
|
|
|
/mob/living/carbon/human/set_nutrition(var/change) //Seriously fuck you oldcoders.
|
|
if(has_trait(TRAIT_NOHUNGER))
|
|
return FALSE
|
|
return ..()
|
|
|
|
/mob/living/carbon/human/species
|
|
var/race = null
|
|
|
|
/mob/living/carbon/human/species/Initialize()
|
|
. = ..()
|
|
set_species(race)
|
|
|
|
/mob/living/carbon/human/species/abductor
|
|
race = /datum/species/abductor
|
|
|
|
/mob/living/carbon/human/species/android
|
|
race = /datum/species/android
|
|
|
|
/mob/living/carbon/human/species/angel
|
|
race = /datum/species/angel
|
|
|
|
/mob/living/carbon/human/species/corporate
|
|
race = /datum/species/corporate
|
|
|
|
/mob/living/carbon/human/species/dullahan
|
|
race = /datum/species/dullahan
|
|
|
|
/mob/living/carbon/human/species/felinid
|
|
race = /datum/species/human/felinid
|
|
|
|
/mob/living/carbon/human/species/fly
|
|
race = /datum/species/fly
|
|
|
|
/mob/living/carbon/human/species/golem
|
|
race = /datum/species/golem
|
|
|
|
/mob/living/carbon/human/species/golem/random
|
|
race = /datum/species/golem/random
|
|
|
|
/mob/living/carbon/human/species/golem/adamantine
|
|
race = /datum/species/golem/adamantine
|
|
|
|
/mob/living/carbon/human/species/golem/plasma
|
|
race = /datum/species/golem/plasma
|
|
|
|
/mob/living/carbon/human/species/golem/diamond
|
|
race = /datum/species/golem/diamond
|
|
|
|
/mob/living/carbon/human/species/golem/gold
|
|
race = /datum/species/golem/gold
|
|
|
|
/mob/living/carbon/human/species/golem/silver
|
|
race = /datum/species/golem/silver
|
|
|
|
/mob/living/carbon/human/species/golem/plasteel
|
|
race = /datum/species/golem/plasteel
|
|
|
|
/mob/living/carbon/human/species/golem/titanium
|
|
race = /datum/species/golem/titanium
|
|
|
|
/mob/living/carbon/human/species/golem/plastitanium
|
|
race = /datum/species/golem/plastitanium
|
|
|
|
/mob/living/carbon/human/species/golem/alien_alloy
|
|
race = /datum/species/golem/alloy
|
|
|
|
/mob/living/carbon/human/species/golem/wood
|
|
race = /datum/species/golem/wood
|
|
|
|
/mob/living/carbon/human/species/golem/uranium
|
|
race = /datum/species/golem/uranium
|
|
|
|
/mob/living/carbon/human/species/golem/sand
|
|
race = /datum/species/golem/sand
|
|
|
|
/mob/living/carbon/human/species/golem/glass
|
|
race = /datum/species/golem/glass
|
|
|
|
/mob/living/carbon/human/species/golem/bluespace
|
|
race = /datum/species/golem/bluespace
|
|
|
|
/mob/living/carbon/human/species/golem/bananium
|
|
race = /datum/species/golem/bananium
|
|
|
|
/mob/living/carbon/human/species/golem/blood_cult
|
|
race = /datum/species/golem/runic
|
|
|
|
/mob/living/carbon/human/species/golem/cloth
|
|
race = /datum/species/golem/cloth
|
|
|
|
/mob/living/carbon/human/species/golem/plastic
|
|
race = /datum/species/golem/plastic
|
|
|
|
/mob/living/carbon/human/species/golem/clockwork
|
|
race = /datum/species/golem/clockwork
|
|
|
|
/mob/living/carbon/human/species/golem/clockwork/no_scrap
|
|
race = /datum/species/golem/clockwork/no_scrap
|
|
|
|
/mob/living/carbon/human/species/jelly
|
|
race = /datum/species/jelly
|
|
|
|
/mob/living/carbon/human/species/jelly/slime
|
|
race = /datum/species/jelly/slime
|
|
|
|
/mob/living/carbon/human/species/jelly/stargazer
|
|
race = /datum/species/jelly/stargazer
|
|
|
|
/mob/living/carbon/human/species/jelly/luminescent
|
|
race = /datum/species/jelly/luminescent
|
|
|
|
/mob/living/carbon/human/species/lizard
|
|
race = /datum/species/lizard
|
|
|
|
/mob/living/carbon/human/species/ethereal
|
|
race = /datum/species/ethereal
|
|
|
|
/mob/living/carbon/human/species/lizard/ashwalker
|
|
race = /datum/species/lizard/ashwalker
|
|
|
|
/mob/living/carbon/human/species/moth
|
|
race = /datum/species/moth
|
|
|
|
/mob/living/carbon/human/species/mush
|
|
race = /datum/species/mush
|
|
|
|
/mob/living/carbon/human/species/plasma
|
|
race = /datum/species/plasmaman
|
|
|
|
/mob/living/carbon/human/species/pod
|
|
race = /datum/species/pod
|
|
|
|
/mob/living/carbon/human/species/shadow
|
|
race = /datum/species/shadow
|
|
|
|
/mob/living/carbon/human/species/shadow/nightmare
|
|
race = /datum/species/shadow/nightmare
|
|
|
|
/mob/living/carbon/human/species/skeleton
|
|
race = /datum/species/skeleton
|
|
|
|
/mob/living/carbon/human/species/synth
|
|
race = /datum/species/synth
|
|
|
|
/mob/living/carbon/human/species/synth/military
|
|
race = /datum/species/synth/military
|
|
|
|
/mob/living/carbon/human/species/vampire
|
|
race = /datum/species/vampire
|
|
|
|
/mob/living/carbon/human/species/zombie
|
|
race = /datum/species/zombie
|
|
|
|
/mob/living/carbon/human/species/zombie/infectious
|
|
race = /datum/species/zombie/infectious
|
|
|
|
/mob/living/carbon/human/species/zombie/krokodil_addict
|
|
race = /datum/species/krokodil_addict
|