Merge branch 'master' into deadmin-prefs

This commit is contained in:
SandPoot
2022-03-22 15:35:46 -03:00
committed by GitHub
1559 changed files with 287712 additions and 68795 deletions
+67 -67
View File
@@ -65,29 +65,30 @@
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
var/blood_effect_volume = blood_volume + integrating_blood
switch(blood_effect_volume)
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
if(prob(10))
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(5))
to_chat(src, "<span class='warning'>You feel [word].</span>")
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
if(prob(5))
blur_eyes(6)
to_chat(src, "<span class='warning'>You feel very [word].</span>")
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
adjustOxyLoss(5)
if(prob(15))
Unconscious(rand(20,60))
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
if(!HAS_TRAIT(src, TRAIT_NODEATH))
death()
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
var/word = pick("dizzy","woozy","faint")
var/blood_effect_volume = blood_volume + integrating_blood
switch(blood_effect_volume)
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
if(prob(10))
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(5))
to_chat(src, "<span class='warning'>You feel [word].</span>")
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
if(prob(5))
blur_eyes(6)
to_chat(src, "<span class='warning'>You feel very [word].</span>")
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
adjustOxyLoss(5)
if(prob(15))
Unconscious(rand(20,60))
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
if(!HAS_TRAIT(src, TRAIT_NODEATH))
death()
var/temp_bleed = 0
//Bleeding out
@@ -156,7 +157,7 @@
blood_volume -= amount
var/list/blood_data = get_blood_data(blood_id)
var/list/blood_data = get_blood_data()
if(iscarbon(AM))
var/mob/living/carbon/C = AM
@@ -177,54 +178,53 @@
return TRUE
/mob/living/proc/get_blood_data(blood_id)
/mob/living/proc/get_blood_data()
return
/mob/living/carbon/get_blood_data(blood_id)
if(blood_id == /datum/reagent/blood || /datum/reagent/blood/jellyblood) //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
blood_data["viruses"] = list()
/mob/living/carbon/get_blood_data()
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
blood_data["viruses"] = list()
for(var/thing in diseases)
var/datum/disease/D = thing
blood_data["viruses"] += D.Copy()
for(var/thing in diseases)
var/datum/disease/D = thing
blood_data["viruses"] += D.Copy()
blood_data["blood_DNA"] = dna.unique_enzymes
blood_data["bloodcolor"] = dna.species.exotic_blood_color
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
for(var/datum/reagent/R in reagents.reagent_list)
temp_chem[R.type] = R.volume
blood_data["trace_chem"] = list2params(temp_chem)
if(mind)
blood_data["mind"] = mind
else if(last_mind)
blood_data["mind"] = last_mind
if(ckey)
blood_data["ckey"] = ckey
else if(last_mind)
blood_data["ckey"] = ckey(last_mind.key)
blood_data["blood_DNA"] = dna.unique_enzymes
blood_data["bloodcolor"] = dna.species.exotic_blood_color
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
for(var/datum/reagent/R in reagents.reagent_list)
temp_chem[R.type] = R.volume
blood_data["trace_chem"] = list2params(temp_chem)
if(mind)
blood_data["mind"] = mind
else if(last_mind)
blood_data["mind"] = last_mind
if(ckey)
blood_data["ckey"] = ckey
else if(last_mind)
blood_data["ckey"] = ckey(last_mind.key)
if(!suiciding)
blood_data["cloneable"] = 1
blood_data["blood_type"] = dna.blood_type
blood_data["gender"] = gender
blood_data["real_name"] = real_name
blood_data["features"] = dna.features
blood_data["factions"] = faction
blood_data["quirks"] = list()
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
blood_data["quirks"] += T.type
blood_data["changeling_loudness"] = 0
if(mind)
var/datum/antagonist/changeling/ling = mind.has_antag_datum(/datum/antagonist/changeling)
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
if(!suiciding)
blood_data["cloneable"] = 1
blood_data["blood_type"] = dna.blood_type
blood_data["gender"] = gender
blood_data["real_name"] = real_name
blood_data["features"] = dna.features
blood_data["factions"] = faction
blood_data["quirks"] = list()
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
blood_data["quirks"] += T.type
blood_data["changeling_loudness"] = 0
if(mind)
var/datum/antagonist/changeling/ling = mind.has_antag_datum(/datum/antagonist/changeling)
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
//get the id of the substance this mob use as blood.
/mob/proc/get_blood_id()
+1 -1
View File
@@ -11,7 +11,7 @@
/obj/effect/dummy/phased_mob/slaughter/relaymove(mob/user, direction)
forceMove(get_step(src,direction))
/obj/effect/dummy/phased_mob/slaughter/ex_act()
/obj/effect/dummy/phased_mob/slaughter/ex_act(severity, target, origin)
return
/obj/effect/dummy/phased_mob/slaughter/wave_ex_act(power, datum/wave_explosion/explosion, dir)
+1 -1
View File
@@ -43,7 +43,7 @@
/mob/living/brain/update_mobility()
return ((mobility_flags = (container?.in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE)))
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
/mob/living/brain/ex_act(severity, target, origin) //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
return
/mob/living/brain/wave_ex_act(power, datum/wave_explosion/explosion, dir)
@@ -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
@@ -172,7 +172,7 @@
if(target.dropItemToGround(W))
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
target.equip_to_slot_if_possible(src, SLOT_WEAR_MASK, 0, 1, 1)
target.equip_to_slot_if_possible(src, ITEM_SLOT_MASK, 0, 1, 1)
return TRUE // time for a smoke
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
@@ -259,7 +259,7 @@
return 1
var/mob/living/carbon/C = M
if(ishuman(C) && !(SLOT_WEAR_MASK in C.dna.species.no_equip))
if(ishuman(C) && !(ITEM_SLOT_MASK in C.dna.species.no_equip))
var/mob/living/carbon/human/H = C
if(H.is_mouth_covered(head_only = 1))
return FALSE
+14 -67
View File
@@ -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)
@@ -314,7 +261,7 @@
// too soon.
var/buckle_cd = 600
if(handcuffed)
var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED)
var/obj/item/restraints/O = src.get_item_by_slot(ITEM_SLOT_HANDCUFFED)
buckle_cd = O.breakouttime
MarkResistTime()
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
@@ -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")
@@ -898,16 +845,16 @@
update_inv_handcuffed()
update_hud_handcuffed()
/mob/living/carbon/proc/can_defib()
/mob/living/carbon/proc/can_revive(ignore_timelimit = FALSE, maximum_brute_dam = MAX_REVIVE_BRUTE_DAMAGE, maximum_fire_dam = MAX_REVIVE_FIRE_DAMAGE, ignore_heart = FALSE)
var/tlimit = DEFIB_TIME_LIMIT * 10
var/obj/item/organ/heart = getorgan(/obj/item/organ/heart)
if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK) || AmBloodsucker(src))
return
if((world.time - timeofdeath) > tlimit)
if(!ignore_timelimit && (world.time - timeofdeath) > tlimit)
return
if((getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
if((getBruteLoss() >= maximum_brute_dam) || (getFireLoss() >= maximum_fire_dam))
return
if(!heart || (heart.organ_flags & ORGAN_FAILING))
if(!ignore_heart && (!heart || (heart.organ_flags & ORGAN_FAILING)))
return
var/obj/item/organ/brain/BR = getorgan(/obj/item/organ/brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || suiciding)
@@ -1190,15 +1137,15 @@
/mob/living/carbon/check_obscured_slots()
if(head)
if(head.flags_inv & HIDEMASK)
LAZYOR(., SLOT_WEAR_MASK)
LAZYOR(., ITEM_SLOT_MASK)
if(head.flags_inv & HIDEEYES)
LAZYOR(., SLOT_GLASSES)
LAZYOR(., ITEM_SLOT_EYES)
if(head.flags_inv & HIDEEARS)
LAZYOR(., SLOT_EARS)
LAZYOR(., ITEM_SLOT_EARS)
if(wear_mask)
if(wear_mask.flags_inv & HIDEEYES)
LAZYOR(., SLOT_GLASSES)
LAZYOR(., ITEM_SLOT_EYES)
// if any of our bodyparts are bleeding
/mob/living/carbon/proc/is_bleeding()
@@ -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 = ITEM_SLOT_HEAD
/datum/strippable_item/mob_item_slot/back
key = STRIPPABLE_ITEM_BACK
item_slot = ITEM_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 = ITEM_SLOT_MASK
/datum/strippable_item/mob_item_slot/neck
key = STRIPPABLE_ITEM_NECK
item_slot = ITEM_SLOT_NECK
/datum/strippable_item/mob_item_slot/handcuffs
key = STRIPPABLE_ITEM_HANDCUFFS
item_slot = ITEM_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 = ITEM_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
@@ -1,3 +1,4 @@
GLOBAL_LIST_EMPTY(dead_players_during_shift)
/mob/living/carbon/human/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-h")
@@ -39,7 +40,9 @@
dizziness = 0
jitteriness = 0
if(client && !suiciding && !(client in GLOB.dead_players_during_shift))
GLOB.dead_players_during_shift += client
GLOB.deaths_during_shift++
if(ismecha(loc))
var/obj/mecha/M = loc
if(M.occupant == src)
@@ -31,6 +31,27 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
randomize_human(src)
dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init.
/// Provides a dummy that is consistently bald, white, naked, etc.
/mob/living/carbon/human/dummy/consistent
/mob/living/carbon/human/dummy/consistent/setup_human_dna()
create_dna(src)
dna.initialize_dna(skip_index = TRUE)
dna.features["body_markings"] = "None"
dna.features["ears"] = "Cat"
dna.features["ethcolor"] = COLOR_WHITE
dna.features["frills"] = "None"
dna.features["horns"] = "None"
dna.features["mcolor"] = COLOR_LIME
dna.features["moth_antennae"] = "Plain"
dna.features["moth_markings"] = "None"
dna.features["moth_wings"] = "Plain"
dna.features["snout"] = "Round"
dna.features["spines"] = "None"
dna.features["tail_human"] = "Cat"
dna.features["tail_lizard"] = "Smooth"
//Inefficient pooling/caching way.
GLOBAL_LIST_EMPTY(human_dummy_list)
GLOBAL_LIST_EMPTY(dummy_mob_list)
+19 -18
View File
@@ -31,7 +31,7 @@
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>!"
//uniform
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
if(w_uniform && !(ITEM_SLOT_ICLOTHING in obscured))
//accessory
var/accessory_msg
if(istype(w_uniform, /obj/item/clothing/under))
@@ -47,7 +47,7 @@
if(wear_suit && !(wear_suit.obj_flags & EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)]."
//suit/armor storage
if(s_store && !(SLOT_S_STORE in obscured))
if(s_store && !(ITEM_SLOT_SUITSTORE in obscured))
. += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name]."
//back
if(back)
@@ -59,7 +59,7 @@
. += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))]."
//gloves
if(gloves && !(SLOT_GLOVES in obscured))
if(gloves && !(ITEM_SLOT_GLOVES in obscured))
. += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands."
else if(length(blood_DNA))
var/hand_number = get_num_arms(FALSE)
@@ -78,18 +78,18 @@
. += "[t_He] [t_has] [belt.get_examine_string(user)] about [t_his] waist."
//shoes
if(shoes && !(SLOT_SHOES in obscured))
if(shoes && !(ITEM_SLOT_FEET in obscured))
. += "[t_He] [t_is] wearing [shoes.get_examine_string(user)] on [t_his] feet."
//mask
if(wear_mask && !(SLOT_WEAR_MASK in obscured))
if(wear_mask && !(ITEM_SLOT_MASK in obscured))
. += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face."
if(wear_neck && !(SLOT_NECK in obscured))
if(wear_neck && !(ITEM_SLOT_NECK in obscured))
. += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck."
//eyes
if(!(SLOT_GLASSES in obscured))
if(!(ITEM_SLOT_EYES in obscured))
if(glasses)
. += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes."
else if((left_eye_color == BLOODCULT_EYE || right_eye_color == BLOODCULT_EYE) && iscultist(src) && HAS_TRAIT(src, TRAIT_CULT_EYES))
@@ -100,7 +100,7 @@
. += "<b><font color=orange>[t_His] eyes are flickering a bright yellow!</font></b>"
//ears
if(ears && !(SLOT_EARS in obscured))
if(ears && !(ITEM_SLOT_EARS in obscured))
. += "[t_He] [t_has] [ears.get_examine_string(user)] on [t_his] ears."
//ID
@@ -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
+7 -183
View File
@@ -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>&nbsp;</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 += "&nbsp;<A href='?src=[REF(src)];internal=[SLOT_BACK]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr><tr><td>&nbsp;</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>&nbsp;</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 += "&nbsp;<A href='?src=[REF(src)];toggle_helmet=[SLOT_WEAR_SUIT]'>[hardsuit_head ? "Retract Helmet" : "Extend Helmet"]</A>"
dat += "</td></tr>"
dat += "<tr><td>&nbsp;&#8627;<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 += "&nbsp;<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>&nbsp;&#8627;<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 += "&nbsp;<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>&nbsp;&#8627;<B>Pockets:</B></font></td></tr>"
dat += "<tr><td><font color=grey>&nbsp;&#8627;<B>ID:</B></font></td></tr>"
dat += "<tr><td><font color=grey>&nbsp;&#8627;<B>Belt:</B></font></td></tr>"
else
dat += "<tr><td>&nbsp;&#8627;<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 += "&nbsp;<A href='?src=[REF(src)];internal=[SLOT_BELT]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr>"
dat += "<tr><td>&nbsp;&#8627;<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 += "&nbsp;<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>&nbsp;&#8627;<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"])
@@ -548,11 +372,11 @@
. = ..()
if(wear_suit)
if(wear_suit.flags_inv & HIDEGLOVES)
LAZYOR(., SLOT_GLOVES)
LAZYOR(., ITEM_SLOT_GLOVES)
if(wear_suit.flags_inv & HIDEJUMPSUIT)
LAZYOR(., SLOT_W_UNIFORM)
LAZYOR(., ITEM_SLOT_ICLOTHING)
if(wear_suit.flags_inv & HIDESHOES)
LAZYOR(., SLOT_SHOES)
LAZYOR(., ITEM_SLOT_FEET)
/mob/living/carbon/human/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
if(judgement_criteria & JUDGE_EMAGGED)
@@ -1118,15 +942,15 @@
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>"
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .)
/mob/living/carbon/human/chestonly
bodyparts = list(/obj/item/bodypart/chest)
/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
@@ -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 = ITEM_SLOT_EYES
/datum/strippable_item/mob_item_slot/ears
key = STRIPPABLE_ITEM_EARS
item_slot = ITEM_SLOT_EARS
/datum/strippable_item/mob_item_slot/jumpsuit
key = STRIPPABLE_ITEM_JUMPSUIT
item_slot = ITEM_SLOT_ICLOTHING
/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 = ITEM_SLOT_OCLOTHING
/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 = ITEM_SLOT_GLOVES
/datum/strippable_item/mob_item_slot/feet
key = STRIPPABLE_ITEM_FEET
item_slot = ITEM_SLOT_FEET
/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 = ITEM_SLOT_SUITSTORE
/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 = ITEM_SLOT_ID
/datum/strippable_item/mob_item_slot/belt
key = STRIPPABLE_ITEM_BELT
item_slot = ITEM_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 = ITEM_SLOT_LPOCKET
pocket_side = "left"
/datum/strippable_item/mob_item_slot/pocket/right
key = STRIPPABLE_ITEM_RPOCKET
item_slot = ITEM_SLOT_RPOCKET
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
@@ -0,0 +1,89 @@
/datum/action/innate/ability/coiling
name = "Coil Grabbed Mob"
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "coil_icon"
icon_icon = 'icons/mob/actions/actions_snake.dmi'
background_icon_state = "bg_alien"
required_mobility_flags = MOBILITY_STAND
var/currently_coiling = FALSE
var/mob/living/carbon/human/currently_coiled
var/mutable_appearance/tracked_overlay
/datum/action/innate/ability/coiling/Activate()
// make sure they meet the mobility/check flags
if(IsAvailable())
// check that the user has grabbed someone and they are not currently coiling someone
if(ishuman(owner.pulling) && !currently_coiling)
coil_mob(owner.pulling)
/datum/action/innate/ability/coiling/proc/update_coil_offset(atom/source, old_dir, new_dir)
// update the coiling offset on the coiled user depending on the way the owner is facing
switch(new_dir)
if(NORTH)
currently_coiled.pixel_x = -12
if(EAST)
currently_coiled.pixel_x = -12
if(SOUTH)
currently_coiled.pixel_x = 12
if(WEST)
currently_coiled.pixel_x = 12
/datum/action/innate/ability/coiling/proc/coil_mob(var/mob/living/carbon/human/H)
// begin the coiling action
H.visible_message("<span class='warning'>[owner] coils [H] with their tail!</span>", \
"<span class='userdanger'>[owner] coils you with their tail!</span>")
currently_coiling = TRUE
currently_coiled = H
H.layer -= 0.1 // LISTEN I HATE TOUCHING MOB LAYERS TOO BUT THIS IS JUST SO THEY RENDER UNDER THE OTHER PLAYER SDFHSDFHDSFHDSH
// move user to same tile
H.forceMove(get_turf(owner))
// cancel the coiling action if certain things are done
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/cancel_coil)
RegisterSignal(owner, COMSIG_LIVING_RESTING, .proc/cancel_coil)
RegisterSignal(owner, COMSIG_LIVING_STOPPED_PULLING, .proc/cancel_coil)
// update the coil offset, update again if owner changes direction
RegisterSignal(owner, COMSIG_ATOM_DIR_CHANGE, .proc/update_coil_offset)
update_coil_offset(null, null, owner.dir)
// set our overlay to new image
var/mob/living/carbon/human/user = owner
user.dna.species.mutant_bodyparts["taur"] = "Naga (coiled)"
user.dna.features["taur"] = "Naga (coiled)"
user.update_mutant_bodyparts()
/datum/action/innate/ability/coiling/proc/cancel_coil()
var/mob/living/carbon/human/H = owner
// cancel the coiling action by removing the overlay
currently_coiled.pixel_x = 0
currently_coiling = FALSE
currently_coiled = null
// unregister signals
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
UnregisterSignal(owner, COMSIG_LIVING_RESTING)
UnregisterSignal(owner, COMSIG_LIVING_STOPPED_PULLING)
UnregisterSignal(owner, COMSIG_ATOM_DIR_CHANGE)
// change overlay back to original image
H.dna.species.mutant_bodyparts["taur"] = "Naga"
H.dna.features["taur"] = "Naga"
H.update_mutant_bodyparts()
H.update_body()
H.layer += 0.1
// remove the added overlay
owner.cut_overlay(tracked_overlay)
tracked_overlay = null
/datum/action/innate/ability/coiling/Remove(mob/M)
cancel_coil()
..(M)
@@ -22,7 +22,7 @@
/datum/action/innate/ability/humanoid_customization/proc/change_form()
var/mob/living/carbon/human/H = owner
var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel")
var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color", "Eye Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel")
if(select_alteration == "Body Color")
var/new_color = input(owner, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null
@@ -34,6 +34,27 @@
H.update_hair()
else
to_chat(H, "<span class='notice'>Invalid color. Your color is not bright enough.</span>")
else if(select_alteration == "Eye Color")
if(iscultist(H) && HAS_TRAIT(H, TRAIT_CULT_EYES))
to_chat(H, "<span class='cultlarge'>\"I do not need you to hide yourself anymore, relish my gift.\"</span>")
return
var/heterochromia = input(owner, "Do you want to have heterochromia?", "Confirm Multicolors") in list("Yes", "No")
if(heterochromia == "Yes")
var/new_color1 = input(owner, "Choose your left eye color:", "Eye Color Change","#"+H.dna?.features["left_eye_color"]) as color|null
if(new_color1)
H.left_eye_color = sanitize_hexcolor(new_color1, 6)
var/new_color2 = input(owner, "Choose your right eye color:", "Eye Color Change","#"+H.dna?.features["right_eye_color"]) as color|null
if(new_color2)
H.right_eye_color = sanitize_hexcolor(new_color2, 6)
else
var/new_eyes = input(owner, "Choose your eye color:", "Character Preference","#"+H.dna?.features["left_eye_color"]) as color|null
if(new_eyes)
H.left_eye_color = sanitize_hexcolor(new_eyes, 6)
H.right_eye_color = sanitize_hexcolor(new_eyes, 6)
H.dna?.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK)
H.dna?.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK)
H.update_body()
else if(select_alteration == "Hair Style")
if(H.gender == MALE)
var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list
@@ -135,6 +156,8 @@
var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(S.ignore)
continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey)))
snowflake_taur_list[S.name] = path
var/new_taur
@@ -17,39 +17,39 @@
// Return the item currently in the slot ID
/mob/living/carbon/human/get_item_by_slot(slot_id)
switch(slot_id)
if(SLOT_BACK)
if(ITEM_SLOT_BACK)
return back
if(SLOT_WEAR_MASK)
if(ITEM_SLOT_MASK)
return wear_mask
if(SLOT_NECK)
if(ITEM_SLOT_NECK)
return wear_neck
if(SLOT_HANDCUFFED)
if(ITEM_SLOT_HANDCUFFED)
return handcuffed
if(SLOT_LEGCUFFED)
if(ITEM_SLOT_LEGCUFFED)
return legcuffed
if(SLOT_BELT)
if(ITEM_SLOT_BELT)
return belt
if(SLOT_WEAR_ID)
if(ITEM_SLOT_ID)
return wear_id
if(SLOT_EARS)
if(ITEM_SLOT_EARS)
return ears
if(SLOT_GLASSES)
if(ITEM_SLOT_EYES)
return glasses
if(SLOT_GLOVES)
if(ITEM_SLOT_GLOVES)
return gloves
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
return head
if(SLOT_SHOES)
if(ITEM_SLOT_FEET)
return shoes
if(SLOT_WEAR_SUIT)
if(ITEM_SLOT_OCLOTHING)
return wear_suit
if(SLOT_W_UNIFORM)
if(ITEM_SLOT_ICLOTHING)
return w_uniform
if(SLOT_L_STORE)
if(ITEM_SLOT_LPOCKET)
return l_store
if(SLOT_R_STORE)
if(ITEM_SLOT_RPOCKET)
return r_store
if(SLOT_S_STORE)
if(ITEM_SLOT_SUITSTORE)
return s_store
return null
@@ -98,17 +98,17 @@
var/not_handled = FALSE //Added in case we make this type path deeper one day
switch(slot)
if(SLOT_BELT)
if(ITEM_SLOT_BELT)
belt = I
update_inv_belt()
if(SLOT_WEAR_ID)
if(ITEM_SLOT_ID)
wear_id = I
sec_hud_set_ID()
update_inv_wear_id()
if(SLOT_EARS)
if(ITEM_SLOT_EARS)
ears = I
update_inv_ears()
if(SLOT_GLASSES)
if(ITEM_SLOT_EYES)
glasses = I
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
@@ -121,13 +121,13 @@
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
update_inv_glasses()
if(SLOT_GLOVES)
if(ITEM_SLOT_GLOVES)
gloves = I
update_inv_gloves()
if(SLOT_SHOES)
if(ITEM_SLOT_FEET)
shoes = I
update_inv_shoes()
if(SLOT_WEAR_SUIT)
if(ITEM_SLOT_OCLOTHING)
wear_suit = I
if(I.flags_inv & HIDEJUMPSUIT)
update_inv_w_uniform()
@@ -135,17 +135,17 @@
stop_pulling() //can't pull if restrained
update_action_buttons_icon() //certain action buttons will no longer be usable.
update_inv_wear_suit()
if(SLOT_W_UNIFORM)
if(ITEM_SLOT_ICLOTHING)
w_uniform = I
update_suit_sensors()
update_inv_w_uniform()
if(SLOT_L_STORE)
if(ITEM_SLOT_LPOCKET)
l_store = I
update_inv_pockets()
if(SLOT_R_STORE)
if(ITEM_SLOT_RPOCKET)
r_store = I
update_inv_pockets()
if(SLOT_S_STORE)
if(ITEM_SLOT_SUITSTORE)
s_store = I
update_inv_s_store()
else
@@ -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))
@@ -296,7 +296,7 @@
if(incapacitated())
return
var/obj/item/thing = get_active_held_item()
var/obj/item/equipped_back = get_item_by_slot(SLOT_BACK)
var/obj/item/equipped_back = get_item_by_slot(ITEM_SLOT_BACK)
if(!equipped_back) // We also let you equip a backpack like this
if(!thing)
to_chat(src, "<span class='warning'>You have no backpack to take something out of!</span>")
@@ -327,7 +327,7 @@
if(incapacitated())
return
var/obj/item/thing = get_active_held_item()
var/obj/item/equipped_belt = get_item_by_slot(SLOT_BELT)
var/obj/item/equipped_belt = get_item_by_slot(ITEM_SLOT_BELT)
if(!equipped_belt) // We also let you equip a belt like this
if(!thing)
to_chat(src, "<span class='warning'>You have no belt to take something out of!</span>")
+17 -1
View File
@@ -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))
+251 -48
View File
@@ -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
@@ -138,6 +142,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/// A path to an outfit that is important for species life e.g. plasmaman outfit
var/datum/outfit/outfit_important_for_life
///Is this species a flying species? Used as an easy check for some things
var/flying_species = FALSE
///The actual flying ability given to flying species
var/datum/action/innate/flight/fly
///Current wings icon
var/wings_icon = "Angel"
//Dictates which wing icons are allowed for a given species. If count is >1 a radial menu is used to choose between all icons in list
var/list/wings_icons = SPECIES_WINGS_ANGEL
///Species-only traits. Can be found in [code/__DEFINES/DNA.dm]
var/list/species_traits = list(HAS_FLESH,HAS_BONE) //by default they can scar and have bones/flesh unless set to something else
///Generic traits tied to having the species.
@@ -147,6 +160,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 +345,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
@@ -490,6 +504,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/datum/disease/A in C.diseases)
A.cure(FALSE)
if(flying_species && isnull(fly))
fly = new
fly.Grant(C)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(NOGENITALS in H.dna.species.species_traits)
@@ -564,22 +582,54 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(F)
qdel(F)
if(flying_species)
if(C.movement_type & FLYING)
ToggleFlight(C)
fly.Remove(C)
QDEL_NULL(fly)
if(C.dna && C.dna.species && (C.dna.features["wings"] == wings_icon))
if("wings" in C.dna.species.mutant_bodyparts)
C.dna.species.mutant_bodyparts -= "wings"
C.dna.features["wings"] = "None"
C.update_body()
if(ROBOTIC_LIMBS in species_traits)
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)
@@ -856,6 +906,22 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/tauric = mutant_bodyparts["taur"] && H.dna.features["taur"] && H.dna.features["taur"] != "None"
// stuff for adding/removing the coiling ability if you have a taur part
// if another action is ever based on mutant parts we should probably make a system for it so it's all done in one proc with less overhead
var/datum/action/found_action
for(var/datum/action/A in H.actions)
if(A.type == /datum/action/innate/ability/coiling)
found_action = A
if(found_action && (!tauric || (H.dna.features["taur"] != "Naga" && H.dna.features["taur"] != "Naga (coiled)")))
found_action.Remove(H)
if(!found_action && tauric && H.dna.features["taur"] == "Naga")
found_action = new /datum/action/innate/ability/coiling()
found_action.Grant(H)
for(var/mutant_part in mutant_bodyparts)
var/reference_list = GLOB.mutant_reference_list[mutant_part]
if(reference_list)
@@ -1159,13 +1225,18 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return move_trail */
/datum/species/proc/spec_life(mob/living/carbon/human/H)
if(flying_species) //turns off flight automatically if they can't.
HandleFlight(H)
if(HAS_TRAIT(H, TRAIT_NOBREATH))
H.setOxyLoss(0)
H.losebreath = 0
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)
@@ -1189,11 +1260,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/num_legs = H.get_num_legs(FALSE)
switch(slot)
if(SLOT_HANDS)
if(ITEM_SLOT_HANDS)
if(H.get_empty_held_indexes())
return TRUE
return FALSE
if(SLOT_WEAR_MASK)
if(ITEM_SLOT_MASK)
if(H.wear_mask)
return FALSE
if(!(I.slot_flags & ITEM_SLOT_MASK))
@@ -1201,25 +1272,25 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_NECK)
if(ITEM_SLOT_NECK)
if(H.wear_neck)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_NECK) )
return FALSE
return TRUE
if(SLOT_BACK)
if(ITEM_SLOT_BACK)
if(H.back)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_BACK) )
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_WEAR_SUIT)
if(ITEM_SLOT_OCLOTHING)
if(H.wear_suit)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_OCLOTHING) )
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_GLOVES)
if(ITEM_SLOT_GLOVES)
if(H.gloves)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_GLOVES) )
@@ -1227,7 +1298,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(num_arms < 2)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_SHOES)
if(ITEM_SLOT_FEET)
if(H.shoes)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_FEET) )
@@ -1240,7 +1311,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_BELT)
if(ITEM_SLOT_BELT)
if(H.belt)
return FALSE
if(!(I.item_flags & NO_UNIFORM_REQUIRED))
@@ -1252,7 +1323,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!(I.slot_flags & ITEM_SLOT_BELT))
return
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_GLASSES)
if(ITEM_SLOT_EYES)
if(H.glasses)
return FALSE
if(!(I.slot_flags & ITEM_SLOT_EYES))
@@ -1260,7 +1331,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
if(H.head)
return FALSE
if(!(I.slot_flags & ITEM_SLOT_HEAD))
@@ -1268,7 +1339,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_EARS)
if(ITEM_SLOT_EARS)
if(H.ears)
return FALSE
if(!(I.slot_flags & ITEM_SLOT_EARS))
@@ -1276,13 +1347,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_W_UNIFORM)
if(ITEM_SLOT_ICLOTHING)
if(H.w_uniform)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_ICLOTHING) )
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_WEAR_ID)
if(ITEM_SLOT_ID)
if(H.wear_id)
return FALSE
if(!(I.item_flags & NO_UNIFORM_REQUIRED))
@@ -1294,7 +1365,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if( !(I.slot_flags & ITEM_SLOT_ID) )
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_L_STORE)
if(ITEM_SLOT_LPOCKET)
if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them.
return FALSE
if(H.l_store)
@@ -1306,11 +1377,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(return_warning)
return_warning[1] = "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return FALSE
if(I.slot_flags & ITEM_SLOT_DENYPOCKET)
return FALSE
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) )
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKETS) )
return TRUE
if(SLOT_R_STORE)
if(ITEM_SLOT_RPOCKET)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
if(H.r_store)
@@ -1322,12 +1391,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(return_warning)
return_warning[1] = "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return FALSE
if(I.slot_flags & ITEM_SLOT_DENYPOCKET)
return FALSE
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) )
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKETS) )
return TRUE
return FALSE
if(SLOT_S_STORE)
if(ITEM_SLOT_SUITSTORE)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
if(H.s_store)
@@ -1347,7 +1414,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if( istype(I, /obj/item/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed) )
return TRUE
return FALSE
if(SLOT_HANDCUFFED)
if(ITEM_SLOT_HANDCUFFED)
if(H.handcuffed)
return FALSE
if(!istype(I, /obj/item/restraints/handcuffs))
@@ -1355,7 +1422,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(num_arms < 2)
return FALSE
return TRUE
if(SLOT_LEGCUFFED)
if(ITEM_SLOT_LEGCUFFED)
if(H.legcuffed)
return FALSE
if(!istype(I, /obj/item/restraints/legcuffs))
@@ -1363,7 +1430,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(num_legs < 2)
return FALSE
return TRUE
if(SLOT_IN_BACKPACK)
if(ITEM_SLOT_BACKPACK)
if(H.back)
if(SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_CAN_INSERT, I, H, TRUE))
return TRUE
@@ -1874,7 +1941,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)
@@ -1890,11 +1957,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma.
var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev)
var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang && !/datum/antagonist/gang/boss)
if(rev)
rev.remove_revolutionary(FALSE, user)
if(gang)
H.mind.remove_antag_datum(/datum/antagonist/gang)
if(bloody) //Apply blood
if(H.wear_mask)
@@ -2171,15 +2235,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
@@ -2193,9 +2262,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)
@@ -2203,7 +2272,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")
@@ -2231,11 +2300,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)
@@ -2356,10 +2425,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return
////////////
//Stun//
// Stun //
////////////
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
if(flying_species && H.movement_type & FLYING)
ToggleFlight(H,0)
flyslip(H)
if(H)
stop_wagging_tail(H)
. = stunmod * H.physiology.stun_mod * amount
@@ -2369,10 +2441,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//////////////
/datum/species/proc/space_move(mob/living/carbon/human/H)
return 0
if(H.movement_type & FLYING)
return TRUE
return FALSE
/datum/species/proc/negates_gravity(mob/living/carbon/human/H)
return 0
if(H.movement_type & FLYING)
return TRUE
return FALSE
////////////////
//Tail Wagging//
@@ -2406,3 +2482,130 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
mutant_bodyparts["spines"] = mutant_bodyparts["waggingspines"]
mutant_bodyparts -= "waggingspines"
H.update_body()
///////////////
//FLIGHT SHIT//
///////////////
/datum/species/proc/GiveSpeciesFlight(mob/living/carbon/human/H, all_wings = FALSE)
if(flying_species) //grant them the choice of all wings if they don't have them
all_wings = TRUE
flying_species = TRUE
//CITADEL CHANGE: check if they already have wings, and "evolve" them based off of the wings they have. If they have none, use their species wings basis.
var/list/wingslist
if(all_wings) //give them the full list of wing choices to pick from, typically if they drink a second flight potion
wingslist = SPECIES_WINGS_ALL
else
//why the fuck do we have two different wing types anyways? they're literally almost both using the same wing shit too.
var/datum/sprite_accessory/deco_wings/D = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
var/datum/sprite_accessory/insect_wings/I = GLOB.insect_wings_list[H.dna.features["insect_wings"]]
if(mutant_bodyparts["deco_wings"] && D?.upgrade_to.len) //species check to see if they were allowed to have deco wings
wingslist = D.upgrade_to
else if(mutant_bodyparts["insect_wings"] && I?.upgrade_to.len) //species check to see if they were allowed to have insect wings
wingslist = I.upgrade_to
else
wingslist = wings_icons
if(wingslist.len > 1)
if(!H.client)
wings_icon = pick(wingslist)
else
var/list/wings = list()
for(var/W in wingslist)
var/datum/sprite_accessory/S = GLOB.wings_list[W] //Gets the datum for every wing this species has, then prompts user with a radial menu
var/image/img = image(icon = 'icons/mob/wings_functional.dmi', icon_state = "m_wingsopen_[S.icon_state]_BEHIND") //Process the HUD elements
img.transform *= 0.5
img.pixel_x = -32
if(wings[S.name])
stack_trace("Different wing types with repeated names. Please fix as this may cause issues.")
else
wings[S.name] = img
wings_icon = show_radial_menu(H, H, wings, tooltips = TRUE)
if(!wings_icon)
wings_icon = pick(wings_icons)
else
wings_icon = wingslist[1]
if(isnull(fly))
fly = new
fly.Grant(H)
if(H.dna.features["wings"] != wings_icon)
mutant_bodyparts["wings"] = wings_icon
H.dna.features["wings"] = wings_icon
H.update_body()
/datum/species/proc/HandleFlight(mob/living/carbon/human/H)
if(H.movement_type & FLYING)
if(!CanFly(H))
ToggleFlight(H)
return FALSE
return TRUE
else
return FALSE
/datum/species/proc/CanFly(mob/living/carbon/human/H)
if(H.stat || !(H.mobility_flags & MOBILITY_STAND))
return FALSE
if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
to_chat(H, "<span class='warning'>Your suit blocks your wings from extending!</span>")
return FALSE
var/turf/T = get_turf(H)
if(!T)
return FALSE
var/datum/gas_mixture/environment = T.return_air()
if(environment && !(environment.return_pressure() > 30))
to_chat(H, "<span class='warning'>The atmosphere is too thin for you to fly!</span>")
return FALSE
else
return TRUE
/datum/species/proc/flyslip(mob/living/carbon/human/H)
var/obj/buckled_obj
if(H.buckled)
buckled_obj = H.buckled
to_chat(H, "<span class='notice'>Your wings spazz out and launch you!</span>")
playsound(H.loc, 'sound/misc/slip.ogg', 50, TRUE, -3)
for(var/obj/item/I in H.held_items)
H.accident(I)
var/olddir = H.dir
H.stop_pulling()
if(buckled_obj)
buckled_obj.unbuckle_mob(H)
step(buckled_obj, olddir)
else
new /datum/forced_movement(H, get_ranged_target_turf(H, olddir, 4), 1, FALSE, CALLBACK(H, /mob/living/carbon/.proc/spin, 1, 1))
return TRUE
//UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly
/datum/species/proc/ToggleFlight(mob/living/carbon/human/H)
if(!(H.movement_type & FLYING) && CanFly(H))
stunmod *= 2
speedmod -= 0.35
H.setMovetype(H.movement_type | FLYING)
override_float = TRUE
H.pass_flags |= PASSTABLE
H.OpenWings()
H.update_mobility()
else
stunmod *= 0.5
speedmod += 0.35
H.setMovetype(H.movement_type & ~FLYING)
override_float = FALSE
H.pass_flags &= ~PASSTABLE
H.CloseWings()
/datum/action/innate/flight
name = "Toggle Flight"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "flight"
/datum/action/innate/flight/Activate()
var/mob/living/carbon/human/H = owner
var/datum/species/S = H.dna.species
if(S.CanFly(H))
S.ToggleFlight(H)
if(!(H.movement_type & FLYING))
to_chat(H, "<span class='notice'>You settle gently back onto the ground...</span>")
else
to_chat(H, "<span class='notice'>You beat your wings and begin to hover gently above the ground...</span>")
H.set_resting(FALSE, TRUE)
@@ -12,3 +12,4 @@
species_language_holder = /datum/language_holder/synthetic
limbs_id = SPECIES_SYNTH
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
@@ -1,145 +0,0 @@
/datum/species/angel
name = "Angel"
id = SPECIES_ANGEL
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "wings" = "Angel")
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
no_equip = list(SLOT_BACK)
blacklisted = 1
limbs_id = SPECIES_HUMAN
skinned_type = /obj/item/stack/sheet/animalhide/human
species_category = SPECIES_CATEGORY_BASIC //they're a kind of human
var/datum/action/innate/flight/fly
/datum/species/angel/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
..()
if(H.dna && H.dna.species && (H.dna.features["wings"] != "Angel"))
if(!H.dna.species.mutant_bodyparts["wings"])
H.dna.species.mutant_bodyparts["wings"] = "Angel"
H.dna.features["wings"] = "Angel"
H.update_body()
if(ishuman(H) && !fly)
fly = new
fly.Grant(H)
ADD_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT)
/datum/species/angel/on_species_loss(mob/living/carbon/human/H)
if(fly)
fly.Remove(H)
if(H.movement_type & FLYING)
H.setMovetype(H.movement_type & ~FLYING)
ToggleFlight(H,0)
if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel"))
if(H.dna.species.mutant_bodyparts["wings"])
H.dna.species.mutant_bodyparts -= "wings"
H.dna.features["wings"] = "None"
H.update_body()
REMOVE_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT)
..()
/datum/species/angel/spec_life(mob/living/carbon/human/H)
HandleFlight(H)
/datum/species/angel/proc/HandleFlight(mob/living/carbon/human/H)
if(H.movement_type & FLYING)
if(!CanFly(H))
ToggleFlight(H,0)
return 0
return 1
else
return 0
/datum/species/angel/proc/CanFly(mob/living/carbon/human/H)
if(!CHECK_MOBILITY(H, MOBILITY_MOVE))
return FALSE
if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
to_chat(H, "Your suit blocks your wings from extending!")
return FALSE
var/turf/T = get_turf(H)
if(!T)
return FALSE
var/datum/gas_mixture/environment = T.return_air()
if(environment && !(environment.return_pressure() > 30))
to_chat(H, "<span class='warning'>The atmosphere is too thin for you to fly!</span>")
return FALSE
return TRUE
/datum/action/innate/flight
name = "Toggle Flight"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "flight"
/datum/action/innate/flight/Activate()
var/mob/living/carbon/human/H = owner
var/datum/species/angel/A = H.dna.species
if(A.CanFly(H))
if(H.movement_type & FLYING)
to_chat(H, "<span class='notice'>You settle gently back onto the ground...</span>")
A.ToggleFlight(H,0)
H.update_mobility()
else
to_chat(H, "<span class='notice'>You beat your wings and begin to hover gently above the ground...</span>")
H.set_resting(FALSE, TRUE)
A.ToggleFlight(H,1)
H.update_mobility()
/datum/species/angel/proc/flyslip(mob/living/carbon/human/H)
var/obj/buckled_obj
if(H.buckled)
buckled_obj = H.buckled
to_chat(H, "<span class='notice'>Your wings spazz out and launch you!</span>")
playsound(H.loc, 'sound/misc/slip.ogg', 50, 1, -3)
for(var/obj/item/I in H.held_items)
H.accident(I)
var/olddir = H.dir
H.stop_pulling()
if(buckled_obj)
buckled_obj.unbuckle_mob(H)
step(buckled_obj, olddir)
else
for(var/i=1, i<5, i++)
spawn (i)
step(H, olddir)
H.spin(1,1)
return 1
/datum/species/angel/spec_stun(mob/living/carbon/human/H,amount)
if(H.movement_type & FLYING)
ToggleFlight(H,0)
flyslip(H)
. = ..()
/datum/species/angel/negates_gravity(mob/living/carbon/human/H)
if(H.movement_type & FLYING)
return 1
/datum/species/angel/space_move(mob/living/carbon/human/H)
if(H.movement_type & FLYING)
return 1
/datum/species/angel/proc/ToggleFlight(mob/living/carbon/human/H,flight)
if(flight && CanFly(H))
stunmod = 2
speedmod = -0.1
H.setMovetype(H.movement_type | FLYING)
override_float = TRUE
H.pass_flags |= PASSTABLE
H.OpenWings()
else
stunmod = 1
speedmod = 0
H.setMovetype(H.movement_type & ~FLYING)
override_float = FALSE
H.pass_flags &= ~PASSTABLE
H.CloseWings()
update_species_slowdown(H)
@@ -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,8 @@
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 = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
@@ -21,6 +21,7 @@
var/web_cooldown = 200
var/web_ready = TRUE
var/spinner_rate = 25
wings_icons = SPECIES_WINGS_MOTH //Arachnids' phylum is arthropods, which include butterflies. Might as well hit them with moth wings.
/datum/species/arachnid/random_name(gender,unique,lastname)
if(unique)
@@ -19,6 +19,7 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_category = SPECIES_CATEGORY_INSECT
wings_icons = SPECIES_WINGS_INSECT
allowed_limb_ids = list("insect","apid","moth","moth_not_greyscale")
@@ -19,3 +19,4 @@
sexes = 0
gib_types = /obj/effect/gibspawner/robot
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
@@ -16,6 +16,7 @@
has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head.
species_category = SPECIES_CATEGORY_UNDEAD
var/pumpkin = FALSE
wings_icons = SPECIES_WINGS_SKELETAL //seems suitable for an undead.
var/obj/item/dullahan_relay/myhead
@@ -13,6 +13,7 @@
exotic_bloodtype = "BUG"
exotic_blood_color = BLOOD_COLOR_BUG
species_category = SPECIES_CATEGORY_INSECT
wings_icons = SPECIES_WINGS_INSECT
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(istype(chem, /datum/reagent/toxin/pestkiller))
@@ -12,7 +12,7 @@
punchdamagelow = 5
punchdamagehigh = 14
punchstunthreshold = 10
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE)
no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE)
nojumpsuit = 1
sexes = 1
damage_overlay_type = ""
@@ -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,9 +32,10 @@
//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
wings_icons = SPECIES_WINGS_ROBOT
var/datum/action/innate/monitor_change/screen
@@ -29,6 +29,7 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_category = SPECIES_CATEGORY_JELLY
wings_icons = SPECIES_WINGS_JELLY
ass_image = 'icons/ass/assslime.png'
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
@@ -69,6 +70,7 @@
to_chat(H, "<span class='danger'>You feel drained!</span>")
if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio))
Cannibalize_Body(H)
..()
/datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H)
var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs()
@@ -404,7 +406,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.
@@ -29,6 +29,7 @@
tail_type = "tail_lizard"
wagging_type = "waggingtail_lizard"
species_category = SPECIES_CATEGORY_LIZARD
wings_icons = SPECIES_WINGS_DRAGON
ass_image = 'icons/ass/asslizard.png'
@@ -16,7 +16,7 @@
punchdamagehigh = 12 //still better than humans
punchstunthreshold = 10
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM)
no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING)
burnmod = 1.25
heatmod = 1.5
@@ -23,6 +23,7 @@
outfit_important_for_life = /datum/outfit/plasmaman
species_category = SPECIES_CATEGORY_SKELETON
wings_icons = SPECIES_WINGS_SKELETAL
ass_image = 'icons/ass/assplasma.png'
@@ -16,6 +16,7 @@
mutanteyes = /obj/item/organ/eyes/night_vision
species_category = SPECIES_CATEGORY_SHADOW
wings_icons = SPECIES_WINGS_SKELETAL //not sure what's more spooky for these guys - skeleton or dragon?
/datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -36,7 +37,7 @@
limbs_id = SPECIES_SHADOW
burnmod = 1.5
blacklisted = TRUE
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE)
no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE)
species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_CHUNKYFINGERS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
@@ -16,6 +16,7 @@
burnmod = 1.25
species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople
wings_icons = SPECIES_WINGS_SKELETAL
/datum/species/skeleton/New()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season!
@@ -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
@@ -28,3 +35,4 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
@@ -18,6 +18,7 @@
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
species_language_holder = /datum/language_holder/synthetic
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
/datum/species/synth/military
name = "Military Synth"
@@ -15,8 +15,10 @@
skinned_type = /obj/item/stack/sheet/animalhide/human
var/info_text = "You are a <span class='danger'>Vampire</span>. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability."
species_category = SPECIES_CATEGORY_UNDEAD
wings_icons = SPECIES_WINGS_DRAGON //closest to "bat" wings.
var/batform_enabled = TRUE
/datum/species/vampire/roundstart
id = SPECIES_VAMPIRE_WEAK
batform_enabled = FALSE
@@ -17,3 +17,4 @@
disliked_food = JUNKFOOD
liked_food = GROSS | MEAT
species_category = SPECIES_CATEGORY_ALIEN
wings_icons = SPECIES_WINGS_DRAGON //most depictions of xenomorphs with wings are closest to this.
@@ -16,6 +16,7 @@
disliked_food = NONE
liked_food = GROSS | MEAT | RAW
species_category = SPECIES_CATEGORY_UNDEAD
wings_icons = SPECIES_WINGS_SKELETAL //eh.
/datum/species/zombie/notspaceproof
id = "notspaceproofzombie"
@@ -128,7 +128,7 @@ There are several things that need to be remembered:
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ICLOTHING) + 1]
inv.update_icon()
if(istype(w_uniform, /obj/item/clothing/under))
@@ -180,7 +180,7 @@ There are several things that need to be remembered:
remove_overlay(ID_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ID) + 1]
inv.update_icon()
var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER]
@@ -204,8 +204,8 @@ There are several things that need to be remembered:
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(GLOVES_LAYER)
if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1]
inv.update_icon()
if(!gloves && bloody_hands)
@@ -242,7 +242,7 @@ There are several things that need to be remembered:
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EYES) + 1]
inv.update_icon()
if(glasses)
@@ -269,7 +269,7 @@ There are several things that need to be remembered:
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EARS) + 1]
inv.update_icon()
if(ears)
@@ -295,7 +295,7 @@ There are several things that need to be remembered:
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_FEET) + 1]
inv.update_icon()
if(dna.species.mutant_bodyparts["taur"])
@@ -330,7 +330,7 @@ There are several things that need to be remembered:
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_SUITSTORE) + 1]
inv.update_icon()
if(s_store)
@@ -357,7 +357,7 @@ There are several things that need to be remembered:
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
inv.update_icon()
if(head)
@@ -394,7 +394,7 @@ There are several things that need to be remembered:
remove_overlay(BELT_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BELT) + 1]
inv.update_icon()
if(belt)
@@ -416,7 +416,7 @@ There are several things that need to be remembered:
remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_OCLOTHING) + 1]
inv.update_icon()
if(wear_suit)
@@ -479,10 +479,10 @@ There are several things that need to be remembered:
if(client && hud_used)
var/atom/movable/screen/inventory/inv
inv = hud_used.inv_slots[SLOT_L_STORE]
inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_LPOCKET) + 1]
inv.update_icon()
inv = hud_used.inv_slots[SLOT_R_STORE]
inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_RPOCKET) + 1]
inv.update_icon()
if(l_store)
@@ -506,7 +506,7 @@ There are several things that need to be remembered:
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1]
inv.update_icon()
if(wear_mask)
+51 -48
View File
@@ -1,16 +1,16 @@
/mob/living/carbon/get_item_by_slot(slot_id)
switch(slot_id)
if(SLOT_BACK)
if(ITEM_SLOT_BACK)
return back
if(SLOT_WEAR_MASK)
if(ITEM_SLOT_MASK)
return wear_mask
if(SLOT_NECK)
if(ITEM_SLOT_NECK)
return wear_neck
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
return head
if(SLOT_HANDCUFFED)
if(ITEM_SLOT_HANDCUFFED)
return handcuffed
if(SLOT_LEGCUFFED)
if(ITEM_SLOT_LEGCUFFED)
return legcuffed
return null
@@ -20,17 +20,17 @@
return slot
if(critical) //it is CRITICAL they get this item, no matter what
//do they have a backpack?
var/obj/item/backpack = get_item_by_slot(SLOT_BACK)
var/obj/item/backpack = get_item_by_slot(ITEM_SLOT_BACK)
if(!backpack)
//nothing on their back
backpack = new /obj/item/storage/backpack(get_turf(src))
if(equip_to_slot(backpack, SLOT_BACK)) //worst-case-scenario, something that shouldnt wear a backpack gets one
if(equip_to_slot(backpack, ITEM_SLOT_BACK)) //worst-case-scenario, something that shouldnt wear a backpack gets one
I.forceMove(backpack)
return SLOT_BACK
return ITEM_SLOT_BACK
else if(istype(backpack) && SEND_SIGNAL(backpack, COMSIG_CONTAINS_STORAGE))
//place it in here, regardless of storage capacity
I.forceMove(backpack)
return SLOT_BACK
return ITEM_SLOT_BACK
else
//this should NEVER happen, but if it does, report it with the appropriate information
var/conclusion = qdel_on_fail ? "deleted" : "not moved, staying at current position [I.x], [I.y], [I.z]"
@@ -69,28 +69,28 @@
I.appearance_flags |= NO_CLIENT_COLOR
var/not_handled = FALSE
switch(slot)
if(SLOT_BACK)
if(ITEM_SLOT_BACK)
back = I
update_inv_back()
if(SLOT_WEAR_MASK)
if(ITEM_SLOT_MASK)
wear_mask = I
wear_mask_update(I, toggle_off = 0)
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
head = I
head_update(I)
if(SLOT_NECK)
if(ITEM_SLOT_NECK)
wear_neck = I
update_inv_neck(I)
if(SLOT_HANDCUFFED)
if(ITEM_SLOT_HANDCUFFED)
handcuffed = I
update_handcuffed()
if(SLOT_LEGCUFFED)
if(ITEM_SLOT_LEGCUFFED)
legcuffed = I
update_inv_legcuffed()
if(SLOT_HANDS)
if(ITEM_SLOT_HANDS)
put_in_hands(I)
update_inv_hands()
if(SLOT_IN_BACKPACK)
if(ITEM_SLOT_BACKPACK)
if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
not_handled = TRUE
else
@@ -161,55 +161,58 @@
return index && hand_bodyparts[index]
/**
* Proc called when giving an item to another player
* Proc called when offering an item to another player
*
* This handles creating an alert and adding an overlay to it
*/
/mob/living/carbon/proc/give(target)
var/obj/item/receiving = get_active_held_item()
if(!receiving)
var/obj/item/offered_item = get_active_held_item()
if(!offered_item)
to_chat(src, "<span class='warning'>You're not holding anything to give!</span>")
return
visible_message("<span class='notice'>[src] is offering [receiving]</span>", \
"<span class='notice'>You offer [receiving]</span>", null, 2)
var/mob/living/carbon/targets = list()
if(!target)
for(var/mob/living/carbon/C in orange(1, src))
if(!CanReach(C))
return
targets += C
else
targets += target
if(!targets)
if(IS_DEAD_OR_INCAP(src))
to_chat(src, span_warning("You're unable to offer anything in your current state!"))
return
for(var/mob/living/carbon/C in targets)
var/atom/movable/screen/alert/give/G = C.throw_alert("[src]", /atom/movable/screen/alert/give)
if(!G)
return
G.setup(C, src, receiving)
if(has_status_effect(STATUS_EFFECT_OFFERING))
to_chat(src, span_warning("You're already offering up something!"))
return
if(offered_item.on_offered(src)) // see if the item interrupts with its own behavior
return
visible_message(span_notice("[src] is offering [offered_item]."), \
span_notice("You offer [offered_item]."), null, 2)
apply_status_effect(STATUS_EFFECT_OFFERING, offered_item)
/**
* Proc called when the player clicks the give alert
*
* Handles checking if the player taking the item has open slots and is in range of the giver
* Handles checking if the player taking the item has open slots and is in range of the offerer
* Also deals with the actual transferring of the item to the players hands
* Arguments:
* * giver - The person giving the original item
* * I - The item being given by the giver
* * offerer - The person giving the original item
* * I - The item being given by the offerer
*/
/mob/living/carbon/proc/take(mob/living/carbon/giver, obj/item/I)
clear_alert("[giver]")
if(get_dist(src, giver) > 1)
to_chat(src, "<span class='warning'>[giver] is out of range! </span>")
/mob/living/carbon/proc/take(mob/living/carbon/offerer, obj/item/I)
clear_alert("[offerer]")
if(get_dist(src, offerer) > 1)
to_chat(src, span_warning("[offerer] is out of range!"))
return
if(!I || giver.get_active_held_item() != I)
to_chat(src, "<span class='warning'>[giver] is no longer holding the item they were offering! </span>")
if(!I || offerer.get_active_held_item() != I)
to_chat(src, span_warning("[offerer] is no longer holding the item they were offering!"))
return
if(!get_empty_held_indexes())
to_chat(src, "<span class='warning'>You have no empty hands!</span>")
return
if(!giver.temporarilyRemoveItemFromInventory(I))
visible_message("<span class='notice'>[src] tries to hand over [I] but it's stuck to them....", \
if(I.on_offer_taken(offerer, src)) // see if the item has special behavior for being accepted
return
if(!offerer.temporarilyRemoveItemFromInventory(I))
visible_message("<span class='notice'>[offerer] tries to hand over [I] but it's stuck to them....", \
"<span class'notice'> You make a fool of yourself trying to give away an item stuck to your hands")
return
visible_message(span_notice("[src] takes [I] from [offerer]"), \
span_notice("You take [I] from [offerer]"))
put_in_hands(I)
+50 -6
View File
@@ -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(ITEM_SLOT_OCLOTHING)
var/head_item = get_item_by_slot(ITEM_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//
/////////
@@ -30,7 +30,7 @@
return 0
if(myPath.len <= 0)
myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, MAX_RANGE_FIND + 1, 250,1)
myPath = get_path_to(src, target, 250, 1)
if(myPath)
if(myPath.len > 0)
@@ -5,29 +5,29 @@
return FALSE
switch(slot)
if(SLOT_HANDS)
if(ITEM_SLOT_HANDS)
if(get_empty_held_indexes())
return TRUE
return FALSE
if(SLOT_WEAR_MASK)
if(ITEM_SLOT_MASK)
if(wear_mask)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_MASK) )
return FALSE
return TRUE
if(SLOT_NECK)
if(ITEM_SLOT_NECK)
if(wear_neck)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_NECK) )
return FALSE
return TRUE
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
if(head)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_HEAD) )
return FALSE
return TRUE
if(SLOT_BACK)
if(ITEM_SLOT_BACK)
if(back)
return FALSE
if( !(I.slot_flags & ITEM_SLOT_BACK) )
@@ -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()
@@ -172,5 +184,5 @@
. = ..()
if(prob(10))
var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src)
equip_to_slot_or_del(helmet,SLOT_HEAD)
equip_to_slot_or_del(helmet,ITEM_SLOT_HEAD)
INVOKE_ASYNC(helmet, /obj/item.proc/attack_self, src) // todo encapsulate toggle
@@ -29,9 +29,9 @@
if(ancestor_chain > 1)
generate_fake_scars(rand(ancestor_chain, ancestor_chain * 4))
if(relic_hat)
equip_to_slot_or_del(new relic_hat, SLOT_HEAD)
equip_to_slot_or_del(new relic_hat, ITEM_SLOT_HEAD)
if(relic_mask)
equip_to_slot_or_del(new relic_mask, SLOT_WEAR_MASK)
equip_to_slot_or_del(new relic_mask, ITEM_SLOT_MASK)
/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
@@ -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")
@@ -91,7 +91,7 @@
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1]
inv?.update_icon()
if(wear_mask)
@@ -104,8 +104,8 @@
/mob/living/carbon/update_inv_neck()
remove_overlay(NECK_LAYER)
if(client && hud_used && hud_used.inv_slots[SLOT_NECK])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_NECK]
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1]
inv.update_icon()
if(wear_neck)
@@ -119,7 +119,7 @@
remove_overlay(BACK_LAYER)
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1]
inv?.update_icon()
if(back)
@@ -135,7 +135,7 @@
return
if(client && hud_used)
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
inv?.update_icon()
if(head)
+3 -9
View File
@@ -125,7 +125,7 @@
if(IS_STAMCRIT(src))
to_chat(src, "<span class='warning'>You're too exhausted to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].</span>")
return TRUE
combat_flags &= COMBAT_FLAG_ATTEMPTING_CRAWL
combat_flags |= COMBAT_FLAG_ATTEMPTING_CRAWL
visible_message("<span class='notice'>[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] [L].</span>",
"<span class='notice'>You are now attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].</span>",
target = L, target_message = "<span class='notice'>[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] you.</span>")
@@ -395,6 +395,7 @@
..()
update_pull_movespeed()
update_pull_hud_icon()
SEND_SIGNAL(src, COMSIG_LIVING_STOPPED_PULLING)
/mob/living/verb/stop_pulling1()
set name = "Stop Pulling"
@@ -579,7 +580,7 @@
UNLINT(livingdoll.filters += filter(type="alpha", icon = mob_mask))
livingdoll.filters += filter(type="drop_shadow", size = -1)
if(severity > 0)
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity)
else
clear_fullscreen("brute")
@@ -935,13 +936,6 @@
what.forceMove(drop_location())
log_combat(src, who, "stripped [what] off")
if(Adjacent(who)) //update inventory window
who.show_inv(src)
else
src << browse(null,"window=mob[REF(who)]")
who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item
// The src mob is trying to place an item on someone
// Override if a certain mob should be behave differently when placing items (can't, for example)
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
+1 -1
View File
@@ -539,7 +539,7 @@
//called when the mob receives a bright flash
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0)
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash, override_protection = 0)
if((override_protection || get_eye_protection() < intensity) && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND))))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
@@ -9,6 +9,8 @@
resting = new_resting
if(!silent)
to_chat(src, "<span class='notice'>You are now [resting? "resting" : "getting up"].</span>")
if(resting == 1)
SEND_SIGNAL(src, COMSIG_LIVING_RESTING)
update_resting(updating)
/mob/living/proc/update_resting(update_mobility = TRUE)
@@ -36,6 +36,8 @@
if(ismob(mover))
if(mover in buckled_mobs)
return TRUE
if(HAS_TRAIT(mover, TRAIT_BEING_CARRIED))
return TRUE //We're being carried and our carrier managed to pass, ergo, let us pass aswell.
var/mob/living/L = mover //typecast first, check isliving and only check this if living using short circuit
if(isliving(L) && lying && L.lying) //if we're both lying down and aren't already being thrown/shipped around, don't pass
return FALSE
+4 -1
View File
@@ -2,7 +2,10 @@
..()
//Mind updates
sync_mind()
mind.show_memory(src, 0)
//ambition start
if(mind.memory || mind.antag_datums)
to_chat(src, "<i>[mind.show_memory()]</i>")
//ambition end
//Round specific stuff
if(SSticker.mode)
+1 -1
View File
@@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
if(!eavesdrop_range && say_test(message) == "2") // Yell hook
if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook
process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
//speech bubble
@@ -28,7 +28,7 @@
if(2)
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
/mob/living/silicon/ai/ex_act(severity, target)
/mob/living/silicon/ai/ex_act(severity, target, origin)
switch(severity)
if(1)
gib()
@@ -84,7 +84,6 @@
if(ai.client && !ai.multicam_on)
ai.client.eye = src
update_ai_detect_hud()
update_parallax_contents()
//Holopad
if(istype(ai.current, /obj/machinery/holopad))
var/obj/machinery/holopad/H = ai.current
+1 -1
View File
@@ -4,7 +4,7 @@
stat = DEAD
update_mobility()
update_sight()
clear_fullscreens()
wipe_fullscreens()
//New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here.
remove_from_alive_mob_list()
@@ -13,7 +13,7 @@
emitter_next_use = world.time + emitter_emp_cd
//Need more effects that aren't instadeath or permanent law corruption.
/mob/living/silicon/pai/ex_act(severity, target)
/mob/living/silicon/pai/ex_act(severity, target, origin)
take_holo_damage(severity * 50)
switch(severity)
if(1) //RIP
@@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
gib()
return TRUE
/mob/living/silicon/robot/ex_act(severity, target)
/mob/living/silicon/robot/ex_act(severity, target, origin)
switch(severity)
if(1)
gib()
+1 -1
View File
@@ -78,7 +78,7 @@
GLOB.silicon_mobs -= src
return ..()
/mob/living/silicon/contents_explosion(severity, target)
/mob/living/silicon/contents_explosion(severity, target, origin)
return
/mob/living/silicon/proc/cancelAlarm()
@@ -144,6 +144,6 @@
P.on_hit(src, 0, def_zone)
return BULLET_ACT_HIT
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash/static)
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash/static)
if(affect_silicon)
return ..()
@@ -292,18 +292,21 @@
/mob/living/simple_animal/bot/on_attack_hand(mob/living/carbon/human/H)
if(H.a_intent == INTENT_HELP)
interact(H)
ui_interact(H)
else
return ..()
/mob/living/simple_animal/bot/attack_ai(mob/user)
if(!topic_denied(user))
interact(user)
ui_interact(user)
else
to_chat(user, "<span class='warning'>[src]'s interface is not responding!</span>")
/mob/living/simple_animal/bot/interact(mob/user)
show_controls(user)
/mob/living/simple_animal/bot/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SimpleBot", name)
ui.open()
/mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
@@ -548,7 +551,7 @@ Pass a positive integer as an argument to override a bot's default speed.
var/datum/job/captain/All = new/datum/job/captain
all_access.access = All.get_access()
set_path(get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id=all_access))
set_path(get_path_to(src, waypoint, 200, id=all_access))
calling_ai = caller //Link the AI to the bot!
ai_waypoint = waypoint
@@ -727,6 +730,7 @@ Pass a positive integer as an argument to override a bot's default speed.
access_card.access = user_access + prev_access //Adds the user's access, if any.
mode = BOT_SUMMON
speak("Responding.", radio_channel)
calc_summon_path()
if("ejectpai")
@@ -762,12 +766,12 @@ Pass a positive integer as an argument to override a bot's default speed.
// given an optional turf to avoid
/mob/living/simple_animal/bot/proc/calc_path(turf/avoid)
check_bot_access()
set_path(get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid))
set_path(get_path_to(src, patrol_target, 120, id=access_card, exclude=avoid))
/mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid)
check_bot_access()
spawn()
set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
set_path(get_path_to(src, summon_target, 150, id=access_card, exclude=avoid))
if(!path.len) //Cannot reach target. Give up and announce the issue.
speak("Summon command failed, destination unreachable.",radio_channel)
bot_reset()
@@ -795,56 +799,48 @@ Pass a positive integer as an argument to override a bot's default speed.
else // no path, so calculate new one
calc_summon_path()
/mob/living/simple_animal/bot/Bump(M as mob|obj) //Leave no door unopened!
// Variables sent to TGUI
/mob/living/simple_animal/bot/ui_data(mob/user)
var/list/data = list()
data["can_hack"] = (issilicon(user) || IsAdminGhost(user))
data["custom_controls"] = list()
data["emagged"] = emagged
data["locked"] = locked
data["pai"] = list()
data["settings"] = list()
if(!locked || issilicon(user) || IsAdminGhost(user))
data["pai"]["allow_pai"] = allow_pai
data["pai"]["card_inserted"] = paicard
data["settings"]["airplane_mode"] = remote_disabled
data["settings"]["maintenance_lock"] = !open
data["settings"]["power"] = on
data["settings"]["patrol_station"] = auto_patrol
return data
// Actions received from TGUI
/mob/living/simple_animal/bot/ui_act(action, params)
. = ..()
if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(access_card)))
var/obj/machinery/door/D = M
if(D.check_access(access_card))
D.open()
frustration = 0
/mob/living/simple_animal/bot/proc/show_controls(mob/M)
users |= M
var/dat = ""
dat = get_controls(M)
var/datum/browser/popup = new(M,window_id,window_name,350,600)
popup.set_content(dat)
popup.open(use_onclose = 0)
onclose(M,window_id,ref=src)
return
/mob/living/simple_animal/bot/proc/update_controls()
for(var/mob/M in users)
show_controls(M)
/mob/living/simple_animal/bot/proc/get_controls(mob/M)
return "PROTOBOT - NOT FOR USE"
/mob/living/simple_animal/bot/Topic(href, href_list)
//No ..() to prevent strip panel showing up - Todo: make that saner
if(href_list["close"])// HUE HUE
if(usr in users)
users.Remove(usr)
return TRUE
if(topic_denied(usr))
to_chat(usr, "<span class='warning'>[src]'s interface is not responding!</span>")
return TRUE
add_fingerprint(usr)
if((href_list["power"]) && (bot_core.allowed(usr) || !locked))
if(on)
turn_off()
else
turn_on()
switch(href_list["operation"])
if(.)
return
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
to_chat(usr, span_warning("Access denied."))
return
if(action == "lock")
locked = !locked
if(locked && !(issilicon(usr) || IsAdminGhost(usr)))
return
switch(action)
if("power")
on = !on
update_appearance()
if("maintenance")
open = !open
if("patrol")
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
auto_patrol = !auto_patrol
bot_reset()
if("remote")
if("airplane")
remote_disabled = !remote_disabled
if("hack")
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr))
@@ -865,11 +861,11 @@ Pass a positive integer as an argument to override a bot's default speed.
hacked = FALSE
to_chat(usr, "<span class='notice'>[text_dehack]</span>")
bot_reset()
if("ejectpai")
if("eject_pai")
if(paicard && (!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
to_chat(usr, "<span class='notice'>You eject [paicard] from [bot_name]</span>")
ejectpai(usr)
update_controls()
return
/mob/living/simple_animal/bot/update_icon_state()
icon_state = "[initial(icon_state)][on]"
@@ -897,33 +893,6 @@ Pass a positive integer as an argument to override a bot's default speed.
return TRUE
return FALSE
/mob/living/simple_animal/bot/proc/hack(mob/user)
var/hack
if(hasSiliconAccessInArea(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot.
hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]<BR>"
hack += "Harm Prevention Safety System: <A href='?src=[REF(src)];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
hack += "Remote network control radio: <A href='?src=[REF(src)];operation=remote'>[remote_disabled ? "Disconnected" : "Connected"]</A><BR>"
return hack
/mob/living/simple_animal/bot/proc/showpai(mob/user)
var/eject = ""
if((!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
if(paicard || allow_pai)
eject += "Personality card status: "
if(paicard)
if(client)
eject += "<A href='?src=[REF(src)];operation=ejectpai'>Active</A>"
else
eject += "<A href='?src=[REF(src)];operation=ejectpai'>Inactive</A>"
else if(!allow_pai || key)
eject += "Unavailable"
else
eject += "Not inserted"
eject += "<BR>"
eject += "<BR>"
return eject
/mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/paicard/card)
if(paicard)
to_chat(user, "<span class='warning'>A [paicard] is already inserted!</span>")
@@ -302,7 +302,7 @@
if(!path || path.len == 0) //No path, need a new one
//Try to produce a path to the target, and ignore airlocks to which it has access.
path = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card)
path = get_path_to(src, target, 30, id=access_card)
if(!bot_move(target))
add_to_ignore(target)
target = null
@@ -443,37 +443,33 @@
/obj/machinery/bot_core/cleanbot
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"})
if(!locked || issilicon(user)|| IsAdminGhost(user))
dat += "<BR>Clean Blood: <A href='?src=[REF(src)];operation=blood'>[blood ? "Yes" : "No"]</A>"
dat += "<BR>Clean Trash: <A href='?src=[REF(src)];operation=trash'>[trash ? "Yes" : "No"]</A>"
dat += "<BR>Clean Graffiti: <A href='?src=[REF(src)];operation=drawn'>[drawn ? "Yes" : "No"]</A>"
dat += "<BR>Exterminate Pests: <A href='?src=[REF(src)];operation=pests'>[pests ? "Yes" : "No"]</A>"
dat += "<BR><BR>Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"
return dat
// Variables sent to TGUI
/mob/living/simple_animal/bot/cleanbot/ui_data(mob/user)
var/list/data = ..()
/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list)
if(..())
return 1
if(href_list["operation"])
switch(href_list["operation"])
if("blood")
blood = !blood
if("pests")
pests = !pests
if("trash")
trash = !trash
if("drawn")
drawn = !drawn
get_targets()
update_controls()
if(!locked || issilicon(user)|| IsAdminGhost(user))
data["custom_controls"]["clean_blood"] = blood
data["custom_controls"]["clean_trash"] = trash
data["custom_controls"]["clean_graffiti"] = drawn
data["custom_controls"]["pest_control"] = pests
return data
// Actions received from TGUI
/mob/living/simple_animal/bot/cleanbot/ui_act(action, params)
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(action)
if("clean_blood")
blood = !blood
if("pest_control")
pests = !pests
if("clean_trash")
trash = !trash
if("clean_graffiti")
drawn = !drawn
get_targets()
return
/obj/machinery/bot_core/cleanbot/medbay
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS, ACCESS_MEDICAL)
@@ -96,64 +96,45 @@
text_dehack = "You restore [name]'s combat inhibitor."
text_dehack_fail = "[name] ignores your attempts to restrict him!"
/mob/living/simple_animal/bot/ed209/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Security Unit v2.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
// Variables sent to TGUI
/mob/living/simple_animal/bot/ed209/ui_data(mob/user)
var/list/data = ..()
if(!locked || hasSiliconAccessInArea(user)|| IsAdminGhost(user))
if(!lasercolor)
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol[]"},
data["custom_controls"]["check_id"] = idcheck
data["custom_controls"]["check_weapons"] = weaponscheck
data["custom_controls"]["check_warrants"] = check_records
data["custom_controls"]["handcuff_targets"] = !arrest_type
data["custom_controls"]["arrest_alert"] = declare_arrests
return data
"<A href='?src=[REF(src)];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=[REF(src)];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/ed209/Topic(href, href_list)
// Actions received from TGUI
/mob/living/simple_animal/bot/ed209/ui_act(action, params)
if(lasercolor && ishuman(usr))
var/mob/living/carbon/human/H = usr
if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it
return
else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag)))
return
if(..())
return 1
switch(lasercolor) //Opposing team cannot operate it
if("b")
if(istype(H.wear_suit, /obj/item/clothing/suit/redtag))
return TRUE
if("r")
if(istype(H.wear_suit, /obj/item/clothing/suit/bluetag))
return TRUE
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(href_list["operation"])
if("idcheck")
switch(action)
if("check_id")
idcheck = !idcheck
update_controls()
if("weaponscheck")
if("check_weapons")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
if("check_warrants")
check_records = !check_records
update_controls()
if("switchmode")
if("handcuff_targets")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
if("arrest_alert")
declare_arrests = !declare_arrests
update_controls()
return
/mob/living/simple_animal/bot/ed209/proc/judgement_criteria()
var/final = FALSE
@@ -102,23 +102,6 @@
text_dehack = "You detect errors in [name] and reset his programming."
text_dehack_fail = "[name] is not responding to reset commands!"
/mob/living/simple_animal/bot/firebot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += "<TT><B>Mobile Fire Extinguisher v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
dat += "Extinguish Fires: <A href='?src=[REF(src)];operation=extinguish_fires'>[extinguish_fires ? "Yes" : "No"]</A><BR>"
dat += "Extinguish People: <A href='?src=[REF(src)];operation=extinguish_people'>[extinguish_people ? "Yes" : "No"]</A><BR>"
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
dat += "Stationary Mode: <a href='?src=[REF(src)];operation=stationary_mode'>[stationary_mode ? "Yes" : "No"]</a><br>"
return dat
/mob/living/simple_animal/bot/firebot/emag_act(mob/user)
. = ..()
if(emagged == 1)
@@ -138,20 +121,29 @@
internal_ext.max_water = INFINITY
internal_ext.refill()
/mob/living/simple_animal/bot/firebot/Topic(href, href_list)
if(..())
return TRUE
// Variables sent to TGUI
/mob/living/simple_animal/bot/firebot/ui_data(mob/user)
var/list/data = ..()
if(!locked || issilicon(user) || IsAdminGhost(user))
data["custom_controls"]["extinguish_fires"] = extinguish_fires
data["custom_controls"]["extinguish_people"] = extinguish_people
data["custom_controls"]["stationary_mode"] = stationary_mode
return data
switch(href_list["operation"])
// Actions received from TGUI
/mob/living/simple_animal/bot/firebot/ui_act(action, params)
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(action)
if("extinguish_fires")
extinguish_fires = !extinguish_fires
if("extinguish_people")
extinguish_people = !extinguish_people
if("stationary_mode")
stationary_mode = !stationary_mode
update_controls()
update_icon()
update_appearance()
return
/mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target)
if(ismob(target))
@@ -231,7 +223,7 @@
if(target_fire && (get_dist(src, target_fire) > 2))
path = get_path_to(src, get_turf(target_fire), /turf/proc/Distance_cardinal, 0, 30, 1, id=access_card)
path = get_path_to(src, target_fire, 30, 1, id=access_card)
mode = BOT_MOVING
if(!path.len)
soft_reset()
@@ -71,36 +71,6 @@
text_dehack = "You detect errors in [name] and reset his programming."
text_dehack_fail = "[name] is not responding to reset commands!"
/mob/living/simple_animal/bot/floorbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += "<TT><B>Floor Repairer Controls v1.1</B></TT><BR><BR>"
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
dat += "Special tiles: "
if(specialtiles)
dat += "<A href='?src=[REF(src)];operation=eject'>Loaded \[[specialtiles]/[maxtiles]\]</a><BR>"
else
dat += "None Loaded<BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
dat += "Add tiles to new hull plating: <A href='?src=[REF(src)];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
dat += "Place floor tiles: <A href='?src=[REF(src)];operation=place'>[placetiles ? "Yes" : "No"]</A><BR>"
dat += "Replace existing floor tiles with custom tiles: <A href='?src=[REF(src)];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
dat += "Repair damaged tiles and platings: <A href='?src=[REF(src)];operation=fix'>[fixfloors ? "Yes" : "No"]</A><BR>"
dat += "Traction Magnets: <A href='?src=[REF(src)];operation=anchor'>[anchored ? "Engaged" : "Disengaged"]</A><BR>"
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
var/bmode
if(targetdirection)
bmode = dir2text(targetdirection)
else
bmode = "disabled"
dat += "Line Mode : <A href='?src=[REF(src)];operation=linemode'>[bmode]</A><BR>"
return dat
/mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params)
if(istype(W, /obj/item/stack/tile/plasteel))
to_chat(user, "<span class='notice'>The floorbot can produce normal tiles itself.</span>")
@@ -161,26 +131,44 @@
if(user)
to_chat(user, "<span class='danger'>[src] buzzes and beeps.</span>")
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
if(..())
return 1
// Variables sent to TGUI
/mob/living/simple_animal/bot/floorbot/ui_data(mob/user)
var/list/data = ..()
if(!locked || issilicon(user) || IsAdminGhost(user))
data["custom_controls"]["tile_hull"] = autotile
data["custom_controls"]["place_tiles"] = placetiles
data["custom_controls"]["place_custom"] = replacetiles
data["custom_controls"]["repair_damage"] = fixfloors
data["custom_controls"]["traction_magnets"] = anchored
data["custom_controls"]["tile_stack"] = 0
data["custom_controls"]["line_mode"] = FALSE
if(specialtiles)
data["custom_controls"]["tile_stack"] = specialtiles
if(targetdirection)
data["custom_controls"]["line_mode"] = dir2text(targetdirection)
return data
switch(href_list["operation"])
if("replace")
// Actions received from TGUI
/mob/living/simple_animal/bot/floorbot/ui_act(action, params)
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(action)
if("place_custom")
replacetiles = !replacetiles
if("place")
if("place_tiles")
placetiles = !placetiles
if("fix")
if("repair_damage")
fixfloors = !fixfloors
if("autotile")
if("tile_hull")
autotile = !autotile
if("anchor")
if("traction_magnets")
anchored = !anchored
if("eject")
if("eject_tiles")
if(specialtiles && tiletype != null)
empty_tiles()
if("linemode")
if("line_mode")
var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable")
switch(setdir)
if("north")
@@ -193,7 +181,7 @@
targetdirection = 8
if("disable")
targetdirection = null
update_controls()
return
/mob/living/simple_animal/bot/floorbot/proc/empty_tiles()
new tiletype(drop_location(), specialtiles)
@@ -275,9 +263,9 @@
if(path.len == 0)
if(!isturf(target))
var/turf/TL = get_turf(target)
path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
path = get_path_to(src, TL, 30, id=access_card,simulated_only = 0)
else
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
path = get_path_to(src, target, 30, id=access_card,simulated_only = 0)
if(!bot_move(target))
add_to_ignore(target)
@@ -78,24 +78,6 @@
text_dehack = "You reboot [name] and restore the sound control system."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/honkbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Honkomatic Bike Horn Unit v1.0.7 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=[REF(src)];power=[TRUE]'>[on ? "On" : "Off"]</A>" )
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
dat += text({"<BR> Auto Patrol: []"},
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/honkbot/proc/judgement_criteria()
var/final = NONE
if(check_records)
@@ -155,87 +155,63 @@
/mob/living/simple_animal/bot/medbot/attack_paw(mob/user)
return attack_hand(user)
/mob/living/simple_animal/bot/medbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += "<TT><B>Medical Unit Controls v1.1</B></TT><BR><BR>"
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
dat += "Beaker: "
// Variables sent to TGUI
/mob/living/simple_animal/bot/medbot/ui_data(mob/user)
var/list/data = ..()
if(reagent_glass)
dat += "<A href='?src=[REF(src)];eject=1'>Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]</a>"
else
dat += "None Loaded"
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
data["custom_controls"]["beaker"] = reagent_glass
data["custom_contrlos"]["reagents"] = "[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]"
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
dat += "<TT>Healing Threshold: "
dat += "<a href='?src=[REF(src)];adj_threshold=-10'>--</a> "
dat += "<a href='?src=[REF(src)];adj_threshold=-5'>-</a> "
dat += "[heal_threshold] "
dat += "<a href='?src=[REF(src)];adj_threshold=5'>+</a> "
dat += "<a href='?src=[REF(src)];adj_threshold=10'>++</a>"
dat += "</TT><br>"
data["custom_controls"]["injection_amount"] = injection_amount
data["custom_controls"]["use_beaker"] = use_beaker
data["custom_controls"]["treat_virus"] = treat_virus
data["custom_controls"]["heal_threshold"] = heal_threshold
data["custom_controls"]["speaker"] = !shut_up
data["custom_controls"]["crit_alerts"] = declare_crit
data["custom_controls"]["stationary_mode"] = stationary_mode
return data
dat += "<TT>Injection Level: "
dat += "<a href='?src=[REF(src)];adj_inject=-5'>-</a> "
dat += "[injection_amount] "
dat += "<a href='?src=[REF(src)];adj_inject=5'>+</a> "
dat += "</TT><br>"
// Actions received from TGUI
/mob/living/simple_animal/bot/medbot/ui_act(action, params)
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(action)
if("heal_threshold")
var/adjust_num = round(text2num(params["threshold"]))
heal_threshold = adjust_num
if(heal_threshold < 5)
heal_threshold = 5
if(heal_threshold > 75)
heal_threshold = 75
dat += "Reagent Source: "
dat += "<a href='?src=[REF(src)];use_beaker=1'>[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]</a><br>"
if("injection_amount")
var/adjust_num = round(text2num(params["amount"]))
injection_amount = adjust_num
if(injection_amount < 1)
injection_amount = 1
if(injection_amount > 15)
injection_amount = 15
dat += "Treat Viral Infections: <a href='?src=[REF(src)];virus=1'>[treat_virus ? "Yes" : "No"]</a><br>"
dat += "The speaker switch is [shut_up ? "off" : "on"]. <a href='?src=[REF(src)];togglevoice=[1]'>Toggle</a><br>"
dat += "Critical Patient Alerts: <a href='?src=[REF(src)];critalerts=1'>[declare_crit ? "Yes" : "No"]</a><br>"
dat += "Patrol Station: <a href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</a><br>"
dat += "Stationary Mode: <a href='?src=[REF(src)];stationary=1'>[stationary_mode ? "Yes" : "No"]</a><br>"
if("use_beaker")
use_beaker = !use_beaker
return dat
if("eject")
if(!isnull(reagent_glass))
reagent_glass.forceMove(drop_location())
reagent_glass = null
/mob/living/simple_animal/bot/medbot/Topic(href, href_list)
if(..())
return 1
if("speaker")
shut_up = !shut_up
if("crit_alerts")
declare_crit = !declare_crit
if("stationary_mode")
stationary_mode = !stationary_mode
path = list()
update_appearance()
if(href_list["adj_threshold"])
var/adjust_num = text2num(href_list["adj_threshold"])
heal_threshold += adjust_num
if(heal_threshold < 5)
heal_threshold = 5
if(heal_threshold > 75)
heal_threshold = 75
else if(href_list["adj_inject"])
var/adjust_num = text2num(href_list["adj_inject"])
injection_amount += adjust_num
if(injection_amount < 5)
injection_amount = 5
if(injection_amount > 15)
injection_amount = 15
else if(href_list["use_beaker"])
use_beaker = !use_beaker
else if(href_list["eject"] && (!isnull(reagent_glass)))
reagent_glass.forceMove(drop_location())
reagent_glass = null
else if(href_list["togglevoice"])
shut_up = !shut_up
else if(href_list["critalerts"])
declare_crit = !declare_crit
else if(href_list["stationary"])
stationary_mode = !stationary_mode
path = list()
update_icon()
else if(href_list["virus"])
treat_virus = !treat_virus
update_controls()
if("virus")
treat_virus = !treat_virus
return
/mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params)
@@ -251,7 +227,6 @@
reagent_glass = W
to_chat(user, "<span class='notice'>You insert [W].</span>")
show_controls(user)
else if(istype(W, /obj/item/reagent_containers/syringe/piercing))
if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_PIERERCING))
@@ -517,10 +492,10 @@
return
if(patient && path.len == 0 && (get_dist(src,patient) > 1))
path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card)
path = get_path_to(src, patient, 30, id=access_card)
mode = BOT_MOVING
if(!path.len) //try to get closer if you can't reach the patient directly
path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card)
path = get_path_to(src, patient, 30, 1, id=access_card)
if(!path.len) //Do not chase a patient we cannot reach.
soft_reset()
@@ -138,7 +138,7 @@
add_overlay(load)
return
/mob/living/simple_animal/bot/mulebot/ex_act(severity)
/mob/living/simple_animal/bot/mulebot/ex_act(severity, target, origin)
unload(0)
switch(severity)
if(1)
@@ -276,56 +276,6 @@
if("ejectpai")
ejectpairemote(user)
// TODO: remove this; PDAs currently depend on it
/mob/living/simple_animal/bot/mulebot/get_controls(mob/user)
var/ai = hasSiliconAccessInArea(user)
var/dat
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
dat += "<b>ID:</b> [id]<BR>"
dat += "<b>Power:</b> [on ? "On" : "Off"]<BR>"
dat += "<h3>Status</h3>"
dat += "<div class='statusDisplay'>"
switch(mode)
if(BOT_IDLE)
dat += "<span class='good'>Ready</span>"
if(BOT_DELIVER)
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
if(BOT_GO_HOME)
dat += "<span class='good'>[mode_name[BOT_GO_HOME]]</span>"
if(BOT_BLOCKED)
dat += "<span class='average'>[mode_name[BOT_BLOCKED]]</span>"
if(BOT_NAV,BOT_WAIT_FOR_NAV)
dat += "<span class='average'>[mode_name[BOT_NAV]]</span>"
if(BOT_NO_ROUTE)
dat += "<span class='bad'>[mode_name[BOT_NO_ROUTE]]</span>"
dat += "</div>"
dat += "<b>Current Load:</b> [load ? load.name : "<i>none</i>"]<BR>"
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
if(locked && !ai && !IsAdminGhost(user))
dat += "&nbsp;<br /><div class='notice'>Controls are locked</div><A href='byond://?src=[REF(src)];op=unlock'>Unlock Controls</A>"
else
dat += "&nbsp;<br /><div class='notice'>Controls are unlocked</div><A href='byond://?src=[REF(src)];op=lock'>Lock Controls</A><BR><BR>"
dat += "<A href='byond://?src=[REF(src)];op=power'>Toggle Power</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=stop'>Stop</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=go'>Proceed</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=home'>Return to Home</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=destination'>Set Destination</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=setid'>Set Bot ID</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=sethome'>Set Home</A><BR>"
dat += "<A href='byond://?src=[REF(src)];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
dat += "<A href='byond://?src=[REF(src)];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
dat += "<A href='byond://?src=[REF(src)];op=report'>Toggle Delivery Reporting</A> ([report_delivery ? "On" : "Off"])<BR>"
if(load)
dat += "<A href='byond://?src=[REF(src)];op=unload'>Unload Now</A><BR>"
dat += "<div class='notice'>The maintenance hatch is closed.</div>"
return dat
// returns true if the bot has power
/mob/living/simple_animal/bot/mulebot/proc/has_power()
return !open && cell && cell.charge > 0 && (!wires.is_cut(WIRE_POWER1) && !wires.is_cut(WIRE_POWER2))
@@ -580,7 +530,7 @@
// calculates a path to the current destination
// given an optional turf to avoid
/mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null)
path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid)
path = get_path_to(src, target, 250, id=access_card, exclude=avoid)
// sets the current destination
// signals all beacons matching the delivery code
@@ -209,57 +209,34 @@
text_dehack = "You reboot [name] and restore the target identification."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
// Variables sent to TGUI
/mob/living/simple_animal/bot/secbot/ui_data(mob/user)
var/list/data = ..()
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol: []"},
data["custom_controls"]["check_id"] = idcheck
data["custom_controls"]["check_weapons"] = weaponscheck
data["custom_controls"]["check_warrants"] = check_records
data["custom_controls"]["handcuff_targets"] = !arrest_type
data["custom_controls"]["arrest_alert"] = declare_arrests
return data
"<A href='?src=[REF(src)];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=[REF(src)];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
// Actions received from TGUI
/mob/living/simple_animal/bot/secbot/ui_act(action, params)
. = ..()
if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
switch(href_list["operation"])
if("idcheck")
switch(action)
if("check_id")
idcheck = !idcheck
update_controls()
if("weaponscheck")
if("check_weapons")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
if("check_warrants")
check_records = !check_records
update_controls()
if("switchmode")
if("handcuff_targets")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
if("arrest_alert")
declare_arrests = !declare_arrests
update_controls()
return
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
var/judgement_criteria = judgement_criteria()
@@ -60,5 +60,5 @@
else
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
/mob/living/simple_animal/cockroach/ex_act() //Explosions are a terrible way to handle a cockroach.
/mob/living/simple_animal/cockroach/ex_act(severity, target, origin) //Explosions are a terrible way to handle a cockroach.
return
@@ -24,6 +24,7 @@
. = ..()
AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
AddElement(/datum/element/mob_holder, held_icon)
AddElement(/datum/element/strippable, GLOB.strippable_corgi_items)
//Corgis and pugs are now under one dog subtype
@@ -104,18 +105,175 @@
..(gibbed)
regenerate_icons()
/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user)
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
/datum/strippable_item/corgi_head,
/datum/strippable_item/corgi_back,
/datum/strippable_item/corgi_collar,
/datum/strippable_item/corgi_id,
)))
/datum/strippable_item/corgi_head
key = STRIPPABLE_ITEM_HEAD
/datum/strippable_item/corgi_head/get_item(atom/source)
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
user.set_machine(src)
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
dat += "<br><B>Head:</B> <A href='?src=[REF(src)];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</A>"
dat += "<br><B>Back:</B> <A href='?src=[REF(src)];[inventory_back ? "remove_inv=back'>[inventory_back]" : "add_inv=back'>Nothing"]</A>"
dat += "<br><B>Collar:</B> <A href='?src=[REF(src)];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
return corgi_source.inventory_head
user << browse(dat, "window=mob[REF(src)];size=325x500")
onclose(user, "mob[REF(src)]")
/datum/strippable_item/corgi_head/finish_equip(atom/source, obj/item/equipping, mob/user)
if(!..())
return FALSE
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return FALSE
corgi_source.place_on_head(equipping, user)
/datum/strippable_item/corgi_head/finish_unequip(atom/source, mob/user)
..()
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
finish_unequip_mob(corgi_source.inventory_head, corgi_source, user)
corgi_source.inventory_head = null
corgi_source.update_corgi_fluff()
corgi_source.regenerate_icons()
/datum/strippable_item/corgi_back
key = STRIPPABLE_ITEM_BACK
/datum/strippable_item/corgi_back/get_item(atom/source)
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
return corgi_source.inventory_back
/datum/strippable_item/corgi_back/try_equip(atom/source, obj/item/equipping, mob/user)
. = ..()
if (!.)
return FALSE
if (!ispath(equipping.dog_fashion, /datum/dog_fashion/back))
to_chat(user, "<span class='warning'>You set [equipping] on [source]'s back, but it falls off!</span>")
equipping.forceMove(source.drop_location())
if (prob(25))
step_rand(equipping)
dance_rotate(source, set_original_dir = TRUE)
return FALSE
return TRUE
/datum/strippable_item/corgi_back/finish_equip(atom/source, obj/item/equipping, mob/user)
if(!..())
return FALSE
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return FALSE
equipping.forceMove(corgi_source)
corgi_source.inventory_back = equipping
corgi_source.update_corgi_fluff()
corgi_source.regenerate_icons()
/datum/strippable_item/corgi_back/finish_unequip(atom/source, mob/user)
..()
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
finish_unequip_mob(corgi_source.inventory_back, corgi_source, user)
corgi_source.inventory_back = null
corgi_source.update_corgi_fluff()
corgi_source.regenerate_icons()
/datum/strippable_item/corgi_collar
key = STRIPPABLE_ITEM_CORGI_COLLAR
/datum/strippable_item/corgi_collar/get_item(atom/source)
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
return corgi_source.pcollar
/datum/strippable_item/corgi_collar/try_equip(atom/source, obj/item/equipping, mob/user)
. = ..()
if (!.)
return FALSE
if (!istype(equipping, /obj/item/clothing/neck/petcollar))
to_chat(user, "<span class='warning'>That's not a collar.</span>")
return FALSE
return TRUE
/datum/strippable_item/corgi_collar/finish_equip(atom/source, obj/item/equipping, mob/user)
if(!..())
return FALSE
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return FALSE
corgi_source.add_collar(equipping, user)
corgi_source.update_corgi_fluff()
/datum/strippable_item/corgi_collar/finish_unequip(atom/source, mob/user)
..()
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
finish_unequip_mob(corgi_source.pcollar, corgi_source, user)
corgi_source.pcollar = null
corgi_source.update_corgi_fluff()
corgi_source.regenerate_icons()
/datum/strippable_item/corgi_id
key = STRIPPABLE_ITEM_ID
/datum/strippable_item/corgi_id/get_item(atom/source)
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
return corgi_source.access_card
/datum/strippable_item/corgi_id/try_equip(atom/source, obj/item/equipping, mob/user)
. = ..()
if (!.)
return FALSE
if (!istype(equipping, /obj/item/card/id))
to_chat(user, "<span class='warning'>You can't pin [equipping] to [source]!</span>")
return FALSE
return TRUE
/datum/strippable_item/corgi_id/finish_equip(atom/source, obj/item/equipping, mob/user)
if(!..())
return FALSE
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return FALSE
equipping.forceMove(source)
corgi_source.access_card = equipping
/datum/strippable_item/corgi_id/finish_unequip(atom/source, mob/user)
..()
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
if (!istype(corgi_source))
return
finish_unequip_mob(corgi_source.access_card, corgi_source, user)
corgi_source.access_card = null
corgi_source.update_corgi_fluff()
corgi_source.regenerate_icons()
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type)
var/armorval = 0
@@ -158,114 +316,12 @@
..()
update_corgi_fluff()
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
usr << browse(null, "window=mob[REF(src)]")
usr.unset_machine()
return
//Removing from inventory
if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if(BODY_ZONE_HEAD)
if(inventory_head)
usr.put_in_hands(inventory_head)
inventory_head = null
update_corgi_fluff()
regenerate_icons()
else
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
return
if("back")
if(inventory_back)
usr.put_in_hands(inventory_back)
inventory_back = null
update_corgi_fluff()
regenerate_icons()
else
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
return
if("collar")
if(pcollar)
usr.put_in_hands(pcollar)
pcollar = null
update_corgi_fluff()
regenerate_icons()
show_inv(usr)
//Adding things to inventory
else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
switch(add_to)
if("collar")
var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item()
if(!istype(P))
to_chat(usr,"<span class='warning'>That's not a collar.</span>")
return
add_collar(P, usr)
update_corgi_fluff()
if(BODY_ZONE_HEAD)
place_on_head(usr.get_active_held_item(),usr)
if("back")
if(inventory_back)
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
return
else
var/obj/item/item_to_add = usr.get_active_held_item()
if(!item_to_add)
usr.visible_message("[usr] pets [src].","<span class='notice'>You rest your hand on [src]'s back for a moment.</span>")
return
if(!usr.temporarilyRemoveItemFromInventory(item_to_add))
to_chat(usr, "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>")
return
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
item_to_add.afterattack(src,usr,1)
return
//The objects that corgis can wear on their backs.
var/allowed = FALSE
if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/back))
allowed = TRUE
if(!allowed)
to_chat(usr, "<span class='warning'>You set [item_to_add] on [src]'s back, but it falls off!</span>")
item_to_add.forceMove(drop_location())
if(prob(25))
step_rand(item_to_add)
for(var/i in list(1,2,4,8,4,8,4,dir))
setDir(i)
sleep(1)
return
item_to_add.forceMove(src)
src.inventory_back = item_to_add
update_corgi_fluff()
regenerate_icons()
show_inv(usr)
else
return ..()
//Corgis are supposed to be simpler, so only a select few objects can actually be put
//to be compatible with them. The objects are below.
//Many hats added, Some will probably be removed, just want to see which ones are popular.
// > some will probably be removed
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
INVOKE_ASYNC(item_to_add, /obj/item.proc/afterattack, src, user, 1)
return
if(inventory_head)
if(user)
to_chat(user, "<span class='warning'>You can't put more than one hat on [src]!</span>")
@@ -303,9 +359,7 @@
item_to_add.forceMove(drop_location())
if(prob(25))
step_rand(item_to_add)
for(var/i in list(1,2,4,8,4,8,4,dir))
setDir(i)
sleep(1)
dance_rotate(src, set_original_dir = TRUE)
return valid
@@ -88,10 +88,10 @@
if(default_storage)
var/obj/item/I = new default_storage(src)
equip_to_slot_or_del(I, SLOT_GENERC_DEXTROUS_STORAGE)
equip_to_slot_or_del(I, ITEM_SLOT_DEX_STORAGE)
if(default_hatmask)
var/obj/item/I = new default_hatmask(src)
equip_to_slot_or_del(I, SLOT_HEAD)
equip_to_slot_or_del(I, ITEM_SLOT_HEAD)
ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
@@ -61,7 +61,7 @@
if(!D.default_hatmask && seasonal_hats && possible_seasonal_hats.len)
var/hat_type = pick(possible_seasonal_hats)
var/obj/item/new_hat = new hat_type(D)
D.equip_to_slot_or_del(new_hat, SLOT_HEAD)
D.equip_to_slot_or_del(new_hat, ITEM_SLOT_HEAD)
D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
user.transfer_ckey(D, FALSE)
qdel(src)
@@ -188,6 +188,9 @@
/mob/living/simple_animal/drone/cogscarab/update_drone_hack()
return //we don't get hacked or give a shit about it
/mob/living/simple_animal/drone/cogscarab/death(gibbed)
. = ..()
/mob/living/simple_animal/drone/cogscarab/drone_chat(msg)
titled_hierophant_message(src, msg, "nezbere", "brass", "Construct") //HIEROPHANT DRONES
@@ -21,13 +21,13 @@
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
switch(slot)
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
if(head)
return 0
if(!((I.slot_flags & ITEM_SLOT_HEAD) || (I.slot_flags & ITEM_SLOT_MASK)))
return 0
return 1
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(ITEM_SLOT_DEX_STORAGE)
if(internal_storage)
return 0
return 1
@@ -36,9 +36,9 @@
/mob/living/simple_animal/drone/get_item_by_slot(slot_id)
switch(slot_id)
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
return head
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(ITEM_SLOT_DEX_STORAGE)
return internal_storage
return ..()
@@ -63,10 +63,10 @@
I.plane = ABOVE_HUD_PLANE
switch(slot)
if(SLOT_HEAD)
if(ITEM_SLOT_HEAD)
head = I
update_inv_head()
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(ITEM_SLOT_DEX_STORAGE)
internal_storage = I
update_inv_internal_storage()
else
@@ -77,7 +77,7 @@
I.equipped(src, slot)
/mob/living/simple_animal/drone/getBackSlot()
return SLOT_GENERC_DEXTROUS_STORAGE
return ITEM_SLOT_DEX_STORAGE
/mob/living/simple_animal/drone/getBeltSlot()
return SLOT_GENERC_DEXTROUS_STORAGE
return ITEM_SLOT_DEX_STORAGE
@@ -273,10 +273,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
summoner.adjustCloneLoss(amount * 0.5) //dying hosts take 50% bonus damage as cloneloss
update_health_hud()
/mob/living/simple_animal/hostile/guardian/ex_act(severity, target)
/mob/living/simple_animal/hostile/guardian/ex_act(severity, target, origin)
switch(severity)
if(1)
gib()
if(istype(origin, /datum/explosion))
gib(was_explosion = origin)
else
gib()
return
if(2)
adjustBruteLoss(60)
@@ -286,10 +289,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/mob/living/simple_animal/hostile/guardian/wave_ex_act(power, datum/wave_explosion/explosion, dir)
adjustBruteLoss(EXPLOSION_POWER_STANDARD_SCALE_MOB_DAMAGE(power, explosion.mob_damage_mod * 0.33))
/mob/living/simple_animal/hostile/guardian/gib()
/mob/living/simple_animal/hostile/guardian/gib(no_brain, no_organs, no_bodyparts, datum/explosion/was_explosion)
if(summoner)
to_chat(summoner, "<span class='danger'><B>Your [src] was blown up!</span></B>")
summoner.gib()
summoner.gib(was_explosion = was_explosion)
ghostize()
qdel(src)
@@ -52,7 +52,7 @@
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
switch(slot)
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(ITEM_SLOT_DEX_STORAGE)
if(internal_storage)
return 0
return 1
@@ -63,17 +63,17 @@
return
switch(slot)
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(ITEM_SLOT_DEX_STORAGE)
internal_storage = I
update_inv_internal_storage()
else
to_chat(src, "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>")
/mob/living/simple_animal/hostile/guardian/dextrous/getBackSlot()
return SLOT_GENERC_DEXTROUS_STORAGE
return ITEM_SLOT_DEX_STORAGE
/mob/living/simple_animal/hostile/guardian/dextrous/getBeltSlot()
return SLOT_GENERC_DEXTROUS_STORAGE
return ITEM_SLOT_DEX_STORAGE
/mob/living/simple_animal/hostile/guardian/dextrous/proc/update_inv_internal_storage()
if(internal_storage && client && hud_used && hud_used.hud_shown)
@@ -11,7 +11,7 @@
toggle_button_type = /atom/movable/screen/guardian/ToggleMode
var/toggle = FALSE
/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity)
/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity, target, origin)
if(severity == 1)
adjustBruteLoss(400) //if in protector mode, will do 20 damage and not actually necessarily kill the summoner
else
@@ -87,7 +87,7 @@
else
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
/mob/living/simple_animal/banana_spider/ex_act()
/mob/living/simple_animal/banana_spider/ex_act(severity, target, origin)
return
/mob/living/simple_animal/banana_spider/start_pulling()
@@ -62,7 +62,7 @@
user.transfer_ckey(src, FALSE)
density = TRUE
/mob/living/simple_animal/hostile/bread/ex_act()
/mob/living/simple_animal/hostile/bread/ex_act(severity, target, origin)
return
/mob/living/simple_animal/hostile/bread/start_pulling()
@@ -132,7 +132,7 @@ Difficulty: Medium
return FALSE
return ..()
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target)
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target, origin)
if(dash())
return
return ..()
@@ -154,7 +154,7 @@ Difficulty: Hard
return 0
return ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target)
/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target, origin)
if(severity >= EXPLODE_LIGHT)
return
severity = EXPLODE_LIGHT // puny mortals
@@ -421,7 +421,7 @@ Difficulty: Very Hard
if(ismob(AM))
ActivationReaction(AM, ACTIVATE_MOB_BUMP)
/obj/machinery/anomalous_crystal/ex_act()
/obj/machinery/anomalous_crystal/ex_act(severity, target, origin)
ActivationReaction(null, ACTIVATE_BOMB)
/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing
@@ -740,7 +740,7 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/emp_act()
return
/obj/structure/closet/stasis/ex_act()
/obj/structure/closet/stasis/ex_act(severity, target, origin)
return
/obj/structure/closet/stasis/handle_lock_addition()
@@ -147,7 +147,7 @@ Difficulty: Extremely Hard
if(isturf(target) || isobj(target))
target.ex_act(EXPLODE_HEAVY)
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target)
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target, origin)
adjustBruteLoss(30 * severity - 120)
visible_message("<span class='danger'>[src] absorbs the explosion!</span>", "<span class='userdanger'>You absorb the explosion!</span>")
@@ -79,7 +79,7 @@ Difficulty: Medium
. = ..()
internal = new/obj/item/gps/internal/dragon(src)
/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target)
/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target, origin)
if(severity == 3)
return
..()
@@ -387,7 +387,7 @@ Difficulty: Medium
light_range = 2
duration = 13
/obj/effect/temp_visual/lava_warning/ex_act()
/obj/effect/temp_visual/lava_warning/ex_act(severity, target, origin)
return
/obj/effect/temp_visual/lava_warning/Initialize(mapload, var/reset_time = 10)
@@ -674,7 +674,7 @@ Difficulty: Normal
layer = LOW_OBJ_LAYER
anchored = TRUE
/obj/effect/hierophant/ex_act()
/obj/effect/hierophant/ex_act(severity, target, origin)
return
/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
@@ -138,7 +138,7 @@
adjustBruteLoss(-L.maxHealth/2)
L.gib()
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target)
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target, origin)
switch (severity)
if (EXPLODE_DEVASTATE)
adjustBruteLoss(250)
@@ -50,7 +50,7 @@
if(isliving(target) && !target.Adjacent(targets_from) && ranged_cooldown <= world.time)//No more being shot at point blank or spammed with RNG beams
OpenFire(target)
/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target)
/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target, origin)
switch(severity)
if(1)
gib()
@@ -113,7 +113,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
severity = 7
hud_used.healths.icon_state = "elite_health[severity]"
if(severity > 0)
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity)
else
clear_fullscreen("brute")
@@ -191,7 +191,7 @@
continue
visible_message("<span class='danger'>[src] grabs hold of [L]!</span>")
var/mob/living/carbon/C = L
var/obj/item/clothing/S = C.get_item_by_slot(SLOT_WEAR_SUIT)
var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING)
if(S && S.resistance_flags & GOLIATH_RESISTANCE)
L.Stun(25)
else if(S && S.resistance_flags & GOLIATH_WEAKNESS)
@@ -90,7 +90,7 @@
/datum/action/cooldown/coffer/Trigger()
. = ..()
if(!.)
if(!. || owner.stat != CONSCIOUS)
return
var/turf/T = get_turf(owner)
var/loot = rand(1,100)
@@ -135,7 +135,7 @@
/datum/action/cooldown/riot/Trigger()
. = ..()
if(!.)
if(!. || owner.stat != CONSCIOUS)
return
var/cap = CONFIG_GET(number/ratcap)
var/something_from_nothing = FALSE
+90 -77
View File
@@ -124,6 +124,9 @@
/mob/living/simple_animal/parrot/proc/toggle_mode,
/mob/living/simple_animal/parrot/proc/perch_mob_player))
/mob/living/simple_animal/parrot/ComponentInitialize()
. = ..()
AddElement(/datum/element/strippable, GLOB.strippable_parrot_items)
/mob/living/simple_animal/parrot/examine(mob/user)
. = ..()
@@ -183,91 +186,101 @@
return 0
/*
* Inventory
*/
/mob/living/simple_animal/parrot/show_inv(mob/user)
user.set_machine(src)
GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
/datum/strippable_item/parrot_headset,
)))
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
dat += "<br><B>Headset:</B> <A href='?src=[REF(src)];[ears ? "remove_inv=ears'>[ears]" : "add_inv=ears'>Nothing"]</A>"
/datum/strippable_item/parrot_headset
key = STRIPPABLE_ITEM_PARROT_HEADSET
user << browse(dat, "window=mob[REF(src)];size=325x500")
onclose(user, "window=mob[REF(src)]")
/datum/strippable_item/parrot_headset/get_item(atom/source)
var/mob/living/simple_animal/parrot/parrot_source = source
return istype(parrot_source) ? parrot_source.ears : null
/datum/strippable_item/parrot_headset/try_equip(atom/source, obj/item/equipping, mob/user)
. = ..()
if (!.)
return FALSE
/mob/living/simple_animal/parrot/Topic(href, href_list)
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
usr << browse(null, "window=mob[REF(src)]")
usr.unset_machine()
if (!istype(equipping, /obj/item/radio/headset))
to_chat(user, "<span class='warning'>[equipping] won't fit!</span>")
return FALSE
return TRUE
// There is no delay for putting a headset on a parrot.
/datum/strippable_item/parrot_headset/start_equip(atom/source, obj/item/equipping, mob/user)
if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY)
return FALSE
return TRUE
/datum/strippable_item/parrot_headset/finish_equip(atom/source, obj/item/equipping, mob/user)
if(!..())
return FALSE
var/obj/item/radio/headset/radio = equipping
if (!istype(radio))
return FALSE
var/mob/living/simple_animal/parrot/parrot_source = source
if (!istype(parrot_source))
return FALSE
if (!user.transferItemToLoc(radio, source))
return FALSE
parrot_source.ears = radio
to_chat(user, "<span class='notice'>You fit [radio] onto [source].</span>")
parrot_source.available_channels.Cut()
for (var/channel in radio.channels)
var/channel_to_add
switch (channel)
if (RADIO_CHANNEL_ENGINEERING)
channel_to_add = RADIO_TOKEN_ENGINEERING
if (RADIO_CHANNEL_COMMAND)
channel_to_add = RADIO_TOKEN_COMMAND
if (RADIO_CHANNEL_SECURITY)
channel_to_add = RADIO_TOKEN_SECURITY
if (RADIO_CHANNEL_SCIENCE)
channel_to_add = RADIO_TOKEN_SCIENCE
if (RADIO_CHANNEL_MEDICAL)
channel_to_add = RADIO_TOKEN_MEDICAL
if (RADIO_CHANNEL_SUPPLY)
channel_to_add = RADIO_TOKEN_SUPPLY
if (RADIO_CHANNEL_SERVICE)
channel_to_add = RADIO_TOKEN_SERVICE
if (channel_to_add)
parrot_source.available_channels += channel_to_add
if (radio.translate_binary)
parrot_source.available_channels.Add(MODE_TOKEN_BINARY)
/datum/strippable_item/parrot_headset/start_unequip(atom/source, mob/user)
. = ..()
if (!.)
return FALSE
var/mob/living/simple_animal/parrot/parrot_source = source
if (!istype(parrot_source))
return
//Removing from inventory
if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if("ears")
if(!ears)
to_chat(usr, "<span class='warning'>There is nothing to remove from its [remove_from]!</span>")
return
if(!stat)
say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
ears.forceMove(drop_location())
ears = null
for(var/possible_phrase in speak)
if(copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys)
possible_phrase = copytext_char(possible_phrase, 3)
if (!parrot_source.stat)
parrot_source.say("[parrot_source.available_channels.len ? "[pick(parrot_source.available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
//Adding things to inventory
else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
if(!usr.get_active_held_item())
to_chat(usr, "<span class='warning'>You have nothing in your hand to put on its [add_to]!</span>")
return
switch(add_to)
if("ears")
if(ears)
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
return
else
var/obj/item/item_to_add = usr.get_active_held_item()
if(!item_to_add)
return
return TRUE
if( !istype(item_to_add, /obj/item/radio/headset) )
to_chat(usr, "<span class='warning'>This object won't fit!</span>")
return
var/obj/item/radio/headset/headset_to_add = item_to_add
if(!usr.transferItemToLoc(headset_to_add, src))
return
ears = headset_to_add
to_chat(usr, "<span class='notice'>You fit the headset onto [src].</span>")
clearlist(available_channels)
for(var/ch in headset_to_add.channels)
switch(ch)
if(RADIO_CHANNEL_ENGINEERING)
available_channels.Add(RADIO_TOKEN_ENGINEERING)
if(RADIO_CHANNEL_COMMAND)
available_channels.Add(RADIO_TOKEN_COMMAND)
if(RADIO_CHANNEL_SECURITY)
available_channels.Add(RADIO_TOKEN_SECURITY)
if(RADIO_CHANNEL_SCIENCE)
available_channels.Add(RADIO_TOKEN_SCIENCE)
if(RADIO_CHANNEL_MEDICAL)
available_channels.Add(RADIO_TOKEN_MEDICAL)
if(RADIO_CHANNEL_SUPPLY)
available_channels.Add(RADIO_TOKEN_SUPPLY)
if(RADIO_CHANNEL_SERVICE)
available_channels.Add(RADIO_TOKEN_SERVICE)
if(headset_to_add.translate_binary)
available_channels.Add(MODE_TOKEN_BINARY)
else
return ..()
/datum/strippable_item/parrot_headset/finish_unequip(atom/source, mob/user)
..()
var/mob/living/simple_animal/parrot/parrot_source = source
if (!istype(parrot_source))
return
finish_unequip_mob(parrot_source.ears, parrot_source, user)
parrot_source.ears = null
/*
* Attack responces
@@ -642,7 +655,7 @@
item = I
break
if(item)
if(!AStar(src, get_turf(item), /turf/proc/Distance_cardinal))
if(!get_path_to(src, item))
item = null
continue
return item
@@ -307,11 +307,16 @@
if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp))
adjustHealth(unsuitable_atmos_damage)
/mob/living/simple_animal/gib()
if(butcher_results)
/mob/living/simple_animal/gib(no_brain, no_organs, no_bodyparts, datum/explosion/was_explosion)
if(butcher_results || guaranteed_butcher_results)
var/list/butcher = list()
if(butcher_results)
butcher += butcher_results
if(guaranteed_butcher_results)
butcher += guaranteed_butcher_results
var/atom/Tsec = drop_location()
for(var/path in butcher_results)
for(var/i in 1 to butcher_results[path])
for(var/path in butcher)
for(var/i in 1 to butcher[path])
new path(Tsec)
..()
+1 -1
View File
@@ -599,7 +599,7 @@
/mob/living/proc/become_nearsighted(source)
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)
ADD_TRAIT(src, TRAIT_NEARSIGHT, source)
/mob/living/proc/cure_husk(source)