Merge branch 'master' into familyport
This commit is contained in:
@@ -6,8 +6,6 @@
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
hud_type = /datum/hud/alien
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
|
||||
var/leap_on_click = 0
|
||||
@@ -22,41 +20,26 @@
|
||||
|
||||
can_ventcrawl = TRUE
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list(
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_alien_humanoid_items)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
return handcuffed
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<span class='big bold'>[name]</span>
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=[REF(src)];item=[SLOT_HANDS];hand_index=[i]'>[(I && !(I.item_flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=[REF(src)];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
||||
"}
|
||||
user << browse(dat.Join(), "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "mob[REF(src)]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel & embeds
|
||||
@@ -70,12 +53,6 @@
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
|
||||
return
|
||||
if(href_list["pouches"])
|
||||
visible_message("<span class='danger'>[usr] tries to empty [src]'s pouches.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pouches.</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
|
||||
dropItemToGround(r_store)
|
||||
dropItemToGround(l_store)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
|
||||
@@ -51,10 +51,6 @@
|
||||
// new damage icon system
|
||||
// now constructs damage icon for each organ from mask * damage field
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/show_inv(mob/user)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/toggle_throw_mode()
|
||||
return
|
||||
|
||||
|
||||
@@ -229,61 +229,8 @@
|
||||
/mob/living/carbon/proc/canBeHandcuffed()
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=[REF(src)];item=[SLOT_HEAD]'> [(head && !(head.item_flags & ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=[REF(src)];item=[SLOT_WEAR_MASK]'> [(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Neck:</B> <A href='?src=[REF(src)];item=[SLOT_NECK]'> [(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
|
||||
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><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 : "Nothing"]</a>"
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=[REF(src)];item=[SLOT_BACK]'>[back ? back : "Nothing"]</A>"
|
||||
|
||||
if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS) && istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
|
||||
dat += "<BR><A href='?src=[REF(src)];internal=1'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "mob[REF(src)]")
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel
|
||||
if(usr.canUseTopic(src, BE_CLOSE))
|
||||
if(href_list["internal"] && !HAS_TRAIT(src, TRAIT_NO_INTERNALS))
|
||||
var/slot = text2num(href_list["internal"])
|
||||
var/obj/item/ITEM = get_item_by_slot(slot)
|
||||
if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS))
|
||||
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY))
|
||||
if(internal)
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
else if(ITEM && istype(ITEM, /obj/item/tank))
|
||||
if((wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
internal = ITEM
|
||||
update_internals_hud_icon(1)
|
||||
|
||||
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>", \
|
||||
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>")
|
||||
if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE))
|
||||
var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts
|
||||
if(!L)
|
||||
@@ -699,7 +646,7 @@
|
||||
become_blind(EYES_COVERED)
|
||||
else if(tinttotal >= TINT_DARKENED)
|
||||
cure_blind(EYES_COVERED)
|
||||
overlay_fullscreen("tint", /atom/movable/screen/fullscreen/impaired, 2)
|
||||
overlay_fullscreen("tint", /atom/movable/screen/fullscreen/scaled/impaired, 2)
|
||||
else
|
||||
cure_blind(EYES_COVERED)
|
||||
clear_fullscreen("tint", 0)
|
||||
@@ -775,10 +722,10 @@
|
||||
visionseverity = 9
|
||||
if(-INFINITY to -24)
|
||||
visionseverity = 10
|
||||
overlay_fullscreen("critvision", /atom/movable/screen/fullscreen/crit/vision, visionseverity)
|
||||
overlay_fullscreen("critvision", /atom/movable/screen/fullscreen/scaled/crit/vision, visionseverity)
|
||||
else
|
||||
clear_fullscreen("critvision")
|
||||
overlay_fullscreen("crit", /atom/movable/screen/fullscreen/crit, severity)
|
||||
overlay_fullscreen("crit", /atom/movable/screen/fullscreen/scaled/crit, severity)
|
||||
else
|
||||
clear_fullscreen("crit")
|
||||
clear_fullscreen("critvision")
|
||||
@@ -802,7 +749,7 @@
|
||||
severity = 6
|
||||
if(45 to INFINITY)
|
||||
severity = 7
|
||||
overlay_fullscreen("oxy", /atom/movable/screen/fullscreen/oxy, severity)
|
||||
overlay_fullscreen("oxy", /atom/movable/screen/fullscreen/scaled/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
|
||||
@@ -823,7 +770,7 @@
|
||||
severity = 5
|
||||
if(85 to INFINITY)
|
||||
severity = 6
|
||||
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
|
||||
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@
|
||||
|
||||
return embeds
|
||||
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0)
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash, override_protection = 0)
|
||||
. = ..()
|
||||
|
||||
var/damage = override_protection ? intensity : intensity - get_eye_protection()
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/datum/strippable_item/mob_item_slot/head
|
||||
key = STRIPPABLE_ITEM_HEAD
|
||||
item_slot = SLOT_HEAD
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back
|
||||
key = STRIPPABLE_ITEM_BACK
|
||||
item_slot = SLOT_BACK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask
|
||||
key = STRIPPABLE_ITEM_MASK
|
||||
item_slot = SLOT_WEAR_MASK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/neck
|
||||
key = STRIPPABLE_ITEM_NECK
|
||||
item_slot = SLOT_NECK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs
|
||||
key = STRIPPABLE_ITEM_HANDCUFFS
|
||||
item_slot = SLOT_HANDCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/should_show(atom/source, mob/user)
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.handcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to handcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs
|
||||
key = STRIPPABLE_ITEM_LEGCUFFS
|
||||
item_slot = SLOT_LEGCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/should_show(atom/source, mob/user)
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.legcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to legcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/// A strippable item for a hand
|
||||
/datum/strippable_item/hand
|
||||
// Putting dangerous clothing in our hand is fine.
|
||||
warn_dangerous_clothing = FALSE
|
||||
|
||||
/// Which hand?
|
||||
var/hand_index
|
||||
|
||||
/datum/strippable_item/hand/get_item(atom/source)
|
||||
if (!ismob(source))
|
||||
return null
|
||||
|
||||
var/mob/mob_source = source
|
||||
return mob_source.get_item_for_held_index(hand_index)
|
||||
|
||||
/datum/strippable_item/hand/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
|
||||
if (!mob_source.can_put_in_hand(equipping, hand_index))
|
||||
to_chat(src, "<span class='warning'>\The [equipping] doesn't fit in that place!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
|
||||
if (!do_mob(user, source, equipping.equip_delay_other))
|
||||
return FALSE
|
||||
|
||||
if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY)
|
||||
return FALSE
|
||||
|
||||
if (!mob_source.can_put_in_hand(equipping, hand_index))
|
||||
return FALSE
|
||||
|
||||
if (!user.temporarilyRemoveItemFromInventory(equipping))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
mob_source.put_in_hand(equipping, hand_index)
|
||||
|
||||
/datum/strippable_item/hand/start_unequip(atom/source, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
|
||||
return start_unequip_mob(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/hand/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/obj/item/item = get_item(source)
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
return finish_unequip_mob(item, source, user)
|
||||
|
||||
/datum/strippable_item/hand/left
|
||||
key = STRIPPABLE_ITEM_LHAND
|
||||
hand_index = 1
|
||||
|
||||
/datum/strippable_item/hand/right
|
||||
key = STRIPPABLE_ITEM_RHAND
|
||||
hand_index = 2
|
||||
@@ -37,7 +37,7 @@
|
||||
var/list/whatmighthappen = list()
|
||||
whatmighthappen += list("avoided" = 3, "dropthing" = 1, "movetile" = 1, "shortdeaf" = 1, "flopover" = 1, "nutriloss" = 1, "selfflash" = 1, "harmies" = 1)
|
||||
if(corruption >= CORRUPTION_THRESHHOLD_MAJOR)
|
||||
whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "halluscinate" = 1)
|
||||
whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "hallucinate" = 1, "jamcoolanthud" = 1)
|
||||
if(corruption >= CORRUPTION_THRESHHOLD_CRITICAL)
|
||||
whatmighthappen += list("receporgandamage" = 1, "longlimbdisable" = 1, "blindmutedeaf" = 1, "longstun" = 1, "sleep" = 1, "inducetrauma" = 1, "amplifycorrupt" = 1, "changetemp" = 1)
|
||||
var/event = pickweight(whatmighthappen)
|
||||
@@ -97,8 +97,10 @@
|
||||
if("vomit")
|
||||
to_chat(src, "<span class='notice'>Ejecting contaminant.</span>")
|
||||
vomit()
|
||||
if("halluscinate")
|
||||
if("hallucinate")
|
||||
hallucination += 20 //Doesn't give a cue
|
||||
if("jamcoolanthud")
|
||||
hud_used.coolant_display.jam(10)
|
||||
if("receporgandamage")
|
||||
adjustOrganLoss(ORGAN_SLOT_EARS, rand(10, 20))
|
||||
adjustOrganLoss(ORGAN_SLOT_EYES, rand(10, 20))
|
||||
@@ -159,7 +161,7 @@
|
||||
|
||||
/mob/living/carbon/proc/forcesleep(time = 100)
|
||||
to_chat(src, "<span class='notice'>Preparations complete, powering down.</span>")
|
||||
Sleeping(time, 0)
|
||||
Sleeping(time)
|
||||
|
||||
|
||||
#undef CORRUPTION_CHECK_INTERVAL
|
||||
|
||||
@@ -249,16 +249,17 @@
|
||||
if(DISGUST_LEVEL_DISGUSTED to INFINITY)
|
||||
msg += "[t_He] look[p_s()] extremely disgusted.\n"
|
||||
|
||||
var/apparent_blood_volume = blood_volume
|
||||
if(dna.species.use_skintones && skin_tone == "albino")
|
||||
apparent_blood_volume -= 150 // enough to knock you down one tier
|
||||
switch(apparent_blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
msg += "<b>[t_He] look[p_s()] like pale death.</b>\n"
|
||||
if(-INFINITY to BLOOD_VOLUME_BAD)
|
||||
msg += "<span class='deadsay'><b>[t_He] resemble[p_s()] a crushed, empty juice pouch.</b></span>\n"
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
var/apparent_blood_volume = blood_volume
|
||||
if(dna.species.use_skintones && skin_tone == "albino")
|
||||
apparent_blood_volume -= 150 // enough to knock you down one tier
|
||||
switch(apparent_blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
msg += "<b>[t_He] look[p_s()] like pale death.</b>\n"
|
||||
if(-INFINITY to BLOOD_VOLUME_BAD)
|
||||
msg += "<span class='deadsay'><b>[t_He] resemble[p_s()] a crushed, empty juice pouch.</b></span>\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text")
|
||||
AddElement(/datum/element/flavor_text/carbon/temporary, "", "Set Pose (Temporary Flavor Text)", "This should be used only for things pertaining to the current round!", _save_key = null)
|
||||
AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_human_items, /mob/living/carbon/human/.proc/should_strip)
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
@@ -110,106 +111,6 @@
|
||||
var/datum/disease/D = thing
|
||||
. += "* [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>"
|
||||
if(wear_suit)
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
|
||||
var/hardsuit_head = head && istype(head, /obj/item/clothing/head/helmet/space/hardsuit)
|
||||
dat += " <A href='?src=[REF(src)];toggle_helmet=[SLOT_WEAR_SUIT]'>[hardsuit_head ? "Retract Helmet" : "Extend Helmet"]</A>"
|
||||
dat += "</td></tr>"
|
||||
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>"
|
||||
if(shoes && shoes.can_be_tied && shoes.tied != SHOES_KNOTTED)
|
||||
dat += " <A href='?src=[REF(src)];shoes=[SLOT_SHOES]'>[shoes.tied ? "Untie shoes" : "Knot shoes"]</A>"
|
||||
|
||||
dat += "</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>"
|
||||
|
||||
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)
|
||||
@@ -231,83 +132,6 @@
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
|
||||
return
|
||||
if(href_list["toggle_helmet"])
|
||||
if(!istype(head, /obj/item/clothing/head/helmet/space/hardsuit))
|
||||
return
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = head
|
||||
visible_message("<span class='danger'>[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You try to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>")
|
||||
if(!do_mob(usr, src, hardsuit_head ? head.strip_delay : POCKET_STRIP_DELAY))
|
||||
return
|
||||
if(!istype(wear_suit, /obj/item/clothing/suit/space/hardsuit) || (hardsuit_head ? (!head || head != hardsuit_head) : head))
|
||||
return
|
||||
var/obj/item/clothing/suit/space/hardsuit/hardsuit = wear_suit //This should be an hardsuit given all our checks
|
||||
if(hardsuit.ToggleHelmet(FALSE))
|
||||
visible_message("<span class='danger'>[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet</span>", \
|
||||
"<span class='userdanger'>[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>")
|
||||
return
|
||||
if(href_list["item"])
|
||||
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"])
|
||||
var/strip_mod = 1
|
||||
var/strip_silence = FALSE
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G))
|
||||
strip_mod = G.strip_mod
|
||||
strip_silence = G.strip_silence
|
||||
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(HAS_TRAIT(pocket_item, TRAIT_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, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too)
|
||||
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)
|
||||
if(!usr.can_hold_items() || !usr.put_in_hands(pocket_item))
|
||||
pocket_item.forceMove(drop_location())
|
||||
log_combat(usr, src, "pickpocketed of item: [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)
|
||||
log_combat(usr, src, "placed item [place_item] onto")
|
||||
//do nothing otherwise
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
if(!strip_silence)
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
log_combat(usr, src, "failed to [pocket_item ? "pickpocket item [pocket_item] from" : "place item [place_item] onto "]")
|
||||
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE))
|
||||
// separate from first canusetopic
|
||||
var/mob/living/user = usr
|
||||
if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser
|
||||
shoes.handle_tying(usr)
|
||||
|
||||
..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined
|
||||
|
||||
|
||||
///////HUDs///////
|
||||
if(href_list["hud"])
|
||||
|
||||
@@ -319,7 +319,10 @@
|
||||
var/atom/A = I
|
||||
if(!QDELETED(A))
|
||||
A.ex_act(severity)
|
||||
gib()
|
||||
if(istype(origin, /datum/explosion))
|
||||
gib(was_explosion = origin)
|
||||
else
|
||||
gib()
|
||||
return
|
||||
else
|
||||
brute_loss = 500
|
||||
@@ -413,6 +416,7 @@
|
||||
severity *= 0.5
|
||||
var/do_not_stun = FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
hud_used?.coolant_display.jam(round(severity / 10, 1)) //Messes up the cooling system readout.
|
||||
severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act)
|
||||
do_not_stun = TRUE
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
|
||||
@@ -115,13 +115,13 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_NOGUNS))
|
||||
to_chat(src, "<span class='warning'>You can't bring yourself to use a ranged weapon!</span>")
|
||||
return FALSE
|
||||
if(G.trigger_guard == TRIGGER_GUARD_NORMAL)
|
||||
if(HAS_TRAIT(src, TRAIT_CHUNKYFINGERS))
|
||||
to_chat(src, "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>")
|
||||
balloon_alert(src, "fingers are too big!")
|
||||
return FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_NOGUNS))
|
||||
to_chat(src, span_warning("You can't bring yourself to use a ranged weapon!"))
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/get_bank_account()
|
||||
RETURN_TYPE(/datum/bank_account)
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
#define INTERNALS_TOGGLE_DELAY (4 SECONDS)
|
||||
#define POCKET_EQUIP_DELAY (1 SECONDS)
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list(
|
||||
/datum/strippable_item/mob_item_slot/head,
|
||||
/datum/strippable_item/mob_item_slot/back,
|
||||
/datum/strippable_item/mob_item_slot/mask,
|
||||
/datum/strippable_item/mob_item_slot/neck,
|
||||
/datum/strippable_item/mob_item_slot/eyes,
|
||||
/datum/strippable_item/mob_item_slot/ears,
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit,
|
||||
/datum/strippable_item/mob_item_slot/suit,
|
||||
/datum/strippable_item/mob_item_slot/gloves,
|
||||
/datum/strippable_item/mob_item_slot/feet,
|
||||
/datum/strippable_item/mob_item_slot/suit_storage,
|
||||
/datum/strippable_item/mob_item_slot/id,
|
||||
/datum/strippable_item/mob_item_slot/belt,
|
||||
/datum/strippable_item/mob_item_slot/pocket/left,
|
||||
/datum/strippable_item/mob_item_slot/pocket/right,
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
/mob/living/carbon/human/proc/should_strip(mob/user)
|
||||
if (user.pulling != src || user.grab_state != GRAB_AGGRESSIVE)
|
||||
return TRUE
|
||||
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
return !human_user.can_be_firemanned(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/eyes
|
||||
key = STRIPPABLE_ITEM_EYES
|
||||
item_slot = SLOT_GLASSES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/ears
|
||||
key = STRIPPABLE_ITEM_EARS
|
||||
item_slot = SLOT_EARS
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit
|
||||
key = STRIPPABLE_ITEM_JUMPSUIT
|
||||
item_slot = SLOT_W_UNIFORM
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if (!istype(jumpsuit))
|
||||
return null
|
||||
return jumpsuit?.can_adjust ? "adjust_jumpsuit" : null
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if (!istype(jumpsuit))
|
||||
return null
|
||||
to_chat(source, "<span class='notice'>[user] is trying to adjust your [jumpsuit.name].")
|
||||
if (!do_mob(user, source, jumpsuit.strip_delay * 0.5, ignorehelditem = TRUE))
|
||||
return
|
||||
to_chat(source, "<span class='notice'>[user] successfully adjusted your [jumpsuit.name].")
|
||||
jumpsuit.toggle_jumpsuit_adjust()
|
||||
|
||||
if (!ismob(source))
|
||||
return null
|
||||
|
||||
var/mob/mob_source = source
|
||||
mob_source.update_inv_w_uniform()
|
||||
mob_source.update_body()
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit
|
||||
key = STRIPPABLE_ITEM_SUIT
|
||||
item_slot = SLOT_WEAR_SUIT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/suit/space/hardsuit/suit = get_item(source)
|
||||
if(istype(suit))
|
||||
if(!suit.helmettype)
|
||||
return null
|
||||
return suit?.suittoggled ? "disable_helmet" : "enable_helmet"
|
||||
return null
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit/alternate_action(mob/living/carbon/human/source, mob/user)
|
||||
if(!..())
|
||||
return null
|
||||
if(ishuman(source))
|
||||
var/obj/item/clothing/suit/space/hardsuit/hardsuit = get_item(source)
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = hardsuit.helmet
|
||||
source.visible_message("<span class='danger'>[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>", \
|
||||
"<span class='userdanger'>[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>", \
|
||||
target = user, target_message = "<span class='danger'>You try to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>")
|
||||
if(!do_mob(user, source, hardsuit_head ? hardsuit_head.strip_delay : POCKET_STRIP_DELAY, ignorehelditem = TRUE))
|
||||
return null
|
||||
if((source.head != hardsuit_head) && source.head)
|
||||
return null
|
||||
if(hardsuit.ToggleHelmet(FALSE))
|
||||
source.visible_message("<span class='danger'>[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet</span>", \
|
||||
"<span class='userdanger'>[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet</span>", \
|
||||
target = user, target_message = "<span class='danger'>You [hardsuit_head ? "retract" : "extend"] [source]'s helmet.</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/gloves
|
||||
key = STRIPPABLE_ITEM_GLOVES
|
||||
item_slot = SLOT_GLOVES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet
|
||||
key = STRIPPABLE_ITEM_FEET
|
||||
item_slot = SLOT_SHOES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/shoes/shoes = get_item(source)
|
||||
if (!istype(shoes) || !shoes.can_be_tied)
|
||||
return null
|
||||
|
||||
switch (shoes.tied)
|
||||
if (SHOES_UNTIED)
|
||||
return "knot"
|
||||
if (SHOES_TIED)
|
||||
return "untie"
|
||||
if (SHOES_KNOTTED)
|
||||
return "unknot"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet/alternate_action(atom/source, mob/user)
|
||||
if(!..())
|
||||
return null
|
||||
var/obj/item/clothing/shoes/shoes = get_item(source)
|
||||
if (!istype(shoes))
|
||||
return null
|
||||
|
||||
shoes.handle_tying(user)
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage
|
||||
key = STRIPPABLE_ITEM_SUIT_STORAGE
|
||||
item_slot = SLOT_S_STORE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/id
|
||||
key = STRIPPABLE_ITEM_ID
|
||||
item_slot = SLOT_WEAR_ID
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt
|
||||
key = STRIPPABLE_ITEM_BELT
|
||||
item_slot = SLOT_BELT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket
|
||||
/// Which pocket we're referencing. Used for visible text.
|
||||
var/pocket_side
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_obscuring(atom/source)
|
||||
return isnull(get_item(source)) \
|
||||
? STRIPPABLE_OBSCURING_NONE \
|
||||
: STRIPPABLE_OBSCURING_HIDDEN
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_equip_delay(obj/item/equipping)
|
||||
return POCKET_EQUIP_DELAY
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
warn_owner(source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_unequip(atom/source, mob/user)
|
||||
var/obj/item/item = get_item(source)
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
to_chat(user, span_notice("You try to empty [source]'s [pocket_side] pocket."))
|
||||
|
||||
var/log_message = "[key_name(source)] is being pickpocketed of [item] by [key_name(user)] ([pocket_side])"
|
||||
user.log_message(log_message, LOG_ATTACK, color="red")
|
||||
source.log_message(log_message, LOG_VICTIM, color="red", log_globally=FALSE)
|
||||
item.add_fingerprint(source)
|
||||
|
||||
var/result = start_unequip_mob(item, source, user, POCKET_STRIP_DELAY)
|
||||
|
||||
if (!result)
|
||||
warn_owner(source)
|
||||
|
||||
return result
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/proc/warn_owner(atom/owner)
|
||||
to_chat(owner, span_warning("You feel your [pocket_side] pocket being fumbled with!"))
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/left
|
||||
key = STRIPPABLE_ITEM_LPOCKET
|
||||
item_slot = SLOT_L_STORE
|
||||
pocket_side = "left"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/right
|
||||
key = STRIPPABLE_ITEM_RPOCKET
|
||||
item_slot = SLOT_R_STORE
|
||||
pocket_side = "right"
|
||||
|
||||
/proc/get_strippable_alternate_action_internals(obj/item/item, atom/source)
|
||||
if (!iscarbon(source))
|
||||
return null
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
var/obj/item/clothing/mask
|
||||
var/internals = FALSE
|
||||
|
||||
for(mask in GET_INTERNAL_SLOTS(carbon_source))
|
||||
if(istype(mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = mask
|
||||
if(M.mask_adjusted)
|
||||
if(M.adjustmask(carbon_source))
|
||||
internals = TRUE
|
||||
else
|
||||
internals = TRUE
|
||||
if((mask.clothing_flags & ALLOWINTERNALS))
|
||||
internals = TRUE
|
||||
|
||||
if(carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
internals = TRUE
|
||||
|
||||
if (internals && istype(item, /obj/item/tank))
|
||||
return isnull(carbon_source.internal) ? "enable_internals" : "disable_internals"
|
||||
|
||||
/proc/strippable_alternate_action_internals(obj/item/item, atom/source, mob/user)
|
||||
var/obj/item/tank/tank = item
|
||||
if (!istype(tank))
|
||||
return null
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
if (!istype(carbon_source))
|
||||
return null
|
||||
|
||||
var/obj/item/clothing/mask
|
||||
var/internals = FALSE
|
||||
|
||||
for(mask in GET_INTERNAL_SLOTS(carbon_source))
|
||||
if(istype(mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = mask
|
||||
if(M.mask_adjusted)
|
||||
if(M.adjustmask(carbon_source))
|
||||
internals = TRUE
|
||||
else
|
||||
internals = TRUE
|
||||
if((mask.clothing_flags & ALLOWINTERNALS))
|
||||
internals = TRUE
|
||||
|
||||
if(!internals)
|
||||
return null
|
||||
|
||||
carbon_source.visible_message(
|
||||
span_danger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, span_notice("You try to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]..."))
|
||||
|
||||
if(!do_mob(user, carbon_source, INTERNALS_TOGGLE_DELAY, ignorehelditem = TRUE))
|
||||
return null
|
||||
|
||||
if(carbon_source.internal)
|
||||
carbon_source.internal = null
|
||||
|
||||
// This isn't meant to be FALSE, it correlates to the icon's name.
|
||||
carbon_source.update_internals_hud_icon(0)
|
||||
else if (!QDELETED(item))
|
||||
if(internals || carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
carbon_source.internal = item
|
||||
carbon_source.update_internals_hud_icon(1)
|
||||
|
||||
carbon_source.visible_message(
|
||||
span_danger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name]."),
|
||||
span_userdanger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, span_notice("You [isnull(carbon_source.internal) ? "close" : "open"] the valve on [source]'s [item.name]."))
|
||||
|
||||
return TRUE
|
||||
|
||||
#undef INTERNALS_TOGGLE_DELAY
|
||||
#undef POCKET_EQUIP_DELAY
|
||||
@@ -209,7 +209,7 @@
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
if(HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
||||
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1)
|
||||
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/scaled/impaired, 1)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
|
||||
update_sight()
|
||||
if(!QDELETED(src))
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
/mob/living/carbon/human/PhysicalLife(seconds, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM) && hud_used)
|
||||
hud_used.coolant_display.update_counter(src)
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
|
||||
@@ -76,9 +78,23 @@
|
||||
|
||||
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
|
||||
|
||||
var/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(breath && HAS_TRAIT(src, TRAIT_NOBREATH) && HAS_TRAIT(src, TRAIT_AUXILIARY_LUNGS)) //Something something bz and synth cooling systems interacting (in reality, this only exists to not make robot lings too strong)
|
||||
var/total_moles = breath.total_moles()
|
||||
var/pressure = breath.return_pressure()
|
||||
#define PP_MOLES(X) ((X / total_moles) * pressure)
|
||||
#define PP(air, gas) PP_MOLES(air.get_moles(gas))
|
||||
var/bz_pp = PP(breath, GAS_BZ)
|
||||
if(bz_pp > 1)
|
||||
reagents.add_reagent(/datum/reagent/bz_metabolites,5)
|
||||
else if(bz_pp > 0.1)
|
||||
reagents.add_reagent(/datum/reagent/bz_metabolites,1)
|
||||
#undef PP_MOLES
|
||||
#undef PP
|
||||
|
||||
var/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(!L)
|
||||
if(HAS_TRAIT(src, TRAIT_NOBREATH))
|
||||
return
|
||||
if(health >= crit_threshold)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
|
||||
else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
|
||||
|
||||
@@ -108,6 +108,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/burnmod = 1
|
||||
///multiplier for damage from cold temperature
|
||||
var/coldmod = 1
|
||||
///moves their safe minimum temp by this value.
|
||||
var/cold_offset = 0
|
||||
///moves their safe maximum temp by this value.
|
||||
var/hot_offset = 0
|
||||
///multiplier for damage from hot temperature
|
||||
var/heatmod = 1
|
||||
///multiplier for stun durations
|
||||
@@ -147,6 +151,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/list/blacklisted_quirks = list() // Quirks that will be removed upon gaining this species, to be defined by species
|
||||
var/list/removed_quirks = list() // Quirks that got removed due to being blacklisted, and will be restored when on_species_loss() is called
|
||||
var/balance_point_values = FALSE //If true, will balance point values on species gain after removing blacklisted quirks. Use this for roundstart species with blacklisted quirks that people may attempt to use to powergame trait points.
|
||||
|
||||
///Punch-specific attack verb.
|
||||
var/attack_verb = "punch"
|
||||
@@ -331,7 +336,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/should_have_brain = TRUE
|
||||
var/should_have_heart = !(NOBLOOD in species_traits)
|
||||
var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits)
|
||||
var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits))
|
||||
var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
|
||||
var/should_have_eyes = TRUE
|
||||
var/should_have_ears = TRUE
|
||||
@@ -569,17 +574,39 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
for(var/obj/item/bodypart/B in C.bodyparts)
|
||||
B.change_bodypart_status(initial(B.status), FALSE, TRUE)
|
||||
|
||||
if((TRAIT_ROBOTIC_ORGANISM in inherent_traits) && C.hud_used)
|
||||
C.hud_used.coolant_display.clear()
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
|
||||
|
||||
// shamelessly inspired by antag_datum.remove_blacklisted_quirks()
|
||||
/datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C)
|
||||
var/mob/living/L = C.mind?.current
|
||||
if(istype(L))
|
||||
for(var/q in L.roundstart_quirks)
|
||||
var/datum/quirk/Q = q
|
||||
if(Q.type in blacklisted_quirks)
|
||||
qdel(Q)
|
||||
removed_quirks += Q.type
|
||||
. = 0
|
||||
if(istype(C))
|
||||
if(!balance_point_values)
|
||||
for(var/q in C.roundstart_quirks)
|
||||
var/datum/quirk/Q = q
|
||||
if(Q.type in blacklisted_quirks)
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
else
|
||||
var/point_overhead = 0
|
||||
for(var/datum/quirk/Q as anything in C.roundstart_quirks)
|
||||
if(Q.type in blacklisted_quirks)
|
||||
point_overhead -= Q.value
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
if(point_overhead)
|
||||
for(var/datum/quirk/Q as anything in C.roundstart_quirks)
|
||||
if(Q.value > 0)
|
||||
point_overhead -= Q.value
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
if(!point_overhead)
|
||||
break
|
||||
|
||||
// restore any quirks that we removed
|
||||
/datum/species/proc/restore_quirks(mob/living/carbon/C)
|
||||
@@ -1165,7 +1192,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)
|
||||
if((H.health < H.crit_threshold) && takes_crit_damage)
|
||||
H.adjustBruteLoss(1)
|
||||
if(!HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM))
|
||||
H.adjustBruteLoss(1)
|
||||
else
|
||||
H.adjustFireLoss(1) //Robots melt instead of taking brute.
|
||||
|
||||
/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -1874,7 +1904,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(!I.get_sharpness() && armor_block < 50)
|
||||
if(prob(I.force))
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM))
|
||||
H.adjustToxLoss(5, toxins_type = TOX_SYSCORRUPT) //Bonk! - Effectively 5 bonus damage
|
||||
else
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
@@ -2168,15 +2198,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
//Thermal protection (insulation) has mixed benefits in two situations (hot in hot places, cold in hot places)
|
||||
if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
|
||||
var/natural = 0
|
||||
var/cooling_efficiency = 1
|
||||
if(H.stat != DEAD)
|
||||
natural = H.natural_bodytemperature_stabilization()
|
||||
cooling_efficiency = H.get_cooling_efficiency()
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) //Synths by default slowly heat up and need to lose said heat to the environment or active cooling. If you have very high cooling efficiency, you instead passively cool.
|
||||
H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), (T0C + SYNTH_MIN_PASSIVE_COOLING_TEMP), (T0C + SYNTH_MAX_PASSIVE_GAIN_TEMP))
|
||||
var/thermal_protection = 1
|
||||
if(loc_temp < H.bodytemperature) //Place is colder than we are
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + max((thermal_protection * (loc_temp - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max(((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
|
||||
else //Place is hotter than we are
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment
|
||||
@@ -2190,9 +2225,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 2)
|
||||
if(-35 to -20)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 1)
|
||||
if(-20 to 0) //This is the sweet spot where air is considered normal
|
||||
if(-20 to 1) //This is the sweet spot where air is considered normal
|
||||
H.clear_alert("tempfeel")
|
||||
if(0 to 15) //When the air around you matches your body's temperature, you'll start to feel warm.
|
||||
if(1 to 15) //When the air around you matches your body's temperature, you'll start to feel warm.
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 1)
|
||||
if(15 to 30)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 2)
|
||||
@@ -2200,7 +2235,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 3)
|
||||
|
||||
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
|
||||
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
|
||||
if(H.bodytemperature > (BODYTEMP_HEAT_DAMAGE_LIMIT + hot_offset) && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
|
||||
//Body temperature is too hot.
|
||||
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
@@ -2228,11 +2263,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.emote("scream")
|
||||
H.apply_damage(burn_damage, BURN)
|
||||
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
else if(H.bodytemperature < (BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//Apply cold slowdown
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = (((BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/shiver, 1)
|
||||
|
||||
@@ -24,11 +24,18 @@
|
||||
id = SPECIES_MAMMAL_SYNTHETIC
|
||||
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE,WINGCOLOR,HORNCOLOR)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID|MOB_BEAST
|
||||
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
@@ -47,4 +54,7 @@
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
exotic_bloodtype = "S"
|
||||
exotic_blood_color = BLOOD_COLOR_OIL
|
||||
allowed_limb_ids = list("mammal","aquatic","avian", "human")
|
||||
species_category = "robot"
|
||||
|
||||
@@ -5,14 +5,20 @@
|
||||
default_color = "00FF00"
|
||||
blacklisted = 0
|
||||
sexes = 0
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE,HAIR,ROBOTIC_LIMBS)
|
||||
hair_alpha = 210
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
|
||||
mutant_bodyparts = list("ipc_screen" = "Blank", "deco_wings" = "None", "ipc_antenna" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
@@ -26,7 +32,7 @@
|
||||
//special cybernetic organ for getting power from apcs
|
||||
mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord)
|
||||
|
||||
exotic_bloodtype = "HF"
|
||||
exotic_bloodtype = "S"
|
||||
exotic_blood_color = BLOOD_COLOR_OIL
|
||||
species_category = SPECIES_CATEGORY_ROBOT
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,HAS_FLESH)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
say_mod = "beeps"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
//Procs called while dead
|
||||
/mob/living/carbon/proc/handle_death()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.chemical_flags & REAGENT_DEAD_PROCESS)
|
||||
if(R.chemical_flags & REAGENT_DEAD_PROCESS && !is_reagent_processing_invalid(R, src))
|
||||
R.on_mob_dead(src)
|
||||
|
||||
///////////////
|
||||
@@ -573,9 +573,6 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness-1,0)
|
||||
|
||||
if(silent)
|
||||
silent = max(silent-1, 0)
|
||||
|
||||
@@ -583,7 +580,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
handle_hallucinations()
|
||||
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness - (drunkenness * 0.04), 0)
|
||||
drunkenness *= 0.96
|
||||
if(drunkenness >= 6)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk)
|
||||
if(prob(25))
|
||||
@@ -598,6 +595,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk")
|
||||
clear_alert("drunk")
|
||||
sound_environment_override = SOUND_ENVIRONMENT_NONE
|
||||
drunkenness = max(drunkenness - 0.2, 0)
|
||||
|
||||
if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director"))
|
||||
if(SSresearch.science_tech)
|
||||
@@ -661,7 +659,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
|
||||
//used in human and monkey handle_environment()
|
||||
/mob/living/carbon/proc/natural_bodytemperature_stabilization()
|
||||
if (HAS_TRAIT(src, TRAIT_COLDBLOODED))
|
||||
if(HAS_TRAIT(src, TRAIT_COLDBLOODED) || HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 0 //Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this.
|
||||
|
||||
var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature
|
||||
@@ -674,6 +672,52 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
return min(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, max(body_temperature_difference, -BODYTEMP_AUTORECOVERY_MINIMUM/4))
|
||||
if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY)
|
||||
return min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
|
||||
|
||||
/mob/living/carbon/proc/get_cooling_efficiency()
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 1
|
||||
|
||||
var/integration_bonus = min(blood_volume * SYNTH_INTEGRATION_COOLANT_CAP, integrating_blood * SYNTH_INTEGRATION_COOLANT_PENALTY) //Integration blood somewhat helps, though only at 40% impact and to a cap of 25% of current blood level.
|
||||
var/blood_effective_volume = blood_volume + integration_bonus
|
||||
var/coolant_efficiency = min(blood_effective_volume / BLOOD_VOLUME_SAFE, 1) //Low coolant is only a negative, adding more than needed will not help you.
|
||||
var/environment_efficiency = get_environment_cooling_efficiency()
|
||||
|
||||
return min(coolant_efficiency * environment_efficiency, SYNTH_MAX_COOLING_EFFICIENCY)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/get_environment_cooling_efficiency()
|
||||
var/suitlink = check_suitlinking()
|
||||
if(suitlink)
|
||||
return suitlink //If you are wearing full EVA or lavaland hazard gear (on lavaland), assume it has been made to accomodate your cooling needs.
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if(!environment)
|
||||
return 0
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/heat = environment.return_temperature()
|
||||
|
||||
var/heat_efficiency = clamp(1 + ((bodytemperature - heat) * SYNTH_HEAT_EFFICIENCY_COEFF), 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
var/pressure_efficiency = clamp(pressure / ONE_ATMOSPHERE, 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_LOWPRESSURECOOLING))
|
||||
pressure_efficiency = max(pressure_efficiency, 1) //Space adaptation nulls drawbacks of low-pressure cooling.
|
||||
|
||||
var/total_environment_efficiency = min(heat_efficiency * pressure_efficiency, SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP) //At best, you can get 200% total
|
||||
return total_environment_efficiency
|
||||
|
||||
/mob/living/carbon/proc/check_suitlinking()
|
||||
var/suit_item = get_item_by_slot(SLOT_WEAR_SUIT)
|
||||
var/head_item = get_item_by_slot(SLOT_HEAD)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space))
|
||||
return 1
|
||||
|
||||
if(T && is_mining_level(T.z) && istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/////////
|
||||
//LIVER//
|
||||
/////////
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
hud_type = /datum/hud/monkey
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_monkey_items, create_strippable_list(list(
|
||||
/datum/strippable_item/mob_item_slot/head,
|
||||
/datum/strippable_item/mob_item_slot/back,
|
||||
/datum/strippable_item/mob_item_slot/mask,
|
||||
/datum/strippable_item/mob_item_slot/neck,
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner)
|
||||
add_verb(src, /mob/living/proc/mob_sleep)
|
||||
add_verb(src, /mob/living/proc/lay_down)
|
||||
@@ -47,6 +58,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD)
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, 2)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_monkey_items)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Destroy()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/mob/living/carbon/adjust_drugginess(amount)
|
||||
druggy = max(druggy+amount, 0)
|
||||
if(druggy)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/high)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/tiled/high)
|
||||
throw_alert("high", /atom/movable/screen/alert/high)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "high", /datum/mood_event/high)
|
||||
sound_environment_override = SOUND_ENVIRONMENT_DRUGGED
|
||||
@@ -18,7 +18,7 @@
|
||||
/mob/living/carbon/set_drugginess(amount)
|
||||
druggy = max(amount, 0)
|
||||
if(druggy)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/high)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/tiled/high)
|
||||
throw_alert("high", /atom/movable/screen/alert/high)
|
||||
else
|
||||
clear_fullscreen("high")
|
||||
|
||||
Reference in New Issue
Block a user