mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-24 04:28:12 +01:00
Merge remote-tracking branch 'upstream/dev' into CultVisualNetwork
Conflicts: code/setup.dm
This commit is contained in:
@@ -802,6 +802,7 @@ var/list/admin_verbs_mentor = list(
|
||||
M.r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
M.update_eyes()
|
||||
|
||||
var/new_skin = input("Please select body color. This is for Tajaran, Unathi, and Skrell only!", "Character Generation") as color
|
||||
if(new_skin)
|
||||
|
||||
@@ -968,11 +968,7 @@
|
||||
|
||||
//strip their stuff and stick it in the crate
|
||||
for(var/obj/item/I in M)
|
||||
M.u_equip(I)
|
||||
if(I)
|
||||
I.loc = locker
|
||||
I.layer = initial(I.layer)
|
||||
I.dropped(M)
|
||||
M.drop_from_inventory(I, locker)
|
||||
M.update_icons()
|
||||
|
||||
//so they black out before warping
|
||||
@@ -1005,11 +1001,7 @@
|
||||
return
|
||||
|
||||
for(var/obj/item/I in M)
|
||||
M.u_equip(I)
|
||||
if(I)
|
||||
I.loc = M.loc
|
||||
I.layer = initial(I.layer)
|
||||
I.dropped(M)
|
||||
M.drop_from_inventory(I)
|
||||
|
||||
M.Paralyse(5)
|
||||
sleep(5)
|
||||
@@ -1034,11 +1026,7 @@
|
||||
return
|
||||
|
||||
for(var/obj/item/I in M)
|
||||
M.u_equip(I)
|
||||
if(I)
|
||||
I.loc = M.loc
|
||||
I.layer = initial(I.layer)
|
||||
I.dropped(M)
|
||||
M.drop_from_inventory(I)
|
||||
|
||||
M.Paralyse(5)
|
||||
sleep(5)
|
||||
@@ -1085,11 +1073,7 @@
|
||||
return
|
||||
|
||||
for(var/obj/item/I in M)
|
||||
M.u_equip(I)
|
||||
if(I)
|
||||
I.loc = M.loc
|
||||
I.layer = initial(I.layer)
|
||||
I.dropped(M)
|
||||
M.drop_from_inventory(I)
|
||||
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/observer = M
|
||||
@@ -1835,16 +1819,10 @@
|
||||
if(!security)
|
||||
//strip their stuff before they teleport into a cell :downs:
|
||||
for(var/obj/item/weapon/W in H)
|
||||
if(istype(W, /datum/organ/external))
|
||||
if(istype(W, /obj/item/organ/external))
|
||||
continue
|
||||
//don't strip organs
|
||||
H.u_equip(W)
|
||||
if (H.client)
|
||||
H.client.screen -= W
|
||||
if (W)
|
||||
W.loc = H.loc
|
||||
W.dropped(H)
|
||||
W.layer = initial(W.layer)
|
||||
H.drop_from_inventory(W)
|
||||
//teleport person to cell
|
||||
H.loc = pick(prisonwarp)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/proc/getbrokeninhands()
|
||||
var/icon/IL = new('icons/mob/items_lefthand.dmi')
|
||||
var/icon/IL = new('icons/mob/items/lefthand.dmi')
|
||||
var/list/Lstates = IL.IconStates()
|
||||
var/icon/IR = new('icons/mob/items_righthand.dmi')
|
||||
var/icon/IR = new('icons/mob/items/righthand.dmi')
|
||||
var/list/Rstates = IR.IconStates()
|
||||
|
||||
|
||||
|
||||
@@ -735,19 +735,19 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
commandos.equip(M)
|
||||
|
||||
if("nanotrasen representative")
|
||||
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform)
|
||||
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_if_possible(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear)
|
||||
|
||||
var/obj/item/device/pda/heads/pda = new(M)
|
||||
pda.owner = M.real_name
|
||||
pda.ownjob = "NanoTrasen Navy Representative"
|
||||
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
|
||||
|
||||
M.equip_if_possible(pda, slot_r_store)
|
||||
M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_if_possible(new /obj/item/weapon/clipboard(M), slot_belt)
|
||||
M.equip_to_slot_or_del(pda, slot_r_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_belt)
|
||||
|
||||
var/obj/item/weapon/card/id/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card"
|
||||
@@ -757,23 +757,23 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
W.access += list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer")
|
||||
W.assignment = "NanoTrasen Navy Representative"
|
||||
W.registered_name = M.real_name
|
||||
M.equip_if_possible(W, slot_wear_id)
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
if("nanotrasen officer")
|
||||
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
|
||||
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head)
|
||||
|
||||
var/obj/item/device/pda/heads/pda = new(M)
|
||||
pda.owner = M.real_name
|
||||
pda.ownjob = "NanoTrasen Navy Officer"
|
||||
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
|
||||
|
||||
M.equip_if_possible(pda, slot_r_store)
|
||||
M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt)
|
||||
M.equip_to_slot_or_del(pda, slot_r_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt)
|
||||
|
||||
var/obj/item/weapon/card/id/centcom/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card"
|
||||
@@ -781,24 +781,24 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
W.access += get_all_centcom_access()
|
||||
W.assignment = "NanoTrasen Navy Officer"
|
||||
W.registered_name = M.real_name
|
||||
M.equip_if_possible(W, slot_wear_id)
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
|
||||
if("nanotrasen captain")
|
||||
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform)
|
||||
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head)
|
||||
|
||||
var/obj/item/device/pda/heads/pda = new(M)
|
||||
pda.owner = M.real_name
|
||||
pda.ownjob = "NanoTrasen Navy Captain"
|
||||
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
|
||||
|
||||
M.equip_if_possible(pda, slot_r_store)
|
||||
M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_if_possible(new /obj/item/weapon/gun/energy(M), slot_belt)
|
||||
M.equip_to_slot_or_del(pda, slot_r_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt)
|
||||
|
||||
var/obj/item/weapon/card/id/centcom/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card"
|
||||
@@ -806,7 +806,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
W.access += get_all_centcom_access()
|
||||
W.assignment = "NanoTrasen Navy Captain"
|
||||
W.registered_name = M.real_name
|
||||
M.equip_if_possible(W, slot_wear_id)
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
if("emergency response team")
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
proc/triggered(mob/target as mob, var/type = "feet")
|
||||
if(!armed)
|
||||
return
|
||||
var/datum/organ/external/affecting = null
|
||||
var/obj/item/organ/external/affecting = null
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
switch(type)
|
||||
|
||||
@@ -111,6 +111,7 @@ datum/preferences
|
||||
// maps each organ to either null(intact), "cyborg" or "amputated"
|
||||
// will probably not be able to do this for head and torso ;)
|
||||
var/list/organ_data = list()
|
||||
var/list/rlimb_data = list()
|
||||
var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor"
|
||||
|
||||
var/list/flavor_texts = list()
|
||||
@@ -344,7 +345,12 @@ datum/preferences
|
||||
++ind
|
||||
if(ind > 1)
|
||||
dat += ", "
|
||||
dat += "\tMechanical [organ_name] prothesis"
|
||||
var/datum/robolimb/R
|
||||
if(rlimb_data[name] && all_robolimbs[rlimb_data[name]])
|
||||
R = all_robolimbs[rlimb_data[name]]
|
||||
else
|
||||
R = basic_robolimb
|
||||
dat += "\t[R.company] [organ_name] prothesis"
|
||||
else if(status == "amputated")
|
||||
++ind
|
||||
if(ind > 1)
|
||||
@@ -629,6 +635,8 @@ datum/preferences
|
||||
dat += "</br><b>Has a plantlike physiology.</b>"
|
||||
if(current_species.flags & IS_SYNTHETIC)
|
||||
dat += "</br><b>Is machine-based.</b>"
|
||||
if(current_species.flags & REGENERATES_LIMBS)
|
||||
dat += "</br><b>Has a plantlike physiology.</b>"
|
||||
dat += "</small></td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table><center><hr/>"
|
||||
@@ -1421,15 +1429,25 @@ datum/preferences
|
||||
switch(new_state)
|
||||
if("Normal")
|
||||
organ_data[limb] = null
|
||||
rlimb_data[limb] = null
|
||||
if(third_limb)
|
||||
organ_data[third_limb] = null
|
||||
rlimb_data[third_limb] = null
|
||||
if("Amputated")
|
||||
organ_data[limb] = "amputated"
|
||||
rlimb_data[limb] = null
|
||||
if(second_limb)
|
||||
organ_data[second_limb] = "amputated"
|
||||
rlimb_data[second_limb] = null
|
||||
|
||||
if("Prothesis")
|
||||
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in chargen_robolimbs
|
||||
if(!choice)
|
||||
return
|
||||
rlimb_data[limb] = choice
|
||||
organ_data[limb] = "cyborg"
|
||||
if(second_limb)
|
||||
organ_data[second_limb] = choice
|
||||
organ_data[second_limb] = "cyborg"
|
||||
if(third_limb && organ_data[third_limb] == "amputated")
|
||||
organ_data[third_limb] = null
|
||||
@@ -1662,21 +1680,28 @@ datum/preferences
|
||||
for(var/name in organ_data)
|
||||
|
||||
var/status = organ_data[name]
|
||||
var/datum/organ/external/O = character.organs_by_name[name]
|
||||
var/obj/item/organ/external/O = character.organs_by_name[name]
|
||||
if(O)
|
||||
if(status == "amputated")
|
||||
O.amputated = 1
|
||||
O.status |= ORGAN_DESTROYED
|
||||
O.destspawn = 1
|
||||
character.organs_by_name[O.limb_name] = null
|
||||
character.organs -= O
|
||||
if(O.children) // This might need to become recursive.
|
||||
for(var/obj/item/organ/external/child in O.children)
|
||||
character.organs_by_name[child.limb_name] = null
|
||||
character.organs -= child
|
||||
|
||||
else if(status == "cyborg")
|
||||
O.status |= ORGAN_ROBOT
|
||||
if(rlimb_data[name])
|
||||
O.robotize(rlimb_data[name])
|
||||
else
|
||||
O.robotize()
|
||||
else
|
||||
var/datum/organ/internal/I = character.internal_organs_by_name[name]
|
||||
var/obj/item/organ/I = character.internal_organs_by_name[name]
|
||||
if(I)
|
||||
if(status == "assisted")
|
||||
I.mechassist()
|
||||
else if(status == "mechanical")
|
||||
I.mechanize()
|
||||
I.robotize()
|
||||
|
||||
character.underwear = underwear
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
S["skills"] >> skills
|
||||
S["skill_specialization"] >> skill_specialization
|
||||
S["organ_data"] >> organ_data
|
||||
S["rlimb_data"] >> rlimb_data
|
||||
S["gear"] >> gear
|
||||
S["home_system"] >> home_system
|
||||
S["citizenship"] >> citizenship
|
||||
@@ -240,6 +241,7 @@
|
||||
if(isnull(disabilities)) disabilities = 0
|
||||
if(!player_alt_titles) player_alt_titles = new()
|
||||
if(!organ_data) src.organ_data = list()
|
||||
if(!rlimb_data) src.rlimb_data = list()
|
||||
if(!gear) src.gear = list()
|
||||
//if(!skin_style) skin_style = "Default"
|
||||
|
||||
@@ -324,6 +326,7 @@
|
||||
S["skills"] << skills
|
||||
S["skill_specialization"] << skill_specialization
|
||||
S["organ_data"] << organ_data
|
||||
S["rlimb_data"] << rlimb_data
|
||||
S["gear"] << gear
|
||||
S["home_system"] << home_system
|
||||
S["citizenship"] << citizenship
|
||||
|
||||
@@ -45,21 +45,15 @@
|
||||
siemens_coefficient = 0.6
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
species_restricted = list("Vox", "Vox Armalis")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/suit.dmi',
|
||||
)
|
||||
species_restricted = list("Vox")
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
|
||||
|
||||
/obj/item/clothing/head/helmet/space/vox
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0.6
|
||||
flags = HEADCOVERSEYES|STOPPRESSUREDAMAGE
|
||||
species_restricted = list("Vox","Vox Armalis")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/head.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/head.dmi',
|
||||
)
|
||||
species_restricted = list("Vox")
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi')
|
||||
|
||||
/obj/item/clothing/head/helmet/space/vox/pressure
|
||||
name = "alien helmet"
|
||||
@@ -137,22 +131,15 @@
|
||||
siemens_coefficient = 0
|
||||
permeability_coefficient = 0.05
|
||||
item_color = "gloves-vox"
|
||||
species_restricted = list("Vox","Vox Armalis")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/gloves.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/gloves.dmi',
|
||||
)
|
||||
species_restricted = list("Vox")
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi')
|
||||
/obj/item/clothing/shoes/magboots/vox
|
||||
|
||||
desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor."
|
||||
name = "vox magclaws"
|
||||
item_state = "boots-vox"
|
||||
icon_state = "boots-vox"
|
||||
|
||||
species_restricted = list("Vox","Vox Armalis")
|
||||
sprite_sheets = list(
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/feet.dmi'
|
||||
)
|
||||
species_restricted = list("Vox")
|
||||
|
||||
action_button_name = "Toggle the magclaws"
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
desc = "A shoulder-mounted battery-powered laser cannon mount."
|
||||
selectable = 1
|
||||
usable = 1
|
||||
use_power_cost = 10
|
||||
module_cooldown = 0
|
||||
|
||||
engage_string = "Configure"
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
// Some space suits are equipped with reactive membranes that support
|
||||
// broken limbs - at the time of writing, only the ninja suit, but
|
||||
// I can see it being useful for other suits as we expand them. ~ Z
|
||||
// The actual splinting occurs in /datum/organ/external/proc/fracture()
|
||||
// The actual splinting occurs in /obj/item/organ/external/proc/fracture()
|
||||
/obj/item/clothing/suit/space/proc/check_limb_support(var/mob/living/carbon/human/user)
|
||||
|
||||
// If this isn't set, then we don't need to care.
|
||||
@@ -87,7 +87,7 @@
|
||||
return
|
||||
|
||||
// Otherwise, remove the splints.
|
||||
for(var/datum/organ/external/E in supporting_limbs)
|
||||
for(var/obj/item/organ/external/E in supporting_limbs)
|
||||
E.status &= ~ ORGAN_SPLINTED
|
||||
user << "The suit stops supporting your [E.display_name]."
|
||||
user << "The suit stops supporting your [E.name]."
|
||||
supporting_limbs = list()
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
//replace old ID
|
||||
del(C)
|
||||
ok = M.equip_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail
|
||||
ok = M.equip_to_slot_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail
|
||||
break
|
||||
else if(istype(Item,/obj/item/weapon/storage/belt))
|
||||
if(M.ckey == "jakksergal" && M.real_name == "Nashi Ra'hal" && M.mind.role_alt_title && M.mind.role_alt_title != "Nurse" && M.mind.role_alt_title != "Chemist")
|
||||
@@ -72,13 +72,13 @@
|
||||
for(var/obj/item/weapon/storage/belt/B in M)
|
||||
del(B)
|
||||
M.belt=null
|
||||
ok = M.equip_if_possible(I, slot_belt, 0)
|
||||
ok = M.equip_to_slot_if_possible(I, slot_belt, 0)
|
||||
break
|
||||
if(istype(M.belt,/obj/item/device/pda))
|
||||
for(var/obj/item/device/pda/Pda in M)
|
||||
M.belt=null
|
||||
M.equip_if_possible(Pda, slot_l_store, 0)
|
||||
ok = M.equip_if_possible(I, slot_belt, 0)
|
||||
M.equip_to_slot_if_possible(Pda, slot_l_store, 0)
|
||||
ok = M.equip_to_slot_if_possible(I, slot_belt, 0)
|
||||
else if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back
|
||||
Item.loc = M.back
|
||||
ok = 1
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("dexalin"))
|
||||
for(var/organ_name in list("chest","l_arm","r_arm","r_leg","l_leg","head","groin"))
|
||||
var/datum/organ/external/E = H.get_organ(organ_name)
|
||||
var/obj/item/organ/external/E = H.get_organ(organ_name)
|
||||
E.take_damage(0, 5, 0)
|
||||
|
||||
/datum/genetics/side_effect/bone_snap
|
||||
@@ -42,7 +42,7 @@
|
||||
finish(mob/living/carbon/human/H)
|
||||
if(!H.reagents.has_reagent("bicaridine"))
|
||||
var/organ_name = pick("chest","l_arm","r_arm","r_leg","l_leg","head","groin")
|
||||
var/datum/organ/external/E = H.get_organ(organ_name)
|
||||
var/obj/item/organ/external/E = H.get_organ(organ_name)
|
||||
E.take_damage(20, 0, 0)
|
||||
E.fracture()
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ var/global/list/holodeck_programs = list(
|
||||
if(isobj(obj))
|
||||
var/mob/M = obj.loc
|
||||
if(ismob(M))
|
||||
M.u_equip(obj)
|
||||
M.remove_from_mob(obj)
|
||||
M.update_icons() //so their overlays update
|
||||
|
||||
if(!silent)
|
||||
@@ -384,4 +384,4 @@ var/global/list/holodeck_programs = list(
|
||||
var/area/targetsource = locate(/area/holodeck/source_plating)
|
||||
targetsource.copy_contents_to(linkedholodeck , 1)
|
||||
active = 0
|
||||
use_power = 1
|
||||
use_power = 1
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
del(W)
|
||||
return
|
||||
else if (istype(W, /obj/item) && get_dist(src,user)<2)
|
||||
user.drop_item(src)
|
||||
user.drop_item(src.loc)
|
||||
visible_message("<span class='notice'>[user] dunks [W] into the [src]!</span>", 3)
|
||||
return
|
||||
|
||||
|
||||
@@ -110,19 +110,19 @@
|
||||
|
||||
|
||||
if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin")
|
||||
var/datum/organ/external/affecting = target.get_organ(target_limb)
|
||||
var/obj/item/organ/external/affecting = target.get_organ(target_limb)
|
||||
var/damage = 0
|
||||
|
||||
if(get_trait(TRAIT_CARNIVOROUS))
|
||||
if(get_trait(TRAIT_CARNIVOROUS) == 2)
|
||||
if(affecting)
|
||||
target << "<span class='danger'>\The [fruit]'s thorns pierce your [affecting.display_name] greedily!</span>"
|
||||
target << "<span class='danger'>\The [fruit]'s thorns pierce your [affecting.name] greedily!</span>"
|
||||
else
|
||||
target << "<span class='danger'>\The [fruit]'s thorns pierce your flesh greedily!</span>"
|
||||
damage = get_trait(TRAIT_POTENCY)/2
|
||||
else
|
||||
if(affecting)
|
||||
target << "<span class='danger'>\The [fruit]'s thorns dig deeply into your [affecting.display_name]!</span>"
|
||||
target << "<span class='danger'>\The [fruit]'s thorns dig deeply into your [affecting.name]!</span>"
|
||||
else
|
||||
target << "<span class='danger'>\The [fruit]'s thorns dig deeply into your flesh!</span>"
|
||||
damage = get_trait(TRAIT_POTENCY)/5
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0)
|
||||
user << "That seed is not compatible with our genetics technology."
|
||||
else
|
||||
user.drop_item(W)
|
||||
user.remove_from_mob(W)
|
||||
W.loc = src
|
||||
seed = W
|
||||
user << "You load [W] into [src]."
|
||||
@@ -120,7 +120,7 @@
|
||||
user << "That disk does not have any gene data loaded."
|
||||
return
|
||||
|
||||
user.drop_item(W)
|
||||
user.remove_from_mob(W)
|
||||
W.loc = src
|
||||
loaded_disk = W
|
||||
user << "You load [W] into [src]."
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O as obj)
|
||||
if (istype(O.loc, /mob))
|
||||
var/mob/user = O.loc
|
||||
user.drop_item(O)
|
||||
user.remove_from_mob(O)
|
||||
else if(istype(O.loc,/obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = O.loc
|
||||
S.remove_from_storage(O, src)
|
||||
|
||||
@@ -453,7 +453,7 @@
|
||||
if(!seed)
|
||||
|
||||
var/obj/item/seeds/S = O
|
||||
user.drop_item(O)
|
||||
user.remove_from_mob(O)
|
||||
|
||||
if(!S.seed)
|
||||
user << "The packet seems to be empty. You throw it away."
|
||||
@@ -497,7 +497,7 @@
|
||||
else if ( istype(O, /obj/item/weapon/plantspray) )
|
||||
|
||||
var/obj/item/weapon/plantspray/spray = O
|
||||
user.drop_item(O)
|
||||
user.remove_from_mob(O)
|
||||
toxins += spray.toxicity
|
||||
pestlevel -= spray.pest_kill_str
|
||||
weedlevel -= spray.weed_kill_str
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
icon_state = "hatchet"
|
||||
flags = CONDUCT
|
||||
force = 12.0
|
||||
w_class = 2.0
|
||||
w_class = 3.0
|
||||
throwforce = 15.0
|
||||
throw_speed = 4
|
||||
throw_range = 4
|
||||
|
||||
@@ -118,6 +118,8 @@
|
||||
origin_tech = "materials=4;phorontech=3;engineering=3"
|
||||
desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff."
|
||||
drill_verb = "cutting"
|
||||
sharp = 1
|
||||
edge = 1
|
||||
|
||||
/obj/item/weapon/pickaxe/diamond
|
||||
name = "diamond pickaxe"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/weapon/ore))
|
||||
user.u_equip(W)
|
||||
user.remove_from_mob(W)
|
||||
src.contents += W
|
||||
if (istype(W, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = W
|
||||
|
||||
+98
-192
@@ -1,15 +1,81 @@
|
||||
//This proc is called whenever someone clicks an inventory ui slot.
|
||||
/mob/proc/attack_ui(slot)
|
||||
var/obj/item/W = get_active_hand()
|
||||
if(istype(W))
|
||||
equip_to_slot_if_possible(W, slot)
|
||||
|
||||
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
|
||||
if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
|
||||
return 1
|
||||
else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//This is a SAFE proc. Use this instead of equip_to_slot()!
|
||||
//set del_on_fail to have it delete W if it fails to equip
|
||||
//set disable_warning to disable the 'you are unable to equip that' warning.
|
||||
//unset redraw_mob to prevent the mob from being redrawn at the end.
|
||||
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
|
||||
if(!istype(W)) return 0
|
||||
|
||||
if(!W.mob_can_equip(src, slot))
|
||||
if(del_on_fail)
|
||||
del(W)
|
||||
else
|
||||
if(!disable_warning)
|
||||
src << "\red You are unable to equip that." //Only print if del_on_fail is false
|
||||
return 0
|
||||
|
||||
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
|
||||
return 1
|
||||
|
||||
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task.
|
||||
//In most cases you will want to use equip_to_slot_if_possible()
|
||||
/mob/proc/equip_to_slot(obj/item/W as obj, slot)
|
||||
return
|
||||
|
||||
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
|
||||
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
|
||||
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
|
||||
|
||||
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
|
||||
var/list/slot_equipment_priority = list( \
|
||||
slot_back,\
|
||||
slot_wear_id,\
|
||||
slot_w_uniform,\
|
||||
slot_wear_suit,\
|
||||
slot_wear_mask,\
|
||||
slot_head,\
|
||||
slot_shoes,\
|
||||
slot_gloves,\
|
||||
slot_l_ear,\
|
||||
slot_r_ear,\
|
||||
slot_glasses,\
|
||||
slot_belt,\
|
||||
slot_s_store,\
|
||||
slot_tie,\
|
||||
slot_l_store,\
|
||||
slot_r_store\
|
||||
)
|
||||
|
||||
//puts the item "W" into an appropriate slot in a human's inventory
|
||||
//returns 0 if it cannot, 1 if successful
|
||||
/mob/proc/equip_to_appropriate_slot(obj/item/W)
|
||||
if(!istype(W)) return 0
|
||||
|
||||
for(var/slot in slot_equipment_priority)
|
||||
if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc
|
||||
//as they handle all relevant stuff like adding it to the player's screen and updating their overlays.
|
||||
|
||||
//Returns the thing in our active hand
|
||||
/mob/proc/get_active_hand()
|
||||
if(issilicon(src))
|
||||
if(isrobot(src))
|
||||
if(src:module_active)
|
||||
return src:module_active
|
||||
else
|
||||
if(hand) return l_hand
|
||||
else return r_hand
|
||||
if(hand) return l_hand
|
||||
else return r_hand
|
||||
|
||||
//Returns the thing in our inactive hand
|
||||
/mob/proc/get_inactive_hand()
|
||||
@@ -77,96 +143,45 @@
|
||||
W.dropped()
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/mob/proc/drop_item_v() //this is dumb.
|
||||
if(stat == CONSCIOUS && isturf(loc))
|
||||
return drop_item()
|
||||
return 0
|
||||
|
||||
|
||||
// Removes an item from inventory and places it in the target atom
|
||||
/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
|
||||
if(W)
|
||||
if(!Target)
|
||||
Target = loc
|
||||
|
||||
if(client) client.screen -= W
|
||||
u_equip(W)
|
||||
remove_from_mob(W)
|
||||
if(!W) return 1 // self destroying objects (tk, grabs)
|
||||
W.layer = initial(W.layer)
|
||||
W.loc = Target
|
||||
|
||||
var/turf/T = get_turf(Target)
|
||||
if(isturf(T))
|
||||
T.Entered(W)
|
||||
|
||||
W.dropped(src)
|
||||
|
||||
W.forceMove(Target)
|
||||
update_icons()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
//Drops the item in our left hand
|
||||
/mob/proc/drop_l_hand(var/atom/Target)
|
||||
if(l_hand)
|
||||
if(client) client.screen -= l_hand
|
||||
l_hand.layer = initial(l_hand.layer)
|
||||
|
||||
if(Target) l_hand.loc = Target.loc
|
||||
else l_hand.loc = loc
|
||||
|
||||
var/turf/T = get_turf(loc)
|
||||
if(isturf(T))
|
||||
T.Entered(l_hand)
|
||||
|
||||
l_hand.dropped(src)
|
||||
l_hand = null
|
||||
update_inv_l_hand()
|
||||
return 1
|
||||
return 0
|
||||
return drop_from_inventory(l_hand, Target)
|
||||
|
||||
//Drops the item in our right hand
|
||||
/mob/proc/drop_r_hand(var/atom/Target)
|
||||
if(r_hand)
|
||||
if(client) client.screen -= r_hand
|
||||
r_hand.layer = initial(r_hand.layer)
|
||||
return drop_from_inventory(r_hand, Target)
|
||||
|
||||
if(Target) r_hand.loc = Target.loc
|
||||
else r_hand.loc = loc
|
||||
|
||||
var/turf/T = get_turf(Target)
|
||||
if(istype(T))
|
||||
T.Entered(r_hand)
|
||||
|
||||
r_hand.dropped(src)
|
||||
r_hand = null
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Drops the item in our active hand.
|
||||
//Drops the item in our active hand. TODO: rename this to drop_active_hand or something
|
||||
/mob/proc/drop_item(var/atom/Target)
|
||||
if(hand) return drop_l_hand(Target)
|
||||
else return drop_r_hand(Target)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO: phase out this proc
|
||||
/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this?
|
||||
W.loc = null
|
||||
W.layer = initial(W.layer)
|
||||
u_equip(W)
|
||||
update_icons()
|
||||
return
|
||||
|
||||
|
||||
/mob/proc/u_equip(W as obj)
|
||||
/*
|
||||
Removes the object from any slots the mob might have, calling the appropriate icon update proc.
|
||||
Does nothing else.
|
||||
|
||||
DO NOT CALL THIS PROC DIRECTLY. It is meant to be called only by other inventory procs.
|
||||
It's probably okay to use it if you are transferring the item between slots on the same mob,
|
||||
but chances are you're safer calling remove_from_mob() or drop_from_inventory() anyways.
|
||||
|
||||
As far as I can tell the proc exists so that mobs with different inventory slots can override
|
||||
the search through all the slots, without having to duplicate the rest of the item dropping.
|
||||
*/
|
||||
/mob/proc/u_equip(obj/W as obj)
|
||||
if (W == r_hand)
|
||||
r_hand = null
|
||||
update_inv_r_hand(0)
|
||||
@@ -181,40 +196,27 @@
|
||||
update_inv_wear_mask(0)
|
||||
return
|
||||
|
||||
//This differs from remove_from_mob() in that it checks canremove first.
|
||||
/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress.
|
||||
if(!I) //If there's nothing to drop, the drop is automatically successful. If(unEquip) should generally be used to check for NODROP.
|
||||
if(!I) //If there's nothing to drop, the drop is automatically successful.
|
||||
return 1
|
||||
|
||||
/*if((I.flags & NODROP) && !force)
|
||||
return 0*/
|
||||
|
||||
if(!I.canremove && !force)
|
||||
return 0
|
||||
|
||||
if(I == r_hand)
|
||||
r_hand = null
|
||||
update_inv_r_hand()
|
||||
else if(I == l_hand)
|
||||
l_hand = null
|
||||
update_inv_l_hand()
|
||||
|
||||
if(I)
|
||||
if(client)
|
||||
client.screen -= I
|
||||
I.loc = loc
|
||||
I.dropped(src)
|
||||
if(I)
|
||||
I.layer = initial(I.layer)
|
||||
remove_from_mob(I)
|
||||
return 1
|
||||
|
||||
//Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob.
|
||||
//It does call u_equip() though. So it can drop items to the floor but only if src is human.
|
||||
/mob/proc/remove_from_mob(var/obj/O)
|
||||
src.u_equip(O)
|
||||
if (src.client)
|
||||
src.client.screen -= O
|
||||
O.layer = initial(O.layer)
|
||||
O.screen_loc = null
|
||||
if(istype(O, /obj/item))
|
||||
var/obj/item/I = O
|
||||
I.dropped()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -240,99 +242,3 @@
|
||||
//if(hasvar(src,"r_hand")) if(src:r_hand) items += src:r_hand
|
||||
|
||||
return items
|
||||
|
||||
/** BS12's proc to get the item in the active hand. Couldn't find the /tg/ equivalent. **/
|
||||
/mob/proc/equipped()
|
||||
return get_active_hand() //TODO: get rid of this proc
|
||||
|
||||
/mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, del_on_fail = 1) // since byond doesn't seem to have pointers, this seems like the best way to do this :/
|
||||
//warning: icky code
|
||||
var/equipped = 0
|
||||
switch(slot)
|
||||
if(slot_back)
|
||||
if(!src.back)
|
||||
src.back = W
|
||||
equipped = 1
|
||||
if(slot_wear_mask)
|
||||
if(!src.wear_mask)
|
||||
src.wear_mask = W
|
||||
equipped = 1
|
||||
if(slot_handcuffed)
|
||||
if(!src.handcuffed)
|
||||
src.handcuffed = W
|
||||
equipped = 1
|
||||
if(slot_l_hand)
|
||||
if(!src.l_hand)
|
||||
src.l_hand = W
|
||||
equipped = 1
|
||||
if(slot_r_hand)
|
||||
if(!src.r_hand)
|
||||
src.r_hand = W
|
||||
equipped = 1
|
||||
if(slot_belt)
|
||||
if(!src.belt && src.w_uniform)
|
||||
src.belt = W
|
||||
equipped = 1
|
||||
if(slot_wear_id)
|
||||
if(!src.wear_id && src.w_uniform)
|
||||
src.wear_id = W
|
||||
equipped = 1
|
||||
if(slot_l_ear)
|
||||
if(!src.l_ear)
|
||||
src.l_ear = W
|
||||
equipped = 1
|
||||
if(slot_r_ear)
|
||||
if(!src.r_ear)
|
||||
src.r_ear = W
|
||||
equipped = 1
|
||||
if(slot_glasses)
|
||||
if(!src.glasses)
|
||||
src.glasses = W
|
||||
equipped = 1
|
||||
if(slot_gloves)
|
||||
if(!src.gloves)
|
||||
src.gloves = W
|
||||
equipped = 1
|
||||
if(slot_head)
|
||||
if(!src.head)
|
||||
src.head = W
|
||||
equipped = 1
|
||||
if(slot_shoes)
|
||||
if(!src.shoes)
|
||||
src.shoes = W
|
||||
equipped = 1
|
||||
if(slot_wear_suit)
|
||||
if(!src.wear_suit)
|
||||
src.wear_suit = W
|
||||
equipped = 1
|
||||
if(slot_w_uniform)
|
||||
if(!src.w_uniform)
|
||||
src.w_uniform = W
|
||||
equipped = 1
|
||||
if(slot_l_store)
|
||||
if(!src.l_store && src.w_uniform)
|
||||
src.l_store = W
|
||||
equipped = 1
|
||||
if(slot_r_store)
|
||||
if(!src.r_store && src.w_uniform)
|
||||
src.r_store = W
|
||||
equipped = 1
|
||||
if(slot_s_store)
|
||||
if(!src.s_store && src.wear_suit)
|
||||
src.s_store = W
|
||||
equipped = 1
|
||||
if(slot_in_backpack)
|
||||
if (src.back && istype(src.back, /obj/item/weapon/storage/backpack))
|
||||
var/obj/item/weapon/storage/backpack/B = src.back
|
||||
if(B.contents.len < B.storage_slots && W.w_class <= B.max_w_class)
|
||||
W.loc = B
|
||||
equipped = 1
|
||||
|
||||
if(equipped)
|
||||
W.layer = 20
|
||||
if(src.back && W.loc != src.back)
|
||||
W.loc = src
|
||||
else
|
||||
if (del_on_fail)
|
||||
del(W)
|
||||
return equipped
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
var/mob/living/carbon/M = other
|
||||
if(!istype(M))
|
||||
return 1
|
||||
if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs)
|
||||
if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
/mob/living/carbon/alien/larva/New()
|
||||
..()
|
||||
add_language("Xenomorph") //Bonus language.
|
||||
internal_organs += new /datum/organ/internal/xenos/hivenode(src)
|
||||
internal_organs |= new /obj/item/organ/xenos/hivenode(src)
|
||||
@@ -10,11 +10,6 @@
|
||||
throw_range = 5
|
||||
origin_tech = "biotech=3"
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
prosthetic_name = "cyberbrain"
|
||||
prosthetic_icon = "brain-prosthetic"
|
||||
organ_tag = "brain"
|
||||
organ_type = /datum/organ/internal/brain
|
||||
|
||||
var/mob/living/carbon/brain/brainmob = null
|
||||
|
||||
/obj/item/organ/brain/xeno
|
||||
@@ -49,19 +44,18 @@
|
||||
else
|
||||
user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.."
|
||||
|
||||
/obj/item/organ/brain/removed(var/mob/living/target,var/mob/living/user)
|
||||
/obj/item/organ/brain/removed(var/mob/living/user)
|
||||
|
||||
..()
|
||||
|
||||
var/mob/living/simple_animal/borer/borer = target.has_brain_worms()
|
||||
var/mob/living/simple_animal/borer/borer = owner.has_brain_worms()
|
||||
|
||||
if(borer)
|
||||
borer.detatch() //Should remove borer if the brain is removed - RR
|
||||
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/brain/B = src
|
||||
if(istype(B) && istype(H))
|
||||
B.transfer_identity(target)
|
||||
if(istype(B) && istype(owner))
|
||||
B.transfer_identity(owner)
|
||||
|
||||
/obj/item/organ/brain/replaced(var/mob/living/target)
|
||||
|
||||
@@ -78,8 +72,6 @@
|
||||
/obj/item/organ/brain/slime
|
||||
name = "slime core"
|
||||
desc = "A complex, organic knot of jelly and crystalline particles."
|
||||
prosthetic_name = null
|
||||
prosthetic_icon = null
|
||||
robotic = 2
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "green slime extract"
|
||||
@@ -87,8 +79,6 @@
|
||||
/obj/item/organ/brain/golem
|
||||
name = "chem"
|
||||
desc = "A tightly furled roll of paper, covered with indecipherable runes."
|
||||
prosthetic_name = null
|
||||
prosthetic_icon = null
|
||||
robotic = 2
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll"
|
||||
@@ -32,8 +32,8 @@
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/organ = H.get_organ("chest")
|
||||
if (istype(organ, /datum/organ/external))
|
||||
var/datum/organ/external/temp = organ
|
||||
if (istype(organ, /obj/item/organ/external))
|
||||
var/obj/item/organ/external/temp = organ
|
||||
if(temp.take_damage(d, 0))
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
@@ -60,12 +60,13 @@
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/M as mob)
|
||||
if(!istype(M, /mob/living/carbon)) return
|
||||
if (hasorgans(M))
|
||||
var/datum/organ/external/temp = M:organs_by_name["r_hand"]
|
||||
if (M.hand)
|
||||
temp = M:organs_by_name["l_hand"]
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
if (H.hand)
|
||||
temp = H.organs_by_name["l_hand"]
|
||||
if(temp && !temp.is_usable())
|
||||
M << "\red You can't use your [temp.display_name]"
|
||||
H << "\red You can't use your [temp.name]"
|
||||
return
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
@@ -155,7 +156,7 @@
|
||||
"\blue You check yourself for injuries." \
|
||||
)
|
||||
|
||||
for(var/datum/organ/external/org in H.organs)
|
||||
for(var/obj/item/organ/external/org in H.organs)
|
||||
var/status = ""
|
||||
var/brutedamage = org.brute_dam
|
||||
var/burndamage = org.burn_dam
|
||||
@@ -186,7 +187,7 @@
|
||||
status = "weirdly shapen."
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.display_name,status),1)
|
||||
src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.name,status),1)
|
||||
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
||||
H.play_xylophone()
|
||||
else if (on_fire)
|
||||
@@ -327,16 +328,9 @@
|
||||
|
||||
if(!item) return //Grab processing has a chance of returning null
|
||||
|
||||
item.layer = initial(item.layer)
|
||||
u_equip(item)
|
||||
update_icons()
|
||||
|
||||
if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required.
|
||||
item.loc = src.loc
|
||||
if(src.client)
|
||||
src.client.screen -= item
|
||||
if(istype(item, /obj/item))
|
||||
item:dropped(src) // let it know it's been dropped
|
||||
|
||||
src.remove_from_mob(item)
|
||||
item.loc = src.loc
|
||||
|
||||
//actually throw it!
|
||||
if (item)
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
g_eyes = green
|
||||
b_eyes = blue
|
||||
|
||||
update_eyes()
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
/mob/living/carbon/human/gib()
|
||||
|
||||
for(var/datum/organ/internal/I in internal_organs)
|
||||
var/obj/item/organ/current_organ = I.remove()
|
||||
if(current_organ)
|
||||
if(istype(loc,/turf))
|
||||
current_organ.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
current_organ.removed(src)
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.removed()
|
||||
if(istype(loc,/turf))
|
||||
I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
|
||||
|
||||
for(var/datum/organ/external/E in src.organs)
|
||||
if(istype(E, /datum/organ/external/chest))
|
||||
continue
|
||||
// Only make the limb drop if it's not too damaged
|
||||
if(prob(100 - E.get_damage()))
|
||||
// Override the current limb status and don't cause an explosion
|
||||
E.droplimb(1,1)
|
||||
for(var/obj/item/organ/external/E in src.organs)
|
||||
E.droplimb(0,DROPLIMB_EDGE,1)
|
||||
|
||||
sleep(1)
|
||||
|
||||
..(species.gibbed_anim)
|
||||
gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color)
|
||||
@@ -38,7 +33,7 @@
|
||||
if(species) species.handle_death(src)
|
||||
|
||||
//Handle brain slugs.
|
||||
var/datum/organ/external/head = get_organ("head")
|
||||
var/obj/item/organ/external/head = get_organ("head")
|
||||
var/mob/living/simple_animal/borer/B
|
||||
|
||||
for(var/I in head.implants)
|
||||
|
||||
@@ -198,9 +198,9 @@
|
||||
|
||||
//splints
|
||||
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
|
||||
var/datum/organ/external/o = get_organ(organ)
|
||||
var/obj/item/organ/external/o = get_organ(organ)
|
||||
if(o && o.status & ORGAN_SPLINTED)
|
||||
msg += "<span class='warning'>[t_He] [t_has] a splint on [t_his] [o.display_name]!</span>\n"
|
||||
msg += "<span class='warning'>[t_He] [t_has] a splint on [t_his] [o.name]!</span>\n"
|
||||
|
||||
if(suiciding)
|
||||
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
@@ -251,33 +251,44 @@
|
||||
var/list/wound_flavor_text = list()
|
||||
var/list/is_destroyed = list()
|
||||
var/list/is_bleeding = list()
|
||||
for(var/datum/organ/external/temp in organs)
|
||||
|
||||
for(var/organ_tag in species.has_limbs)
|
||||
|
||||
var/list/organ_data = species.has_limbs[organ_tag]
|
||||
var/organ_descriptor = organ_data["descriptor"]
|
||||
is_destroyed["[organ_data["descriptor"]]"] = 1
|
||||
|
||||
var/obj/item/organ/external/E = organs_by_name[organ_tag]
|
||||
if(!E)
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] is missing [t_his] [organ_descriptor].</b></span>\n"
|
||||
else if(E.is_stump())
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] has a stump where [t_his] [organ_descriptor] should be.</b></span>\n"
|
||||
else
|
||||
continue
|
||||
|
||||
for(var/obj/item/organ/external/temp in organs)
|
||||
if(temp)
|
||||
if(temp.status & ORGAN_DESTROYED)
|
||||
is_destroyed["[temp.display_name]"] = 1
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'><b>[t_He] is missing [t_his] [temp.display_name].</b></span>\n"
|
||||
continue
|
||||
if(temp.status & ORGAN_ROBOT)
|
||||
if(!(temp.brute_dam + temp.burn_dam))
|
||||
if(!species.flags & IS_SYNTHETIC)
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]!</span>\n"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]!</span>\n"
|
||||
continue
|
||||
else
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]. It has"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]. It has"
|
||||
if(temp.brute_dam) switch(temp.brute_dam)
|
||||
if(0 to 20)
|
||||
wound_flavor_text["[temp.display_name]"] += " some dents"
|
||||
wound_flavor_text["[temp.name]"] += " some dents"
|
||||
if(21 to INFINITY)
|
||||
wound_flavor_text["[temp.display_name]"] += pick(" a lot of dents"," severe denting")
|
||||
wound_flavor_text["[temp.name]"] += pick(" a lot of dents"," severe denting")
|
||||
if(temp.brute_dam && temp.burn_dam)
|
||||
wound_flavor_text["[temp.display_name]"] += " and"
|
||||
wound_flavor_text["[temp.name]"] += " and"
|
||||
if(temp.burn_dam) switch(temp.burn_dam)
|
||||
if(0 to 20)
|
||||
wound_flavor_text["[temp.display_name]"] += " some burns"
|
||||
wound_flavor_text["[temp.name]"] += " some burns"
|
||||
if(21 to INFINITY)
|
||||
wound_flavor_text["[temp.display_name]"] += pick(" a lot of burns"," severe melting")
|
||||
if(wound_flavor_text["[temp.display_name]"])
|
||||
wound_flavor_text["[temp.display_name]"] += "!</span>\n"
|
||||
wound_flavor_text["[temp.name]"] += pick(" a lot of burns"," severe melting")
|
||||
if(wound_flavor_text["[temp.name]"])
|
||||
wound_flavor_text["[temp.name]"] += "!</span>\n"
|
||||
else if(temp.wounds.len > 0)
|
||||
var/list/wound_descriptors = list()
|
||||
for(var/datum/wound/W in temp.wounds)
|
||||
@@ -325,14 +336,14 @@
|
||||
else if(flavor_text.len > 1 && text > 1)
|
||||
flavor_text_string += ","
|
||||
flavor_text_string += flavor_text[text]
|
||||
flavor_text_string += " on [t_his] [temp.display_name].</span><br>"
|
||||
wound_flavor_text["[temp.display_name]"] = flavor_text_string
|
||||
flavor_text_string += " on [t_his] [temp.name].</span><br>"
|
||||
wound_flavor_text["[temp.name]"] = flavor_text_string
|
||||
else
|
||||
wound_flavor_text["[temp.display_name]"] = ""
|
||||
wound_flavor_text["[temp.name]"] = ""
|
||||
if(temp.status & ORGAN_BLEEDING)
|
||||
is_bleeding["[temp.display_name]"] = 1
|
||||
is_bleeding["[temp.name]"] = 1
|
||||
else
|
||||
wound_flavor_text["[temp.display_name]"] = ""
|
||||
wound_flavor_text["[temp.name]"] = ""
|
||||
|
||||
//Handles the text strings being added to the actual description.
|
||||
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
stat("Tank Pressure", internal.air_contents.return_pressure())
|
||||
stat("Distribution Pressure", internal.distribute_pressure)
|
||||
|
||||
var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
|
||||
var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
|
||||
if(P)
|
||||
stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
var/update = 0
|
||||
|
||||
// focus most of the blast on one organ
|
||||
var/datum/organ/external/take_blast = pick(organs)
|
||||
var/obj/item/organ/external/take_blast = pick(organs)
|
||||
update |= take_blast.take_damage(b_loss * 0.9, f_loss * 0.9, used_weapon = "Explosive blast")
|
||||
|
||||
// distribute the remaining 10% on all limbs equally
|
||||
@@ -138,7 +138,7 @@
|
||||
|
||||
var/weapon_message = "Explosive Blast"
|
||||
|
||||
for(var/datum/organ/external/temp in organs)
|
||||
for(var/obj/item/organ/external/temp in organs)
|
||||
switch(temp.name)
|
||||
if("head")
|
||||
update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message)
|
||||
@@ -167,7 +167,7 @@
|
||||
if(stat == 2) return
|
||||
show_message("\red The blob attacks you!")
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
|
||||
apply_damage(rand(30,40), BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
return
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red [src] has been hit by [O]", 1)
|
||||
if (health > 0)
|
||||
var/datum/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head"))
|
||||
var/obj/item/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head"))
|
||||
if(!affecting) return
|
||||
if (istype(O, /obj/effect/immovablerod))
|
||||
if(affecting.take_damage(101, 0))
|
||||
@@ -193,7 +193,7 @@
|
||||
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)
|
||||
L.imp_in = M
|
||||
L.implanted = 1
|
||||
var/datum/organ/external/affected = M.organs_by_name["head"]
|
||||
var/obj/item/organ/external/affected = M.organs_by_name["head"]
|
||||
affected.implants += L
|
||||
L.part = affected
|
||||
L.implanted(src)
|
||||
@@ -201,7 +201,7 @@
|
||||
/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
|
||||
for(var/L in M.contents)
|
||||
if(istype(L, /obj/item/weapon/implant/loyalty))
|
||||
for(var/datum/organ/external/O in M.organs)
|
||||
for(var/obj/item/organ/external/O in M.organs)
|
||||
if(L in O.implants)
|
||||
return 1
|
||||
return 0
|
||||
@@ -326,7 +326,7 @@
|
||||
|
||||
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
|
||||
/mob/living/carbon/human/proc/get_face_name()
|
||||
var/datum/organ/external/head/head = get_organ("head")
|
||||
var/obj/item/organ/external/head/head = get_organ("head")
|
||||
if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
|
||||
return "Unknown"
|
||||
return real_name
|
||||
@@ -357,7 +357,7 @@
|
||||
if (!def_zone)
|
||||
def_zone = pick("l_hand", "r_hand")
|
||||
|
||||
var/datum/organ/external/affected_organ = get_organ(check_zone(def_zone))
|
||||
var/obj/item/organ/external/affected_organ = get_organ(check_zone(def_zone))
|
||||
var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ)
|
||||
|
||||
return ..(shock_damage, source, siemens_coeff, def_zone)
|
||||
@@ -677,7 +677,7 @@
|
||||
return 2
|
||||
|
||||
if(internal_organs_by_name["eyes"]) // Eyes are fucked, not a 'weak point'.
|
||||
var/datum/organ/internal/I = internal_organs_by_name["eyes"]
|
||||
var/obj/item/organ/I = internal_organs_by_name["eyes"]
|
||||
if(I.status & ORGAN_CUT_AWAY)
|
||||
return 2
|
||||
else
|
||||
@@ -795,6 +795,7 @@
|
||||
r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
update_eyes()
|
||||
|
||||
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-s_tone]") as text
|
||||
|
||||
@@ -922,19 +923,16 @@
|
||||
germ_level += n
|
||||
|
||||
/mob/living/carbon/human/revive()
|
||||
for (var/datum/organ/external/O in organs)
|
||||
for (var/obj/item/organ/external/O in organs)
|
||||
O.status &= ~ORGAN_BROKEN
|
||||
O.status &= ~ORGAN_BLEEDING
|
||||
O.status &= ~ORGAN_SPLINTED
|
||||
O.status &= ~ORGAN_CUT_AWAY
|
||||
O.status &= ~ORGAN_ATTACHABLE
|
||||
if (!O.amputated)
|
||||
O.status &= ~ORGAN_DESTROYED
|
||||
O.destspawn = 0
|
||||
O.wounds.Cut()
|
||||
O.heal_damage(1000,1000,1,1)
|
||||
|
||||
var/datum/organ/external/head/h = organs_by_name["head"]
|
||||
var/obj/item/organ/external/head/h = organs_by_name["head"]
|
||||
h.disfigured = 0
|
||||
|
||||
if(species && !(species.flags & NO_BLOOD))
|
||||
@@ -953,7 +951,7 @@
|
||||
H.brainmob.mind.transfer_to(src)
|
||||
del(H)
|
||||
|
||||
for(var/datum/organ/internal/I in internal_organs)
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.damage = 0
|
||||
|
||||
for (var/datum/disease/virus in viruses)
|
||||
@@ -968,11 +966,11 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/is_lung_ruptured()
|
||||
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
|
||||
var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"]
|
||||
return L && L.is_bruised()
|
||||
|
||||
/mob/living/carbon/human/proc/rupture_lung()
|
||||
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
|
||||
var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"]
|
||||
|
||||
if(L && !L.is_bruised())
|
||||
src.custom_pain("You feel a stabbing pain in your chest!", 1)
|
||||
@@ -1033,7 +1031,7 @@
|
||||
/mob/living/carbon/human/get_visible_implants(var/class = 0)
|
||||
|
||||
var/list/visible_implants = list()
|
||||
for(var/datum/organ/external/organ in src.organs)
|
||||
for(var/obj/item/organ/external/organ in src.organs)
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
if(!istype(O,/obj/item/weapon/implant) && (O.w_class > class) && !istype(O,/obj/item/weapon/shard/shrapnel))
|
||||
visible_implants += O
|
||||
@@ -1042,7 +1040,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/handle_embedded_objects()
|
||||
|
||||
for(var/datum/organ/external/organ in src.organs)
|
||||
for(var/obj/item/organ/external/organ in src.organs)
|
||||
if(organ.status & ORGAN_SPLINTED) //Splints prevent movement.
|
||||
continue
|
||||
for(var/obj/item/weapon/O in organ.implants)
|
||||
@@ -1051,11 +1049,11 @@
|
||||
var/msg = null
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
msg ="<span class='warning'>A spike of pain jolts your [organ.display_name] as you bump [O] inside.</span>"
|
||||
msg ="<span class='warning'>A spike of pain jolts your [organ.name] as you bump [O] inside.</span>"
|
||||
if(2)
|
||||
msg ="<span class='warning'>Your movement jostles [O] in your [organ.display_name] painfully.</span>"
|
||||
msg ="<span class='warning'>Your movement jostles [O] in your [organ.name] painfully.</span>"
|
||||
if(3)
|
||||
msg ="<span class='warning'>[O] in your [organ.display_name] twists painfully as you move.</span>"
|
||||
msg ="<span class='warning'>[O] in your [organ.name] twists painfully as you move.</span>"
|
||||
src << msg
|
||||
|
||||
organ.take_damage(rand(1,3), 0, 0)
|
||||
@@ -1292,14 +1290,14 @@
|
||||
|
||||
/mob/living/carbon/human/has_brain()
|
||||
if(internal_organs_by_name["brain"])
|
||||
var/datum/organ/internal/brain = internal_organs_by_name["brain"]
|
||||
var/obj/item/organ/brain = internal_organs_by_name["brain"]
|
||||
if(brain && istype(brain))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/has_eyes()
|
||||
if(internal_organs_by_name["eyes"])
|
||||
var/datum/organ/internal/eyes = internal_organs_by_name["eyes"]
|
||||
var/obj/item/organ/eyes = internal_organs_by_name["eyes"]
|
||||
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
|
||||
return 1
|
||||
return 0
|
||||
@@ -1308,3 +1306,58 @@
|
||||
if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP)))
|
||||
return 0
|
||||
..(slipped_on,stun_duration)
|
||||
|
||||
/mob/living/carbon/human/proc/undislocate()
|
||||
set category = "Object"
|
||||
set name = "Undislocate Joint"
|
||||
set desc = "Pop a joint back into place. Extremely painful."
|
||||
set src in view(1)
|
||||
|
||||
if(!isliving(usr) || usr.next_move > world.time)
|
||||
return
|
||||
usr.next_move = world.time + 20
|
||||
|
||||
if(usr.stat > 0)
|
||||
usr << "You are unconcious and cannot do that!"
|
||||
return
|
||||
|
||||
if(usr.restrained())
|
||||
usr << "You are restrained and cannot do that!"
|
||||
return
|
||||
|
||||
var/mob/S = src
|
||||
var/mob/U = usr
|
||||
var/self = null
|
||||
|
||||
if(S == U)
|
||||
self = 1 // Removing object from yourself.
|
||||
|
||||
var/list/limbs = list()
|
||||
for(var/limb in organs_by_name)
|
||||
var/obj/item/organ/external/current_limb = organs_by_name[limb]
|
||||
if(current_limb && current_limb.dislocated == 2)
|
||||
limbs |= limb
|
||||
|
||||
var/choice = input(src,"Which joint do you wish to relocate?") as null|anything in limbs
|
||||
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/current_limb = organs_by_name[choice]
|
||||
|
||||
if(self)
|
||||
src << "<span class='warning'>You brace yourself to relocate your [current_limb.joint]...</span>"
|
||||
else
|
||||
U << "<span class='warning'>You begin to relocate [S]'s [current_limb.joint]...</span>"
|
||||
|
||||
if(!do_after(U, 30))
|
||||
return
|
||||
if(!choice || !current_limb || !S || !U)
|
||||
return
|
||||
|
||||
if(self)
|
||||
src << "<span class='danger'>You pop your [current_limb.joint] back in!</span>"
|
||||
else
|
||||
U << "<span class='danger'>You pop [S]'s [current_limb.joint] back in!</span>"
|
||||
S << "<span class='danger'>[U] pops your [current_limb.joint] back in!</span>"
|
||||
current_limb.undislocate()
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H))
|
||||
var/datum/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
if(H.hand)
|
||||
temp = H.organs_by_name["l_hand"]
|
||||
if(temp && !temp.is_usable())
|
||||
H << "\red You can't use your [temp.display_name]."
|
||||
if(!temp || !temp.is_usable())
|
||||
H << "\red You can't use your hand."
|
||||
return
|
||||
|
||||
..()
|
||||
@@ -24,7 +24,7 @@
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("\red <B>[H] has attempted to punch [src]!</B>")
|
||||
return 0
|
||||
var/datum/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
|
||||
if(HULK in H.mutations)
|
||||
@@ -98,7 +98,11 @@
|
||||
var/block = 0
|
||||
var/accurate = 0
|
||||
var/hit_zone = H.zone_sel.selecting
|
||||
var/datum/organ/external/affecting = get_organ(hit_zone)
|
||||
var/obj/item/organ/external/affecting = get_organ(hit_zone)
|
||||
|
||||
if(!affecting || affecting.status & ORGAN_DESTROYED)
|
||||
M << "<span class='danger'>They are missing that limb!</span>"
|
||||
return
|
||||
|
||||
switch(src.a_intent)
|
||||
if(I_HELP)
|
||||
@@ -157,7 +161,7 @@
|
||||
miss_type = 1
|
||||
|
||||
if(!miss_type && block)
|
||||
attack_message = "[H] went for [src]'s [affecting.display_name] but was blocked!"
|
||||
attack_message = "[H] went for [src]'s [affecting.name] but was blocked!"
|
||||
miss_type = 2
|
||||
|
||||
// See what attack they use
|
||||
@@ -208,7 +212,7 @@
|
||||
|
||||
if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
|
||||
|
||||
if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/W = null
|
||||
@@ -291,8 +295,23 @@
|
||||
src.visible_message("<span class='danger'>[user] has [attack_message] [src]!</span>")
|
||||
|
||||
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
|
||||
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
updatehealth()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/attack_joint(var/obj/item/W, var/mob/living/user, var/def_zone)
|
||||
var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src)
|
||||
if(user == src) // Attacking yourself can't miss
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
return null
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
|
||||
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
|
||||
return null
|
||||
var/dislocation_str
|
||||
if(prob(W.force))
|
||||
dislocation_str = "[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")] with a grisly crunch!"
|
||||
organ.dislocate()
|
||||
return dislocation_str
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
health = maxHealth
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/datum/organ/external/O in organs) //hardcoded to streamline things a bit
|
||||
total_brute += O.brute_dam
|
||||
total_burn += O.burn_dam
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit
|
||||
total_brute += O.brute_dam
|
||||
total_burn += O.burn_dam
|
||||
|
||||
var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss())
|
||||
var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss())
|
||||
@@ -27,7 +27,7 @@
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
|
||||
if(species && species.has_organ["brain"])
|
||||
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
|
||||
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
|
||||
if(sponge)
|
||||
sponge.take_damage(amount)
|
||||
sponge.damage = min(max(brainloss, 0),(maxHealth*2))
|
||||
@@ -42,7 +42,7 @@
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
|
||||
if(species && species.has_organ["brain"])
|
||||
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
|
||||
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
|
||||
if(sponge)
|
||||
sponge.damage = min(max(amount, 0),(maxHealth*2))
|
||||
brainloss = sponge.damage
|
||||
@@ -56,7 +56,7 @@
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
|
||||
if(species && species.has_organ["brain"])
|
||||
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
|
||||
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
|
||||
if(sponge)
|
||||
brainloss = min(sponge.damage,maxHealth*2)
|
||||
else
|
||||
@@ -68,13 +68,13 @@
|
||||
//These procs fetch a cumulative total damage from all organs
|
||||
/mob/living/carbon/human/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/datum/organ/external/O in organs)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
amount += O.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/human/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/datum/organ/external/O in organs)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
amount += O.burn_dam
|
||||
return amount
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
amount = amount*species.brute_mod
|
||||
|
||||
if (organ_name in organs_by_name)
|
||||
var/datum/organ/external/O = get_organ(organ_name)
|
||||
var/obj/item/organ/external/O = get_organ(organ_name)
|
||||
|
||||
if(amount > 0)
|
||||
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
@@ -119,7 +119,7 @@
|
||||
amount = amount*species.burn_mod
|
||||
|
||||
if (organ_name in organs_by_name)
|
||||
var/datum/organ/external/O = get_organ(organ_name)
|
||||
var/obj/item/organ/external/O = get_organ(organ_name)
|
||||
|
||||
if(amount > 0)
|
||||
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
@@ -163,28 +163,28 @@
|
||||
var/mut_prob = min(80, getCloneLoss()+10)
|
||||
if (amount > 0)
|
||||
if (prob(mut_prob))
|
||||
var/list/datum/organ/external/candidates = list()
|
||||
for (var/datum/organ/external/O in organs)
|
||||
var/list/obj/item/organ/external/candidates = list()
|
||||
for (var/obj/item/organ/external/O in organs)
|
||||
if(!(O.status & ORGAN_MUTATED))
|
||||
candidates |= O
|
||||
if (candidates.len)
|
||||
var/datum/organ/external/O = pick(candidates)
|
||||
var/obj/item/organ/external/O = pick(candidates)
|
||||
O.mutate()
|
||||
src << "<span class = 'notice'>Something is not right with your [O.display_name]...</span>"
|
||||
src << "<span class = 'notice'>Something is not right with your [O.name]...</span>"
|
||||
return
|
||||
else
|
||||
if (prob(heal_prob))
|
||||
for (var/datum/organ/external/O in organs)
|
||||
for (var/obj/item/organ/external/O in organs)
|
||||
if (O.status & ORGAN_MUTATED)
|
||||
O.unmutate()
|
||||
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
|
||||
src << "<span class = 'notice'>Your [O.name] is shaped normally again.</span>"
|
||||
return
|
||||
|
||||
if (getCloneLoss() < 1)
|
||||
for (var/datum/organ/external/O in organs)
|
||||
for (var/obj/item/organ/external/O in organs)
|
||||
if (O.status & ORGAN_MUTATED)
|
||||
O.unmutate()
|
||||
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
|
||||
src << "<span class = 'notice'>Your [O.name] is shaped normally again.</span>"
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
|
||||
// Defined here solely to take species flags into account without having to recast at mob/living level.
|
||||
@@ -226,16 +226,16 @@
|
||||
|
||||
//Returns a list of damaged organs
|
||||
/mob/living/carbon/human/proc/get_damaged_organs(var/brute, var/burn)
|
||||
var/list/datum/organ/external/parts = list()
|
||||
for(var/datum/organ/external/O in organs)
|
||||
var/list/obj/item/organ/external/parts = list()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if((brute && O.brute_dam) || (burn && O.burn_dam))
|
||||
parts += O
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable organs
|
||||
/mob/living/carbon/human/proc/get_damageable_organs()
|
||||
var/list/datum/organ/external/parts = list()
|
||||
for(var/datum/organ/external/O in organs)
|
||||
var/list/obj/item/organ/external/parts = list()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.brute_dam + O.burn_dam < O.max_damage)
|
||||
parts += O
|
||||
return parts
|
||||
@@ -244,9 +244,9 @@
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/heal_organ_damage(var/brute, var/burn)
|
||||
var/list/datum/organ/external/parts = get_damaged_organs(brute,burn)
|
||||
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
|
||||
if(!parts.len) return
|
||||
var/datum/organ/external/picked = pick(parts)
|
||||
var/obj/item/organ/external/picked = pick(parts)
|
||||
if(picked.heal_damage(brute,burn))
|
||||
UpdateDamageIcon()
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
@@ -260,9 +260,9 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0)
|
||||
var/list/datum/organ/external/parts = get_damageable_organs()
|
||||
var/list/obj/item/organ/external/parts = get_damageable_organs()
|
||||
if(!parts.len) return
|
||||
var/datum/organ/external/picked = pick(parts)
|
||||
var/obj/item/organ/external/picked = pick(parts)
|
||||
if(picked.take_damage(brute,burn,sharp,edge))
|
||||
UpdateDamageIcon()
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
@@ -272,11 +272,11 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
|
||||
|
||||
//Heal MANY external organs, in random order
|
||||
/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn)
|
||||
var/list/datum/organ/external/parts = get_damaged_organs(brute,burn)
|
||||
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/datum/organ/external/picked = pick(parts)
|
||||
var/obj/item/organ/external/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
@@ -295,10 +295,10 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
|
||||
// damage MANY external organs, in random order
|
||||
/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null)
|
||||
if(status_flags & GODMODE) return //godmode
|
||||
var/list/datum/organ/external/parts = get_damageable_organs()
|
||||
var/list/obj/item/organ/external/parts = get_damageable_organs()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/datum/organ/external/picked = pick(parts)
|
||||
var/obj/item/organ/external/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
@@ -328,12 +328,12 @@ This function restores the subjects blood to max.
|
||||
This function restores all organs.
|
||||
*/
|
||||
/mob/living/carbon/human/restore_all_organs()
|
||||
for(var/datum/organ/external/current_organ in organs)
|
||||
for(var/obj/item/organ/external/current_organ in organs)
|
||||
current_organ.rejuvenate()
|
||||
|
||||
/mob/living/carbon/human/proc/HealDamage(zone, brute, burn)
|
||||
var/datum/organ/external/E = get_organ(zone)
|
||||
if(istype(E, /datum/organ/external))
|
||||
var/obj/item/organ/external/E = get_organ(zone)
|
||||
if(istype(E, /obj/item/organ/external))
|
||||
if (E.heal_damage(brute, burn))
|
||||
UpdateDamageIcon()
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
@@ -366,7 +366,7 @@ This function restores all organs.
|
||||
|
||||
if(blocked >= 2) return 0
|
||||
|
||||
var/datum/organ/external/organ = null
|
||||
var/obj/item/organ/external/organ = null
|
||||
if(isorgan(def_zone))
|
||||
organ = def_zone
|
||||
else
|
||||
|
||||
@@ -10,7 +10,9 @@ emp_act
|
||||
|
||||
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
|
||||
|
||||
var/datum/organ/external/organ = get_organ(check_zone(def_zone))
|
||||
var/obj/item/organ/external/organ = get_organ(check_zone(def_zone))
|
||||
if(!organ)
|
||||
return
|
||||
|
||||
//Shields
|
||||
if(check_shields(P.damage, "the [P.name]"))
|
||||
@@ -50,7 +52,7 @@ emp_act
|
||||
return (..(P , def_zone))
|
||||
|
||||
/mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone)
|
||||
var/datum/organ/external/affected = get_organ(check_zone(def_zone))
|
||||
var/obj/item/organ/external/affected = get_organ(check_zone(def_zone))
|
||||
var/siemens_coeff = get_siemens_coefficient_organ(affected)
|
||||
stun_amount *= siemens_coeff
|
||||
agony_amount *= siemens_coeff
|
||||
@@ -68,12 +70,12 @@ emp_act
|
||||
if(c_hand && (stun_amount || agony_amount > 10))
|
||||
msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect")
|
||||
|
||||
u_equip(c_hand)
|
||||
drop_from_inventory(c_hand)
|
||||
if (affected.status & ORGAN_ROBOT)
|
||||
emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!")
|
||||
emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!")
|
||||
else
|
||||
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
|
||||
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.display_name]!")
|
||||
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.name]!")
|
||||
|
||||
..(stun_amount, agony_amount, def_zone)
|
||||
|
||||
@@ -84,21 +86,23 @@ emp_act
|
||||
if(def_zone)
|
||||
if(isorgan(def_zone))
|
||||
return getarmor_organ(def_zone, type)
|
||||
var/datum/organ/external/affecting = get_organ(def_zone)
|
||||
return getarmor_organ(affecting, type)
|
||||
var/obj/item/organ/external/affecting = get_organ(def_zone)
|
||||
if(affecting)
|
||||
return getarmor_organ(affecting, type)
|
||||
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
|
||||
|
||||
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
|
||||
for(var/organ_name in organs_by_name)
|
||||
if (organ_name in organ_rel_size)
|
||||
var/datum/organ/external/organ = organs_by_name[organ_name]
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
total += weight
|
||||
var/obj/item/organ/external/organ = organs_by_name[organ_name]
|
||||
if(organ)
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
total += weight
|
||||
return (armorval/max(total, 1))
|
||||
|
||||
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
|
||||
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone)
|
||||
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone)
|
||||
if (!def_zone)
|
||||
return 1.0
|
||||
|
||||
@@ -112,14 +116,14 @@ emp_act
|
||||
return siemens_coefficient
|
||||
|
||||
//this proc returns the armour value for a particular external organ.
|
||||
/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type)
|
||||
if(!type) return 0
|
||||
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
|
||||
if(!type || !def_zone) return 0
|
||||
var/protection = 0
|
||||
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
|
||||
for(var/gear in protective_gear)
|
||||
if(gear && istype(gear ,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = gear
|
||||
if(C.body_parts_covered & def_zone.body_part)
|
||||
if(istype(C) && C.body_parts_covered & def_zone.body_part)
|
||||
protection += C.armor[type]
|
||||
return protection
|
||||
|
||||
@@ -167,10 +171,10 @@ emp_act
|
||||
for(var/obj/O in src)
|
||||
if(!O) continue
|
||||
O.emp_act(severity)
|
||||
for(var/datum/organ/external/O in organs)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.status & ORGAN_DESTROYED) continue
|
||||
O.emp_act(severity)
|
||||
for(var/datum/organ/internal/I in O.internal_organs)
|
||||
for(var/obj/item/organ/I in O.internal_organs)
|
||||
if(I.robotic == 0) continue
|
||||
I.emp_act(severity)
|
||||
..()
|
||||
@@ -186,17 +190,19 @@ emp_act
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
visible_message("\red <B>[user] misses [src] with \the [I]!")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
var/datum/organ/external/affecting = get_organ(target_zone)
|
||||
if (!affecting)
|
||||
return 0
|
||||
if(affecting.status & ORGAN_DESTROYED)
|
||||
user << "What [affecting.display_name]?"
|
||||
return 0
|
||||
var/hit_area = affecting.display_name
|
||||
var/obj/item/organ/external/affecting = get_organ(target_zone)
|
||||
|
||||
if((user != src) && check_shields(I.force, "the [I.name]"))
|
||||
if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump())
|
||||
user << "<span class='danger'>They are missing that limb!</span>"
|
||||
return
|
||||
|
||||
var/effective_force = I.force
|
||||
if(user.a_intent == "disarm") effective_force = round(I.force/2)
|
||||
var/hit_area = affecting.name
|
||||
|
||||
if((user != src) && check_shields(effective_force, "the [I.name]"))
|
||||
return 0
|
||||
|
||||
if(istype(I,/obj/item/weapon/card/emag))
|
||||
@@ -204,9 +210,9 @@ emp_act
|
||||
user << "\red That limb isn't robotic."
|
||||
return
|
||||
if(affecting.sabotaged)
|
||||
user << "\red [src]'s [affecting.display_name] is already sabotaged!"
|
||||
user << "\red [src]'s [affecting.name] is already sabotaged!"
|
||||
else
|
||||
user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties."
|
||||
user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.name] and short out the safeties."
|
||||
var/obj/item/weapon/card/emag/emag = I
|
||||
emag.uses--
|
||||
affecting.sabotaged = 1
|
||||
@@ -224,14 +230,14 @@ emp_act
|
||||
weapon_sharp = 0
|
||||
weapon_edge = 0
|
||||
|
||||
if(armor >= 2) return 0
|
||||
if(!I.force) return 0
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
if(armor >= 2) return 0
|
||||
if(!effective_force) return 0
|
||||
var/Iforce = effective_force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
|
||||
apply_damage(I.force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
|
||||
apply_damage(effective_force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
|
||||
|
||||
var/bloody = 0
|
||||
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2)))
|
||||
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (effective_force * 2)))
|
||||
I.add_blood(src) //Make the weapon bloody, not the person.
|
||||
// if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon
|
||||
// else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays
|
||||
@@ -246,36 +252,37 @@ emp_act
|
||||
H.bloody_body(src)
|
||||
H.bloody_hands(src)
|
||||
|
||||
switch(hit_area)
|
||||
if("head")//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(prob(I.force))
|
||||
apply_effect(20, PARALYZE, armor)
|
||||
visible_message("\red <B>[src] has been knocked unconscious!</B>")
|
||||
if(bloody)//Apply blood
|
||||
if(wear_mask)
|
||||
wear_mask.add_blood(src)
|
||||
update_inv_wear_mask(0)
|
||||
if(head)
|
||||
head.add_blood(src)
|
||||
update_inv_head(0)
|
||||
if(glasses && prob(33))
|
||||
glasses.add_blood(src)
|
||||
update_inv_glasses(0)
|
||||
if(!stat)
|
||||
switch(hit_area)
|
||||
if("head")//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(prob(effective_force))
|
||||
apply_effect(20, PARALYZE, armor)
|
||||
visible_message("\red <B>[src] has been knocked unconscious!</B>")
|
||||
if(bloody)//Apply blood
|
||||
if(wear_mask)
|
||||
wear_mask.add_blood(src)
|
||||
update_inv_wear_mask(0)
|
||||
if(head)
|
||||
head.add_blood(src)
|
||||
update_inv_head(0)
|
||||
if(glasses && prob(33))
|
||||
glasses.add_blood(src)
|
||||
update_inv_glasses(0)
|
||||
|
||||
if("chest")//Easier to score a stun but lasts less time
|
||||
if(prob((I.force + 10)))
|
||||
apply_effect(6, WEAKEN, armor)
|
||||
visible_message("\red <B>[src] has been knocked down!</B>")
|
||||
if("chest")//Easier to score a stun but lasts less time
|
||||
if(prob((effective_force + 10)))
|
||||
apply_effect(6, WEAKEN, armor)
|
||||
visible_message("\red <B>[src] has been knocked down!</B>")
|
||||
|
||||
if(bloody)
|
||||
bloody_body(src)
|
||||
if(bloody)
|
||||
bloody_body(src)
|
||||
|
||||
if(Iforce > 10 || Iforce >= 5 && prob(33))
|
||||
forcesay(hit_appends) //forcesay checks stat already
|
||||
|
||||
//Melee weapon embedded object code.
|
||||
if (I && I.damtype == BRUTE && !I.anchored && !I.is_robot_module())
|
||||
var/damage = I.force
|
||||
var/damage = effective_force
|
||||
if (armor)
|
||||
damage /= armor+1
|
||||
|
||||
@@ -327,8 +334,8 @@ emp_act
|
||||
if ((O.thrower != src) && check_shields(throw_damage, "[O]"))
|
||||
return
|
||||
|
||||
var/datum/organ/external/affecting = get_organ(zone)
|
||||
var/hit_area = affecting.display_name
|
||||
var/obj/item/organ/external/affecting = get_organ(zone)
|
||||
var/hit_area = affecting.name
|
||||
|
||||
src.visible_message("\red [src] has been hit in the [hit_area] by [O].")
|
||||
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here
|
||||
@@ -390,7 +397,7 @@ emp_act
|
||||
/mob/living/carbon/human/embed(var/obj/O, var/def_zone=null)
|
||||
if(!def_zone) ..()
|
||||
|
||||
var/datum/organ/external/affecting = get_organ(def_zone)
|
||||
var/obj/item/organ/external/affecting = get_organ(def_zone)
|
||||
if(affecting)
|
||||
affecting.embed(O)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
|
||||
for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm"))
|
||||
var/datum/organ/external/E = get_organ(organ_name)
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
tally += 4
|
||||
if(E.status & ORGAN_SPLINTED)
|
||||
@@ -40,7 +40,7 @@
|
||||
tally += shoes.slowdown
|
||||
|
||||
for(var/organ_name in list("l_foot","r_foot","l_leg","r_leg"))
|
||||
var/datum/organ/external/E = get_organ(organ_name)
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
tally += 4
|
||||
if(E.status & ORGAN_SPLINTED)
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/mob/living/carbon/human/proc/update_eyes()
|
||||
if(internal_organs_by_name["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"]
|
||||
eyes.eye_colour = list(r_eyes,g_eyes,b_eyes)
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/carbon/var/list/internal_organs = list()
|
||||
/mob/living/carbon/human/var/list/organs = list()
|
||||
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
|
||||
/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too
|
||||
|
||||
// Takes care of organ related updates, such as broken and missing limbs
|
||||
/mob/living/carbon/human/proc/handle_organs()
|
||||
|
||||
number_wounds = 0
|
||||
var/force_process = 0
|
||||
var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss()
|
||||
if(damage_this_tick > last_dam)
|
||||
force_process = 1
|
||||
last_dam = damage_this_tick
|
||||
if(force_process)
|
||||
bad_external_organs.Cut()
|
||||
for(var/obj/item/organ/external/Ex in organs)
|
||||
bad_external_organs |= Ex
|
||||
|
||||
//processing internal organs is pretty cheap, do that first.
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.process()
|
||||
|
||||
handle_stance()
|
||||
handle_grasp()
|
||||
|
||||
if(!force_process && !bad_external_organs.len)
|
||||
return
|
||||
|
||||
for(var/obj/item/organ/external/E in bad_external_organs)
|
||||
if(!E)
|
||||
continue
|
||||
if(!E.need_process())
|
||||
bad_external_organs -= E
|
||||
continue
|
||||
else
|
||||
E.process()
|
||||
number_wounds += E.number_wounds
|
||||
|
||||
if (!lying && world.time - l_move_time < 15)
|
||||
//Moving around with fractured ribs won't do you any good
|
||||
if (E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
|
||||
var/obj/item/organ/I = pick(E.internal_organs)
|
||||
custom_pain("You feel broken bones moving in your [E.name]!", 1)
|
||||
I.take_damage(rand(3,5))
|
||||
|
||||
//Moving makes open wounds get infected much faster
|
||||
if (E.wounds.len)
|
||||
for(var/datum/wound/W in E.wounds)
|
||||
if (W.infection_check())
|
||||
W.germ_level += 1
|
||||
|
||||
/mob/living/carbon/human/proc/handle_stance()
|
||||
// Don't need to process any of this if they aren't standing anyways
|
||||
// unless their stance is damaged, and we want to check if they should stay down
|
||||
if (!stance_damage && (lying || resting) && (life_tick % 4) == 0)
|
||||
return
|
||||
|
||||
stance_damage = 0
|
||||
|
||||
// Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid
|
||||
if (istype(buckled, /obj/structure/bed))
|
||||
return
|
||||
|
||||
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
|
||||
var/obj/item/organ/external/E = organs_by_name[limb_tag]
|
||||
if(!E)
|
||||
stance_damage += 2
|
||||
else if (E.status & ORGAN_DESTROYED)
|
||||
stance_damage += 2 // let it fail even if just foot&leg
|
||||
else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable())
|
||||
stance_damage += 1
|
||||
|
||||
// Canes and crutches help you stand (if the latter is ever added)
|
||||
// One cane mitigates a broken leg+foot, or a missing foot.
|
||||
// Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you.
|
||||
if (l_hand && istype(l_hand, /obj/item/weapon/cane))
|
||||
stance_damage -= 2
|
||||
if (r_hand && istype(r_hand, /obj/item/weapon/cane))
|
||||
stance_damage -= 2
|
||||
|
||||
// standing is poor
|
||||
if(stance_damage >= 4 || (stance_damage >= 2 && prob(5)))
|
||||
if(!(lying || resting))
|
||||
if(species && !(species.flags & NO_PAIN))
|
||||
emote("scream")
|
||||
custom_emote(1, "collapses!")
|
||||
Weaken(5) //can't emote while weakened, apparently.
|
||||
|
||||
/mob/living/carbon/human/proc/handle_grasp()
|
||||
|
||||
if(!l_hand && !r_hand)
|
||||
return
|
||||
|
||||
for (var/obj/item/organ/external/E in organs)
|
||||
if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED))
|
||||
continue
|
||||
|
||||
if(E.is_broken())
|
||||
if(E.body_part == HAND_LEFT)
|
||||
drop_from_inventory(l_hand)
|
||||
else
|
||||
drop_from_inventory(r_hand)
|
||||
|
||||
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
|
||||
emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
|
||||
|
||||
else if(E.is_malfunctioning())
|
||||
|
||||
if(E.body_part == HAND_LEFT)
|
||||
drop_from_inventory(l_hand)
|
||||
else
|
||||
drop_from_inventory(r_hand)
|
||||
|
||||
emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!")
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
spawn(10)
|
||||
del(spark_system)
|
||||
|
||||
//Handles chem traces
|
||||
/mob/living/carbon/human/proc/handle_trace_chems()
|
||||
//New are added for reagents to random organs.
|
||||
for(var/datum/reagent/A in reagents.reagent_list)
|
||||
var/obj/item/organ/O = pick(organs)
|
||||
O.trace_chemicals[A.name] = 100
|
||||
@@ -18,10 +18,6 @@
|
||||
h_style = "Short Vox Quills"
|
||||
..(new_loc, "Vox")
|
||||
|
||||
/mob/living/carbon/human/voxarmalis/New(var/new_loc)
|
||||
h_style = "Bald"
|
||||
..(new_loc, "Vox Armalis")
|
||||
|
||||
/mob/living/carbon/human/diona/New(var/new_loc)
|
||||
..(new_loc, "Diona")
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/has_organ(name)
|
||||
var/datum/organ/external/O = organs_by_name[name]
|
||||
var/obj/item/organ/external/O = organs_by_name[name]
|
||||
|
||||
return (O && !(O.status & ORGAN_DESTROYED) )
|
||||
|
||||
@@ -69,11 +69,11 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
if(slot_glasses)
|
||||
return has_organ("head")
|
||||
if(slot_gloves)
|
||||
return has_organ("l_hand") && has_organ("r_hand")
|
||||
return has_organ("l_hand") || has_organ("r_hand")
|
||||
if(slot_head)
|
||||
return has_organ("head")
|
||||
if(slot_shoes)
|
||||
return has_organ("r_foot") && has_organ("l_foot")
|
||||
return has_organ("r_foot") || has_organ("l_foot")
|
||||
if(slot_wear_suit)
|
||||
return has_organ("chest")
|
||||
if(slot_w_uniform)
|
||||
@@ -89,19 +89,13 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
if(slot_tie)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/u_equip(obj/item/W as obj)
|
||||
/mob/living/carbon/human/u_equip(obj/W as obj)
|
||||
if(!W) return 0
|
||||
|
||||
var/success
|
||||
|
||||
if (W == wear_suit)
|
||||
if(s_store)
|
||||
drop_from_inventory(s_store)
|
||||
if(W)
|
||||
success = 1
|
||||
wear_suit = null
|
||||
if(W.flags_inv & HIDESHOES)
|
||||
update_inv_shoes(0)
|
||||
update_inv_wear_suit()
|
||||
else if (W == w_uniform)
|
||||
if (r_store)
|
||||
@@ -113,43 +107,43 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
if (belt)
|
||||
drop_from_inventory(belt)
|
||||
w_uniform = null
|
||||
success = 1
|
||||
update_inv_w_uniform()
|
||||
else if (W == gloves)
|
||||
gloves = null
|
||||
success = 1
|
||||
update_inv_gloves()
|
||||
else if (W == glasses)
|
||||
glasses = null
|
||||
success = 1
|
||||
update_inv_glasses()
|
||||
else if (W == head)
|
||||
head = null
|
||||
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)|| (W.flags_inv & HIDEMASK))
|
||||
|
||||
var/update_hair = 0
|
||||
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
|
||||
update_hair = 1
|
||||
else if(istype(W, /obj/item))
|
||||
var/obj/item/I = W
|
||||
if(I.flags_inv & HIDEMASK)
|
||||
update_hair = 1
|
||||
if(update_hair)
|
||||
update_hair(0) //rebuild hair
|
||||
update_inv_ears(0)
|
||||
update_inv_wear_mask(0)
|
||||
success = 1
|
||||
|
||||
update_inv_head()
|
||||
else if (W == l_ear)
|
||||
l_ear = null
|
||||
success = 1
|
||||
update_inv_ears()
|
||||
else if (W == r_ear)
|
||||
r_ear = null
|
||||
success = 1
|
||||
update_inv_ears()
|
||||
else if (W == shoes)
|
||||
shoes = null
|
||||
success = 1
|
||||
update_inv_shoes()
|
||||
else if (W == belt)
|
||||
belt = null
|
||||
success = 1
|
||||
update_inv_belt()
|
||||
else if (W == wear_mask)
|
||||
wear_mask = null
|
||||
success = 1
|
||||
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
|
||||
update_hair(0) //rebuild hair
|
||||
update_inv_ears(0)
|
||||
@@ -160,53 +154,36 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
update_inv_wear_mask()
|
||||
else if (W == wear_id)
|
||||
wear_id = null
|
||||
success = 1
|
||||
update_inv_wear_id()
|
||||
else if (W == r_store)
|
||||
r_store = null
|
||||
success = 1
|
||||
update_inv_pockets()
|
||||
else if (W == l_store)
|
||||
l_store = null
|
||||
success = 1
|
||||
update_inv_pockets()
|
||||
else if (W == s_store)
|
||||
s_store = null
|
||||
success = 1
|
||||
update_inv_s_store()
|
||||
else if (W == back)
|
||||
back = null
|
||||
success = 1
|
||||
update_inv_back()
|
||||
else if (W == handcuffed)
|
||||
handcuffed = null
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_require_restraints)
|
||||
buckled.unbuckle_mob()
|
||||
success = 1
|
||||
buckled.unbuckle_mob()
|
||||
update_inv_handcuffed()
|
||||
else if (W == legcuffed)
|
||||
legcuffed = null
|
||||
success = 1
|
||||
update_inv_legcuffed()
|
||||
else if (W == r_hand)
|
||||
r_hand = null
|
||||
success = 1
|
||||
update_inv_r_hand()
|
||||
else if (W == l_hand)
|
||||
l_hand = null
|
||||
success = 1
|
||||
update_inv_l_hand()
|
||||
else
|
||||
return 0
|
||||
|
||||
if(success)
|
||||
if (W)
|
||||
if (client)
|
||||
client.screen -= W
|
||||
W.loc = loc
|
||||
W.dropped(src)
|
||||
//if(W)
|
||||
//W.layer = initial(W.layer)
|
||||
|
||||
update_action_buttons()
|
||||
return 1
|
||||
|
||||
@@ -319,7 +296,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
update_inv_s_store(redraw_mob)
|
||||
if(slot_in_backpack)
|
||||
if(src.get_active_hand() == W)
|
||||
src.u_equip(W)
|
||||
src.remove_from_mob(W)
|
||||
W.loc = src.back
|
||||
if(slot_tie)
|
||||
var/obj/item/clothing/under/uniform = src.w_uniform
|
||||
@@ -339,6 +316,10 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
|
||||
return
|
||||
|
||||
/*
|
||||
MouseDrop human inventory menu
|
||||
*/
|
||||
|
||||
/obj/effect/equip_e
|
||||
name = "equip e"
|
||||
var/mob/source = null
|
||||
@@ -407,7 +388,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
if("splints")
|
||||
var/count = 0
|
||||
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
|
||||
var/datum/organ/external/o = target.organs_by_name[organ]
|
||||
var/obj/item/organ/external/o = target.organs_by_name[organ]
|
||||
if(o.status & ORGAN_SPLINTED)
|
||||
count = 1
|
||||
break
|
||||
@@ -695,7 +676,7 @@ It can still be worn/put on as normal.
|
||||
|
||||
if(can_reach_splints)
|
||||
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
|
||||
var/datum/organ/external/o = target.get_organ(organ)
|
||||
var/obj/item/organ/external/o = target.get_organ(organ)
|
||||
if (o && o.status & ORGAN_SPLINTED)
|
||||
var/obj/item/W = new /obj/item/stack/medical/splint(amount=1)
|
||||
o.status &= ~ORGAN_SPLINTED
|
||||
@@ -771,15 +752,12 @@ It can still be worn/put on as normal.
|
||||
W.add_fingerprint(source)
|
||||
if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;)
|
||||
if(target.r_store)
|
||||
target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store.
|
||||
target.remove_from_mob(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store.
|
||||
else
|
||||
if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob
|
||||
if(item.mob_can_equip(target, slot_to_process, 0))
|
||||
source.u_equip(item)
|
||||
source.remove_from_mob(item)
|
||||
target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1)
|
||||
item.dropped(source)
|
||||
source.update_icons()
|
||||
target.update_icons()
|
||||
|
||||
if(source && target)
|
||||
if(source.machine == target)
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
src << "\red It becomes hard to see for some reason."
|
||||
eye_blurry = 10
|
||||
if(getBrainLoss() >= 35)
|
||||
if(7 <= rn && rn <= 9) if(hand && equipped())
|
||||
if(7 <= rn && rn <= 9) if(get_active_hand())
|
||||
src << "\red Your hand won't respond properly, you drop what you're holding."
|
||||
drop_item()
|
||||
if(getBrainLoss() >= 50)
|
||||
@@ -276,7 +276,7 @@
|
||||
radiation = Clamp(radiation,0,100)
|
||||
|
||||
if (radiation)
|
||||
var/datum/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
|
||||
var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs
|
||||
if(rad_organ && !rad_organ.is_broken())
|
||||
var/rads = radiation/25
|
||||
radiation -= rads
|
||||
@@ -323,7 +323,7 @@
|
||||
adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT)
|
||||
updatehealth()
|
||||
if(organs.len)
|
||||
var/datum/organ/external/O = pick(organs)
|
||||
var/obj/item/organ/external/O = pick(organs)
|
||||
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
|
||||
|
||||
/** breathing **/
|
||||
@@ -388,7 +388,7 @@
|
||||
|
||||
// Lung damage increases the minimum safe pressure.
|
||||
if(species.has_organ["lungs"])
|
||||
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
|
||||
var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"]
|
||||
if(!L)
|
||||
safe_pressure_min = INFINITY //No lungs, how are you breathing?
|
||||
else if(L.is_broken())
|
||||
@@ -871,7 +871,7 @@
|
||||
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
|
||||
var/datum/organ/internal/diona/node/light_organ = locate() in internal_organs
|
||||
var/obj/item/organ/diona/node/light_organ = locate() in internal_organs
|
||||
if(light_organ && !light_organ.is_broken())
|
||||
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
|
||||
if(isturf(loc)) //else, there's considered to be no light
|
||||
@@ -1503,7 +1503,7 @@
|
||||
if(pulse == PULSE_NONE || !species.has_organ["heart"])
|
||||
return
|
||||
|
||||
var/datum/organ/internal/heart/H = internal_organs_by_name["heart"]
|
||||
var/obj/item/organ/heart/H = internal_organs_by_name["heart"]
|
||||
|
||||
if(!H || H.robotic >=2 )
|
||||
return
|
||||
|
||||
@@ -42,56 +42,15 @@
|
||||
)
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"lungs" = /datum/organ/internal/lungs,
|
||||
"liver" = /datum/organ/internal/liver,
|
||||
"kidneys" = /datum/organ/internal/kidney,
|
||||
"brain" = /datum/organ/internal/brain,
|
||||
"eyes" = /datum/organ/internal/eyes,
|
||||
"stack" = /datum/organ/internal/stack/vox
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"lungs" = /obj/item/organ/lungs,
|
||||
"liver" = /obj/item/organ/liver,
|
||||
"kidneys" = /obj/item/organ/kidney,
|
||||
"brain" = /obj/item/organ/brain,
|
||||
"eyes" = /obj/item/organ/eyes,
|
||||
"stack" = /obj/item/organ/stack/vox
|
||||
)
|
||||
|
||||
/datum/species/vox/get_random_name(var/gender)
|
||||
var/datum/language/species_language = all_languages[default_language]
|
||||
return species_language.get_random_name(gender)
|
||||
|
||||
/datum/species/vox/armalis
|
||||
name = "Vox Armalis"
|
||||
name_plural = "Vox"
|
||||
icobase = 'icons/mob/human_races/r_armalis.dmi'
|
||||
deform = 'icons/mob/human_races/r_armalis.dmi'
|
||||
rarity_value = 10
|
||||
|
||||
warning_low_pressure = 50
|
||||
hazard_low_pressure = 0
|
||||
|
||||
cold_level_1 = 80
|
||||
cold_level_2 = 50
|
||||
cold_level_3 = 0
|
||||
|
||||
heat_level_1 = 2000
|
||||
heat_level_2 = 3000
|
||||
heat_level_3 = 4000
|
||||
|
||||
brute_mod = 0.2
|
||||
burn_mod = 0.2
|
||||
|
||||
eyes = "blank_eyes"
|
||||
breath_type = "nitrogen"
|
||||
poison_type = "oxygen"
|
||||
|
||||
flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR
|
||||
|
||||
blood_color = "#2299FC"
|
||||
flesh_color = "#808D11"
|
||||
|
||||
tail = "armalis_tail"
|
||||
icon_template = 'icons/mob/human_races/r_armalis.dmi'
|
||||
|
||||
reagent_tag = IS_VOX
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/leap,
|
||||
/mob/living/carbon/human/proc/gut,
|
||||
/mob/living/carbon/human/proc/commune
|
||||
)
|
||||
@@ -50,6 +50,7 @@
|
||||
// Death vars.
|
||||
var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human
|
||||
var/gibber_type = /obj/effect/gibspawner/human
|
||||
var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
var/remains_type = /obj/effect/decal/remains/xeno
|
||||
var/gibbed_anim = "gibbed-h"
|
||||
var/dusted_anim = "dust-h"
|
||||
@@ -106,13 +107,27 @@
|
||||
var/rarity_value = 1 // Relative rarity/collector value for this species.
|
||||
// Determines the organs that the species spawns with and
|
||||
var/list/has_organ = list( // which required-organ checks are conducted.
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"lungs" = /datum/organ/internal/lungs,
|
||||
"liver" = /datum/organ/internal/liver,
|
||||
"kidneys" = /datum/organ/internal/kidney,
|
||||
"brain" = /datum/organ/internal/brain,
|
||||
"appendix" = /datum/organ/internal/appendix,
|
||||
"eyes" = /datum/organ/internal/eyes
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"lungs" = /obj/item/organ/lungs,
|
||||
"liver" = /obj/item/organ/liver,
|
||||
"kidneys" = /obj/item/organ/kidney,
|
||||
"brain" = /obj/item/organ/brain,
|
||||
"appendix" = /obj/item/organ/appendix,
|
||||
"eyes" = /obj/item/organ/eyes
|
||||
)
|
||||
|
||||
var/list/has_limbs = list(
|
||||
"chest" = list("path" = /obj/item/organ/external/chest),
|
||||
"groin" = list("path" = /obj/item/organ/external/groin),
|
||||
"head" = list("path" = /obj/item/organ/external/head),
|
||||
"l_arm" = list("path" = /obj/item/organ/external/arm),
|
||||
"r_arm" = list("path" = /obj/item/organ/external/arm/right),
|
||||
"l_leg" = list("path" = /obj/item/organ/external/leg),
|
||||
"r_leg" = list("path" = /obj/item/organ/external/leg/right),
|
||||
"l_hand" = list("path" = /obj/item/organ/external/hand),
|
||||
"r_hand" = list("path" = /obj/item/organ/external/hand/right),
|
||||
"l_foot" = list("path" = /obj/item/organ/external/foot),
|
||||
"r_foot" = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
// Bump vars
|
||||
@@ -157,7 +172,10 @@
|
||||
|
||||
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
|
||||
|
||||
//Trying to work out why species changes aren't fixing organs properly.
|
||||
for(var/obj/item/organ/organ in H.contents)
|
||||
if((organ in H.organs) || (organ in H.internal_organs))
|
||||
del(organ)
|
||||
|
||||
if(H.organs) H.organs.Cut()
|
||||
if(H.internal_organs) H.internal_organs.Cut()
|
||||
if(H.organs_by_name) H.organs_by_name.Cut()
|
||||
@@ -168,35 +186,28 @@
|
||||
H.organs_by_name = list()
|
||||
H.internal_organs_by_name = list()
|
||||
|
||||
//This is a basic humanoid limb setup.
|
||||
H.organs_by_name["chest"] = new/datum/organ/external/chest()
|
||||
H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"])
|
||||
H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"])
|
||||
H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"])
|
||||
H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"])
|
||||
H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"])
|
||||
H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"])
|
||||
H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"])
|
||||
H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"])
|
||||
H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"])
|
||||
H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"])
|
||||
for(var/limb_type in has_limbs)
|
||||
var/list/organ_data = has_limbs[limb_type]
|
||||
var/limb_path = organ_data["path"]
|
||||
var/obj/item/organ/O = new limb_path(H)
|
||||
organ_data["descriptor"] = O.name
|
||||
|
||||
for(var/organ in has_organ)
|
||||
var/organ_type = has_organ[organ]
|
||||
H.internal_organs_by_name[organ] = new organ_type(H)
|
||||
H.internal_organs_by_name[organ] = new organ_type(H,1)
|
||||
|
||||
for(var/name in H.organs_by_name)
|
||||
H.organs += H.organs_by_name[name]
|
||||
H.organs |= H.organs_by_name[name]
|
||||
|
||||
for(var/datum/organ/external/O in H.organs)
|
||||
for(var/obj/item/organ/external/O in H.organs)
|
||||
O.owner = H
|
||||
|
||||
if(flags & IS_SYNTHETIC)
|
||||
for(var/datum/organ/external/E in H.organs)
|
||||
for(var/obj/item/organ/external/E in H.organs)
|
||||
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
|
||||
E.status |= ORGAN_ROBOT
|
||||
for(var/datum/organ/internal/I in H.internal_organs)
|
||||
I.mechanize()
|
||||
E.robotize()
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
I.robotize()
|
||||
|
||||
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
|
||||
|
||||
@@ -268,4 +279,4 @@
|
||||
|
||||
// Called in life() when the mob has no client.
|
||||
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/skill = user.skills["combat"]
|
||||
var/datum/organ/external/affecting = target.get_organ(zone)
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
|
||||
if(!skill) skill = 1
|
||||
attack_damage = Clamp(attack_damage, 1, 5)
|
||||
|
||||
if(target == user)
|
||||
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.display_name]!</span>")
|
||||
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.name]!</span>")
|
||||
return 0
|
||||
|
||||
switch(zone)
|
||||
@@ -47,9 +47,9 @@
|
||||
else
|
||||
// ----- BODY ----- //
|
||||
switch(attack_damage)
|
||||
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target]'s [affecting.display_name]!</span>")
|
||||
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!</span>")
|
||||
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.display_name]!</span>")
|
||||
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target]'s [affecting.name]!</span>")
|
||||
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.name]!</span>")
|
||||
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.name]!</span>")
|
||||
|
||||
/datum/unarmed_attack/claws/strong
|
||||
attack_verb = list("slashed")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
flesh_color = "#137E8F"
|
||||
|
||||
has_organ = list(
|
||||
"brain" = /datum/organ/internal/brain/golem
|
||||
"brain" = /obj/item/organ/brain/golem
|
||||
)
|
||||
|
||||
death_message = "becomes completely motionless..."
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
death_message = "rapidly loses cohesion, splattering across the ground..."
|
||||
|
||||
has_organ = list(
|
||||
"brain" = /datum/organ/internal/brain/slime
|
||||
"brain" = /obj/item/organ/brain/slime
|
||||
)
|
||||
|
||||
breath_type = null
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
rarity_value = 3
|
||||
hud_type = /datum/hud_data/diona
|
||||
siemens_coefficient = 0.3
|
||||
eyes = "blank_eyes"
|
||||
|
||||
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
|
||||
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
|
||||
@@ -145,12 +146,26 @@
|
||||
water and other radiation."
|
||||
|
||||
has_organ = list(
|
||||
"nutrient channel" = /datum/organ/internal/diona/nutrients,
|
||||
"neural strata" = /datum/organ/internal/diona/strata,
|
||||
"response node" = /datum/organ/internal/diona/node,
|
||||
"gas bladder" = /datum/organ/internal/diona/bladder,
|
||||
"polyp segment" = /datum/organ/internal/diona/polyp,
|
||||
"anchoring ligament" = /datum/organ/internal/diona/ligament
|
||||
"nutrient channel" = /obj/item/organ/diona/nutrients,
|
||||
"neural strata" = /obj/item/organ/diona/strata,
|
||||
"response node" = /obj/item/organ/diona/node,
|
||||
"gas bladder" = /obj/item/organ/diona/bladder,
|
||||
"polyp segment" = /obj/item/organ/diona/polyp,
|
||||
"anchoring ligament" = /obj/item/organ/diona/ligament
|
||||
)
|
||||
|
||||
has_limbs = list(
|
||||
"chest" = list("path" = /obj/item/organ/external/diona/chest),
|
||||
"groin" = list("path" = /obj/item/organ/external/diona/groin),
|
||||
"head" = list("path" = /obj/item/organ/external/diona/head),
|
||||
"l_arm" = list("path" = /obj/item/organ/external/diona/arm),
|
||||
"r_arm" = list("path" = /obj/item/organ/external/diona/arm/right),
|
||||
"l_leg" = list("path" = /obj/item/organ/external/diona/leg),
|
||||
"r_leg" = list("path" = /obj/item/organ/external/diona/leg/right),
|
||||
"l_hand" = list("path" = /obj/item/organ/external/diona/hand),
|
||||
"r_hand" = list("path" = /obj/item/organ/external/diona/hand/right),
|
||||
"l_foot" = list("path" = /obj/item/organ/external/diona/foot),
|
||||
"r_foot" = list("path" = /obj/item/organ/external/diona/foot/right)
|
||||
)
|
||||
|
||||
warning_low_pressure = 50
|
||||
@@ -166,7 +181,7 @@
|
||||
|
||||
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
|
||||
|
||||
flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR
|
||||
flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | REGENERATES_LIMBS
|
||||
|
||||
blood_color = "#004400"
|
||||
flesh_color = "#907E4A"
|
||||
|
||||
@@ -108,7 +108,7 @@ Des: Removes all infection images from aliens and places an infection image on a
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
@@ -130,7 +130,7 @@ Des: Checks if the passed mob (C) is infected with the alien egg, then gives eac
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
@@ -149,7 +149,7 @@ Des: Removes the alien infection image from all aliens in the world located in p
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
|
||||
@@ -108,7 +108,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs)
|
||||
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
|
||||
return
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs)
|
||||
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
|
||||
return 0
|
||||
|
||||
if(ishuman(C))
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/gain_plasma(var/amount)
|
||||
|
||||
var/datum/organ/internal/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"]
|
||||
var/obj/item/organ/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"]
|
||||
if(!istype(I)) return
|
||||
|
||||
if(amount)
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ)
|
||||
|
||||
var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
|
||||
var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
|
||||
if(!istype(P))
|
||||
src << "<span class='danger'>Your plasma vessel has been removed!</span>"
|
||||
return
|
||||
|
||||
if(needs_organ)
|
||||
var/datum/organ/internal/I = internal_organs_by_name[needs_organ]
|
||||
var/obj/item/organ/I = internal_organs_by_name[needs_organ]
|
||||
if(!I)
|
||||
src << "<span class='danger'>Your [needs_organ] has been removed!</span>"
|
||||
return
|
||||
@@ -62,7 +62,7 @@
|
||||
src << "<span class='alium'>You need to be closer.</span>"
|
||||
return
|
||||
|
||||
var/datum/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"]
|
||||
var/obj/item/organ/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"]
|
||||
if(!istype(I))
|
||||
src << "<span class='alium'>Their plasma vessel is missing.</span>"
|
||||
return
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
vision_flags = SEE_MOBS
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"brain" = /datum/organ/internal/brain/xeno,
|
||||
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel,
|
||||
"hive node" = /datum/organ/internal/xenos/hivenode,
|
||||
"nutrient vessel" = /datum/organ/internal/diona/nutrients
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
"plasma vessel" = /obj/item/organ/xenos/plasmavessel,
|
||||
"hive node" = /obj/item/organ/xenos/hivenode,
|
||||
"nutrient vessel" = /obj/item/organ/diona/nutrients
|
||||
)
|
||||
|
||||
bump_flag = ALIEN
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
|
||||
if(!regenerate(H))
|
||||
var/datum/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
|
||||
var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
|
||||
P.stored_plasma += weeds_plasma_rate
|
||||
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
|
||||
..()
|
||||
@@ -116,7 +116,7 @@
|
||||
return 1
|
||||
|
||||
//next internal organs
|
||||
for(var/datum/organ/internal/I in H.internal_organs)
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
if(I.damage > 0)
|
||||
I.damage = max(I.damage - heal_rate, 0)
|
||||
if (prob(5))
|
||||
@@ -124,11 +124,11 @@
|
||||
return 1
|
||||
|
||||
//next mend broken bones, approx 10 ticks each
|
||||
for(var/datum/organ/external/E in H.bad_external_organs)
|
||||
for(var/obj/item/organ/external/E in H.bad_external_organs)
|
||||
if (E.status & ORGAN_BROKEN)
|
||||
if (prob(mend_prob))
|
||||
if (E.mend_fracture())
|
||||
H << "<span class='alium'>You feel something mend itself inside your [E.display_name].</span>"
|
||||
H << "<span class='alium'>You feel something mend itself inside your [E.name].</span>"
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -153,13 +153,13 @@
|
||||
deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"brain" = /datum/organ/internal/brain/xeno,
|
||||
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
|
||||
"acid gland" = /datum/organ/internal/xenos/acidgland,
|
||||
"hive node" = /datum/organ/internal/xenos/hivenode,
|
||||
"resin spinner" = /datum/organ/internal/xenos/resinspinner,
|
||||
"nutrient vessel" = /datum/organ/internal/diona/nutrients
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
"plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen,
|
||||
"acid gland" = /obj/item/organ/xenos/acidgland,
|
||||
"hive node" = /obj/item/organ/xenos/hivenode,
|
||||
"resin spinner" = /obj/item/organ/xenos/resinspinner,
|
||||
"nutrient vessel" = /obj/item/organ/diona/nutrients
|
||||
)
|
||||
|
||||
inherent_verbs = list(
|
||||
@@ -192,11 +192,11 @@
|
||||
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"brain" = /datum/organ/internal/brain/xeno,
|
||||
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/hunter,
|
||||
"hive node" = /datum/organ/internal/xenos/hivenode,
|
||||
"nutrient vessel" = /datum/organ/internal/diona/nutrients
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
"plasma vessel" = /obj/item/organ/xenos/plasmavessel/hunter,
|
||||
"hive node" = /obj/item/organ/xenos/hivenode,
|
||||
"nutrient vessel" = /obj/item/organ/diona/nutrients
|
||||
)
|
||||
|
||||
inherent_verbs = list(
|
||||
@@ -220,12 +220,12 @@
|
||||
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"brain" = /datum/organ/internal/brain/xeno,
|
||||
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/sentinel,
|
||||
"acid gland" = /datum/organ/internal/xenos/acidgland,
|
||||
"hive node" = /datum/organ/internal/xenos/hivenode,
|
||||
"nutrient vessel" = /datum/organ/internal/diona/nutrients
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
"plasma vessel" = /obj/item/organ/xenos/plasmavessel/sentinel,
|
||||
"acid gland" = /obj/item/organ/xenos/acidgland,
|
||||
"hive node" = /obj/item/organ/xenos/hivenode,
|
||||
"nutrient vessel" = /obj/item/organ/diona/nutrients
|
||||
)
|
||||
|
||||
inherent_verbs = list(
|
||||
@@ -252,14 +252,14 @@
|
||||
deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
|
||||
|
||||
has_organ = list(
|
||||
"heart" = /datum/organ/internal/heart,
|
||||
"brain" = /datum/organ/internal/brain/xeno,
|
||||
"egg sac" = /datum/organ/internal/xenos/eggsac,
|
||||
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
|
||||
"acid gland" = /datum/organ/internal/xenos/acidgland,
|
||||
"hive node" = /datum/organ/internal/xenos/hivenode,
|
||||
"resin spinner" = /datum/organ/internal/xenos/resinspinner,
|
||||
"nutrient vessel" = /datum/organ/internal/diona/nutrients
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"brain" = /obj/item/organ/brain/xeno,
|
||||
"egg sac" = /obj/item/organ/xenos/eggsac,
|
||||
"plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen,
|
||||
"acid gland" = /obj/item/organ/xenos/acidgland,
|
||||
"hive node" = /obj/item/organ/xenos/hivenode,
|
||||
"resin spinner" = /obj/item/organ/xenos/resinspinner,
|
||||
"nutrient vessel" = /obj/item/organ/diona/nutrients
|
||||
)
|
||||
|
||||
inherent_verbs = list(
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
return 0
|
||||
|
||||
// Check if they have a functioning hand.
|
||||
var/datum/organ/external/E = user.organs_by_name["l_hand"]
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_hand"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
return 1
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
target.apply_effect(3, WEAKEN, armour)
|
||||
|
||||
/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/datum/organ/external/affecting = target.get_organ(zone)
|
||||
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.display_name]!</span>")
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
user.visible_message("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.name]!</span>")
|
||||
playsound(user.loc, attack_sound, 25, 1, -1)
|
||||
|
||||
/datum/unarmed_attack/bite
|
||||
@@ -100,8 +100,8 @@
|
||||
damage = 0
|
||||
|
||||
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/datum/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.display_name
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.name
|
||||
|
||||
attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case.
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin")))
|
||||
return 0
|
||||
|
||||
var/datum/organ/external/E = user.organs_by_name["l_foot"]
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
return 1
|
||||
|
||||
@@ -171,8 +171,8 @@
|
||||
return damage + (shoes ? shoes.force : 0)
|
||||
|
||||
/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/datum/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.display_name
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.name
|
||||
|
||||
attack_damage = Clamp(attack_damage, 1, 5)
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
if (!user.lying && (target.lying || (zone in list("l_foot", "r_foot"))))
|
||||
if(target.grabbed_by == user && target.lying)
|
||||
return 0
|
||||
var/datum/organ/external/E = user.organs_by_name["l_foot"]
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
return 1
|
||||
|
||||
@@ -213,8 +213,8 @@
|
||||
return damage + (shoes ? shoes.force : 0)
|
||||
|
||||
/datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/datum/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.display_name
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
var/organ = affecting.name
|
||||
var/obj/item/clothing/shoes = user.shoes
|
||||
|
||||
attack_damage = Clamp(attack_damage, 1, 5)
|
||||
|
||||
@@ -182,7 +182,9 @@ var/global/list/damage_icon_parts = list()
|
||||
// first check whether something actually changed about damage appearance
|
||||
var/damage_appearance = ""
|
||||
|
||||
for(var/datum/organ/external/O in organs)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.is_stump())
|
||||
continue
|
||||
if(O.status & ORGAN_DESTROYED) damage_appearance += "d"
|
||||
else
|
||||
damage_appearance += O.damage_state
|
||||
@@ -198,7 +200,9 @@ var/global/list/damage_icon_parts = list()
|
||||
var/image/standing_image = new /image("icon" = standing)
|
||||
|
||||
// blend the individual damage states with our icons
|
||||
for(var/datum/organ/external/O in organs)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.is_stump())
|
||||
continue
|
||||
if(!(O.status & ORGAN_DESTROYED))
|
||||
O.update_icon()
|
||||
if(O.damage_state == "00") continue
|
||||
@@ -223,7 +227,6 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
var/husk_color_mod = rgb(96,88,80)
|
||||
var/hulk_color_mod = rgb(48,224,40)
|
||||
var/necrosis_color_mod = rgb(10,50,0)
|
||||
|
||||
var/husk = (HUSK in src.mutations)
|
||||
var/fat = (FAT in src.mutations)
|
||||
@@ -231,7 +234,6 @@ var/global/list/damage_icon_parts = list()
|
||||
var/skeleton = (SKELETON in src.mutations)
|
||||
|
||||
var/g = (gender == FEMALE ? "f" : "m")
|
||||
var/has_head = 0
|
||||
|
||||
//CACHING: Generate an index key from visible bodyparts.
|
||||
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
|
||||
@@ -239,19 +241,14 @@ var/global/list/damage_icon_parts = list()
|
||||
//Create a new, blank icon for our mob to use.
|
||||
if(stand_icon)
|
||||
del(stand_icon)
|
||||
|
||||
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
|
||||
|
||||
var/icon_key = "[species.race_key][g][s_tone]"
|
||||
for(var/datum/organ/external/part in organs)
|
||||
|
||||
if(istype(part,/datum/organ/external/head) && !(part.status & ORGAN_DESTROYED))
|
||||
has_head = 1
|
||||
|
||||
if(part.status & ORGAN_DESTROYED)
|
||||
for(var/obj/item/organ/external/part in organs)
|
||||
if(part.is_stump() || (part.status & ORGAN_DESTROYED))
|
||||
icon_key = "[icon_key]0"
|
||||
else if(part.status & ORGAN_ROBOT)
|
||||
icon_key = "[icon_key]2"
|
||||
icon_key = "[icon_key]2[part.model ? "-[part.model]": ""]"
|
||||
else if(part.status & ORGAN_DEAD)
|
||||
icon_key = "[icon_key]3"
|
||||
else
|
||||
@@ -261,69 +258,31 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
var/icon/base_icon
|
||||
if(human_icon_cache[icon_key])
|
||||
//Icon is cached, use existing icon.
|
||||
base_icon = human_icon_cache[icon_key]
|
||||
|
||||
//log_debug("Retrieved cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src].")
|
||||
|
||||
else
|
||||
//BEGIN CACHED ICON GENERATION.
|
||||
var/obj/item/organ/external/chest = get_organ("chest")
|
||||
base_icon = chest.get_icon()
|
||||
|
||||
//BEGIN CACHED ICON GENERATION.
|
||||
var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
|
||||
var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
|
||||
|
||||
//Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs.
|
||||
//No icon stored, so we need to start with a basic one.
|
||||
var/datum/organ/external/chest = get_organ("chest")
|
||||
base_icon = chest.get_icon(race_icon,deform_icon,g)
|
||||
|
||||
if(chest.status & ORGAN_DEAD)
|
||||
base_icon.ColorTone(necrosis_color_mod)
|
||||
base_icon.SetIntensity(0.7)
|
||||
|
||||
for(var/datum/organ/external/part in organs)
|
||||
|
||||
var/icon/temp //Hold the bodypart icon for processing.
|
||||
|
||||
if(part.status & ORGAN_DESTROYED)
|
||||
continue
|
||||
|
||||
if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head))
|
||||
temp = part.get_icon(race_icon,deform_icon,g)
|
||||
else
|
||||
temp = part.get_icon(race_icon,deform_icon)
|
||||
|
||||
if(part.status & ORGAN_DEAD)
|
||||
temp.ColorTone(necrosis_color_mod)
|
||||
temp.SetIntensity(0.7)
|
||||
|
||||
for(var/obj/item/organ/external/part in organs)
|
||||
var/icon/temp = part.get_icon(skeleton)
|
||||
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
|
||||
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
|
||||
if(part.icon_position&(LEFT|RIGHT))
|
||||
|
||||
var/icon/temp2 = new('icons/mob/human.dmi',"blank")
|
||||
|
||||
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
|
||||
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
|
||||
|
||||
if(!(part.icon_position & LEFT))
|
||||
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
|
||||
|
||||
if(!(part.icon_position & RIGHT))
|
||||
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
|
||||
|
||||
base_icon.Blend(temp2, ICON_OVERLAY)
|
||||
|
||||
if(part.icon_position & LEFT)
|
||||
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
|
||||
|
||||
if(part.icon_position & RIGHT)
|
||||
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
|
||||
|
||||
base_icon.Blend(temp2, ICON_UNDERLAY)
|
||||
|
||||
else
|
||||
|
||||
base_icon.Blend(temp, ICON_OVERLAY)
|
||||
|
||||
if(!skeleton)
|
||||
@@ -334,46 +293,18 @@ var/global/list/damage_icon_parts = list()
|
||||
base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3]))
|
||||
|
||||
//Handle husk overlay.
|
||||
if(husk && ("overlay_husk" in icon_states(race_icon)))
|
||||
if(husk && ("overlay_husk" in icon_states(species.icobase)))
|
||||
var/icon/mask = new(base_icon)
|
||||
var/icon/husk_over = new(race_icon,"overlay_husk")
|
||||
var/icon/husk_over = new(species.icobase,"overlay_husk")
|
||||
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
|
||||
husk_over.Blend(mask, ICON_ADD)
|
||||
base_icon.Blend(husk_over, ICON_OVERLAY)
|
||||
|
||||
|
||||
//Skin tone.
|
||||
if(!husk && !hulk)
|
||||
if(species.flags & HAS_SKIN_TONE)
|
||||
if(s_tone >= 0)
|
||||
base_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
|
||||
else
|
||||
base_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
|
||||
|
||||
human_icon_cache[icon_key] = base_icon
|
||||
|
||||
//log_debug("Generated new cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src]. [human_icon_cache.len] cached mob icons.")
|
||||
|
||||
//END CACHED ICON GENERATION.
|
||||
|
||||
stand_icon.Blend(base_icon,ICON_OVERLAY)
|
||||
|
||||
//Skin colour. Not in cache because highly variable (and relatively benign).
|
||||
if (species.flags & HAS_SKIN_COLOR)
|
||||
stand_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
|
||||
|
||||
if(has_head)
|
||||
//Eyes
|
||||
if(!skeleton)
|
||||
var/icon/eyes = new/icon('icons/mob/human_face.dmi', species.eyes)
|
||||
if (species.flags & HAS_EYE_COLOR)
|
||||
eyes.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
|
||||
stand_icon.Blend(eyes, ICON_OVERLAY)
|
||||
|
||||
//Mouth (lipstick!)
|
||||
if(lip_style && (species && species.flags & HAS_LIPS)) //skeletons are allowed to wear lipstick no matter what you think, agouri.
|
||||
stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY)
|
||||
|
||||
//Underwear
|
||||
if(underwear && species.flags & HAS_UNDERWEAR)
|
||||
stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY)
|
||||
@@ -392,7 +323,7 @@ var/global/list/damage_icon_parts = list()
|
||||
//Reset our hair
|
||||
overlays_standing[HAIR_LAYER] = null
|
||||
|
||||
var/datum/organ/external/head/head_organ = get_organ("head")
|
||||
var/obj/item/organ/external/head/head_organ = get_organ("head")
|
||||
if( !head_organ || (head_organ.status & ORGAN_DESTROYED) )
|
||||
if(update_icons) update_icons()
|
||||
return
|
||||
@@ -763,13 +694,12 @@ var/global/list/damage_icon_parts = list()
|
||||
standing.overlays += bloodsies
|
||||
|
||||
overlays_standing[SUIT_LAYER] = standing
|
||||
|
||||
update_tail_showing(0)
|
||||
|
||||
else
|
||||
overlays_standing[SUIT_LAYER] = null
|
||||
|
||||
update_tail_showing(0)
|
||||
update_inv_shoes(0)
|
||||
|
||||
update_collar(0)
|
||||
|
||||
@@ -854,37 +784,47 @@ var/global/list/damage_icon_parts = list()
|
||||
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
|
||||
if(r_hand)
|
||||
r_hand.screen_loc = ui_rhand //TODO
|
||||
|
||||
var/t_icon = INV_R_HAND_DEF_ICON
|
||||
if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons))
|
||||
t_icon = r_hand.item_icons[icon_r_hand]
|
||||
|
||||
var/t_state = r_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand
|
||||
if(!t_state) t_state = r_hand.icon_state
|
||||
|
||||
if(r_hand.icon_override)
|
||||
t_state = "[t_state]_r"
|
||||
overlays_standing[R_HAND_LAYER] = image("icon" = r_hand.icon_override, "icon_state" = "[t_state]")
|
||||
else
|
||||
overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]")
|
||||
overlays_standing[R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]")
|
||||
|
||||
if (handcuffed) drop_r_hand()
|
||||
else
|
||||
overlays_standing[R_HAND_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
|
||||
if(l_hand)
|
||||
l_hand.screen_loc = ui_lhand //TODO
|
||||
|
||||
var/t_icon = INV_L_HAND_DEF_ICON
|
||||
if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons))
|
||||
t_icon = l_hand.item_icons[icon_l_hand]
|
||||
|
||||
var/t_state = l_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand
|
||||
if(!t_state) t_state = l_hand.icon_state
|
||||
|
||||
if(l_hand.icon_override)
|
||||
t_state = "[t_state]_l"
|
||||
overlays_standing[L_HAND_LAYER] = image("icon" = l_hand.icon_override, "icon_state" = "[t_state]")
|
||||
else
|
||||
overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]")
|
||||
overlays_standing[L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]")
|
||||
|
||||
if (handcuffed) drop_l_hand()
|
||||
else
|
||||
overlays_standing[L_HAND_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
|
||||
overlays_standing[TAIL_LAYER] = null
|
||||
@@ -925,48 +865,13 @@ var/global/list/damage_icon_parts = list()
|
||||
/mob/living/carbon/human/proc/update_surgery(var/update_icons=1)
|
||||
overlays_standing[SURGERY_LEVEL] = null
|
||||
var/image/total = new
|
||||
for(var/datum/organ/external/E in organs)
|
||||
for(var/obj/item/organ/external/E in organs)
|
||||
if(E.open)
|
||||
var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.name][round(E.open)]", "layer"=-SURGERY_LEVEL)
|
||||
total.overlays += I
|
||||
overlays_standing[SURGERY_LEVEL] = total
|
||||
if(update_icons) update_icons()
|
||||
|
||||
// Used mostly for creating head items
|
||||
/mob/living/carbon/human/proc/generate_head_icon()
|
||||
//gender no longer matters for the mouth, although there should probably be seperate base head icons.
|
||||
// var/g = "m"
|
||||
// if (gender == FEMALE) g = "f"
|
||||
|
||||
//base icons
|
||||
var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l")
|
||||
|
||||
if(f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
|
||||
if(facial_hair_style)
|
||||
var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
|
||||
facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
|
||||
face_lying.Blend(facial_l, ICON_OVERLAY)
|
||||
|
||||
if(h_style)
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
|
||||
if(hair_style)
|
||||
var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
|
||||
hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
|
||||
face_lying.Blend(hair_l, ICON_OVERLAY)
|
||||
|
||||
//Eyes
|
||||
// Note: These used to be in update_face(), and the fact they're here will make it difficult to create a disembodied head
|
||||
var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l")
|
||||
eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
|
||||
face_lying.Blend(eyes_l, ICON_OVERLAY)
|
||||
|
||||
if(lip_style)
|
||||
face_lying.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_l"), ICON_OVERLAY)
|
||||
|
||||
var/image/face_lying_image = new /image(icon = face_lying)
|
||||
return face_lying_image
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
#undef MUTATIONS_LAYER
|
||||
#undef DAMAGE_LAYER
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
//Monkey Overlays Indexes////////
|
||||
#define M_MASK_LAYER 1
|
||||
#define M_BACK_LAYER 2
|
||||
#define M_HANDCUFF_LAYER 3
|
||||
#define M_L_HAND_LAYER 4
|
||||
#define M_R_HAND_LAYER 5
|
||||
#define TARGETED_LAYER 6
|
||||
#define M_FIRE_LAYER 6
|
||||
#define M_TOTAL_LAYERS 7
|
||||
/////////////////////////////////
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
var/list/overlays_lying[M_TOTAL_LAYERS]
|
||||
var/list/overlays_standing[M_TOTAL_LAYERS]
|
||||
|
||||
/mob/living/carbon/monkey/regenerate_icons()
|
||||
..()
|
||||
update_inv_wear_mask(0)
|
||||
update_inv_back(0)
|
||||
update_inv_r_hand(0)
|
||||
update_inv_l_hand(0)
|
||||
update_inv_handcuffed(0)
|
||||
update_fire(0)
|
||||
update_icons()
|
||||
//Hud Stuff
|
||||
update_hud()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/update_icons()
|
||||
update_hud()
|
||||
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
|
||||
overlays.Cut()
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
if(lying)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(90)
|
||||
M.Translate(1,-6)
|
||||
src.transform = M
|
||||
else
|
||||
var/matrix/M = matrix()
|
||||
src.transform = M
|
||||
|
||||
|
||||
////////
|
||||
/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1)
|
||||
if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) )
|
||||
overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]")
|
||||
wear_mask.screen_loc = ui_monkey_mask
|
||||
else
|
||||
overlays_standing[M_MASK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1)
|
||||
if(r_hand)
|
||||
var/t_icon = INV_R_HAND_DEF_ICON
|
||||
if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons))
|
||||
t_icon = r_hand.item_icons[icon_r_hand]
|
||||
|
||||
var/t_state = r_hand.item_state
|
||||
if(!t_state) t_state = r_hand.icon_state
|
||||
|
||||
overlays_standing[M_R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state)
|
||||
r_hand.screen_loc = ui_rhand
|
||||
if (handcuffed) drop_r_hand()
|
||||
else
|
||||
overlays_standing[M_R_HAND_LAYER] = null
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1)
|
||||
if(l_hand)
|
||||
var/t_icon = INV_L_HAND_DEF_ICON
|
||||
if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons))
|
||||
t_icon = l_hand.item_icons[icon_l_hand]
|
||||
|
||||
var/t_state = l_hand.item_state
|
||||
if(!t_state) t_state = l_hand.icon_state
|
||||
|
||||
overlays_standing[M_L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state)
|
||||
l_hand.screen_loc = ui_lhand
|
||||
if (handcuffed) drop_l_hand()
|
||||
else
|
||||
overlays_standing[M_L_HAND_LAYER] = null
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_back(var/update_icons=1)
|
||||
if(back)
|
||||
overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
|
||||
back.screen_loc = ui_monkey_back
|
||||
else
|
||||
overlays_standing[M_BACK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_handcuffed(var/update_icons=1)
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
stop_pulling()
|
||||
overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1")
|
||||
else
|
||||
overlays_standing[M_HANDCUFF_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_hud()
|
||||
if (client)
|
||||
client.screen |= contents
|
||||
|
||||
//Call when target overlay should be added/removed
|
||||
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
|
||||
if (targeted_by && target_locked)
|
||||
overlays_standing[TARGETED_LAYER] = target_locked
|
||||
else if (!targeted_by && target_locked)
|
||||
del(target_locked)
|
||||
if (!targeted_by)
|
||||
overlays_standing[TARGETED_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/monkey/update_fire(var/update_icons=1)
|
||||
if(on_fire)
|
||||
overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER)
|
||||
else
|
||||
overlays_standing[M_FIRE_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
//Monkey Overlays Indexes////////
|
||||
#undef M_MASK_LAYER
|
||||
#undef M_BACK_LAYER
|
||||
#undef M_HANDCUFF_LAYER
|
||||
#undef M_L_HAND_LAYER
|
||||
#undef M_R_HAND_LAYER
|
||||
#undef TARGETED_LAYER
|
||||
#undef M_FIRE_LAYER
|
||||
#undef M_TOTAL_LAYERS
|
||||
|
||||
@@ -35,11 +35,9 @@
|
||||
// broken or ripped off organs will add quite a bit of pain
|
||||
if(istype(src,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = src
|
||||
for(var/datum/organ/external/organ in M.organs)
|
||||
for(var/obj/item/organ/external/organ in M.organs)
|
||||
if (!organ)
|
||||
continue
|
||||
if((organ.status & ORGAN_DESTROYED) && !organ.amputated)
|
||||
src.traumatic_shock += 60
|
||||
else if(organ.status & ORGAN_BROKEN || organ.open)
|
||||
src.traumatic_shock += 30
|
||||
if(organ.status & ORGAN_SPLINTED)
|
||||
|
||||
@@ -169,7 +169,7 @@ default behaviour is:
|
||||
var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part
|
||||
var/divided_damage = (burn_amount)/(H.organs.len)
|
||||
var/extradam = 0 //added to when organ is at max dam
|
||||
for(var/datum/organ/external/affecting in H.organs)
|
||||
for(var/obj/item/organ/external/affecting in H.organs)
|
||||
if(!affecting) continue
|
||||
if(affecting.take_damage(0, divided_damage+extradam)) //TODO: fix the extradam stuff. Or, ebtter yet...rewrite this entire proc ~Carn
|
||||
H.UpdateDamageIcon()
|
||||
@@ -339,7 +339,7 @@ default behaviour is:
|
||||
var/t = shooter:zone_sel.selecting
|
||||
if ((t in list( "eyes", "mouth" )))
|
||||
t = "head"
|
||||
var/datum/organ/external/def_zone = ran_zone(t)
|
||||
var/obj/item/organ/external/def_zone = ran_zone(t)
|
||||
return def_zone
|
||||
|
||||
|
||||
@@ -528,11 +528,11 @@ default behaviour is:
|
||||
//pull damage with injured people
|
||||
if(prob(25))
|
||||
M.adjustBruteLoss(1)
|
||||
visible_message("\red \The [M]'s wounds open more from being dragged!")
|
||||
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
|
||||
if(M.pull_damage())
|
||||
if(prob(25))
|
||||
M.adjustBruteLoss(2)
|
||||
visible_message("\red \The [M]'s wounds worsen terribly from being dragged!")
|
||||
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
|
||||
var/turf/location = M.loc
|
||||
if (istype(location, /turf/simulated))
|
||||
location.add_blood(M)
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
Stun(2)
|
||||
|
||||
//Being hit while using a deadman switch
|
||||
if(istype(equipped(),/obj/item/device/assembly/signaler))
|
||||
var/obj/item/device/assembly/signaler/signaler = equipped()
|
||||
if(istype(get_active_hand(),/obj/item/device/assembly/signaler))
|
||||
var/obj/item/device/assembly/signaler/signaler = get_active_hand()
|
||||
if(signaler.deadman && prob(80))
|
||||
src.visible_message("\red [src] triggers their deadman's switch!")
|
||||
signaler.signal()
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Electronics:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/organ/external/org in damaged)
|
||||
for(var/obj/item/organ/external/org in damaged)
|
||||
user.show_message(text("\blue \t []: [] - []", \
|
||||
capitalize(org.display_name), \
|
||||
capitalize(org.name), \
|
||||
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
|
||||
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
|
||||
else
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
if(istype(host,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = host
|
||||
var/datum/organ/external/head = H.get_organ("head")
|
||||
var/obj/item/organ/external/head = H.get_organ("head")
|
||||
head.implants -= src
|
||||
|
||||
controlling = 0
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
var/datum/organ/external/E = H.organs_by_name["head"]
|
||||
var/obj/item/organ/external/E = H.organs_by_name["head"]
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
src << "\The [H] does not have a head!"
|
||||
|
||||
@@ -115,12 +115,12 @@
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/I = H.internal_organs_by_name["brain"]
|
||||
var/obj/item/organ/I = H.internal_organs_by_name["brain"]
|
||||
if(!I) // No brain organ, so the borer moves in and replaces it permanently.
|
||||
replace_brain()
|
||||
else
|
||||
// If they're in normally, implant removal can get them out.
|
||||
var/datum/organ/external/head = H.get_organ("head")
|
||||
var/obj/item/organ/external/head = H.get_organ("head")
|
||||
head.implants += src
|
||||
|
||||
return
|
||||
@@ -183,11 +183,11 @@
|
||||
|
||||
H.ChangeToHusk()
|
||||
|
||||
var/datum/organ/internal/borer/B = new(H)
|
||||
var/obj/item/organ/borer/B = new(H)
|
||||
H.internal_organs_by_name["brain"] = B
|
||||
H.internal_organs |= B
|
||||
|
||||
var/datum/organ/external/affecting = H.get_organ("head")
|
||||
var/obj/item/organ/external/affecting = H.get_organ("head")
|
||||
affecting.implants -= src
|
||||
|
||||
var/s2h_id = src.computer_id
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
if(ishuman(target_mob))
|
||||
var/mob/living/carbon/human/H = target_mob
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
|
||||
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
|
||||
return H
|
||||
else if(isliving(target_mob))
|
||||
|
||||
@@ -475,7 +475,7 @@
|
||||
|
||||
if(ishuman(parrot_interest))
|
||||
var/mob/living/carbon/human/H = parrot_interest
|
||||
var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1)
|
||||
visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
|
||||
@@ -607,7 +607,7 @@
|
||||
stolen_item = C.r_hand
|
||||
|
||||
if(stolen_item)
|
||||
C.u_equip(stolen_item)
|
||||
C.remove_from_mob(stolen_item)
|
||||
held_item = stolen_item
|
||||
stolen_item.loc = src
|
||||
visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.")
|
||||
|
||||
+7
-76
@@ -117,77 +117,6 @@
|
||||
/mob/proc/restrained()
|
||||
return
|
||||
|
||||
//This proc is called whenever someone clicks an inventory ui slot.
|
||||
/mob/proc/attack_ui(slot)
|
||||
var/obj/item/W = get_active_hand()
|
||||
if(istype(W))
|
||||
equip_to_slot_if_possible(W, slot)
|
||||
|
||||
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
|
||||
if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
|
||||
return 1
|
||||
else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//This is a SAFE proc. Use this instead of equip_to_slot()!
|
||||
//set del_on_fail to have it delete W if it fails to equip
|
||||
//set disable_warning to disable the 'you are unable to equip that' warning.
|
||||
//unset redraw_mob to prevent the mob from being redrawn at the end.
|
||||
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
|
||||
if(!istype(W)) return 0
|
||||
|
||||
if(!W.mob_can_equip(src, slot))
|
||||
if(del_on_fail)
|
||||
del(W)
|
||||
else
|
||||
if(!disable_warning)
|
||||
src << "\red You are unable to equip that." //Only print if del_on_fail is false
|
||||
return 0
|
||||
|
||||
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
|
||||
return 1
|
||||
|
||||
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task.
|
||||
//In most cases you will want to use equip_to_slot_if_possible()
|
||||
/mob/proc/equip_to_slot(obj/item/W as obj, slot)
|
||||
return
|
||||
|
||||
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
|
||||
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
|
||||
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
|
||||
|
||||
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
|
||||
var/list/slot_equipment_priority = list( \
|
||||
slot_back,\
|
||||
slot_wear_id,\
|
||||
slot_w_uniform,\
|
||||
slot_wear_suit,\
|
||||
slot_wear_mask,\
|
||||
slot_head,\
|
||||
slot_shoes,\
|
||||
slot_gloves,\
|
||||
slot_l_ear,\
|
||||
slot_r_ear,\
|
||||
slot_glasses,\
|
||||
slot_belt,\
|
||||
slot_s_store,\
|
||||
slot_tie,\
|
||||
slot_l_store,\
|
||||
slot_r_store\
|
||||
)
|
||||
|
||||
//puts the item "W" into an appropriate slot in a human's inventory
|
||||
//returns 0 if it cannot, 1 if successful
|
||||
/mob/proc/equip_to_appropriate_slot(obj/item/W)
|
||||
if(!istype(W)) return 0
|
||||
|
||||
for(var/slot in slot_equipment_priority)
|
||||
if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/mob/proc/reset_view(atom/A)
|
||||
if (client)
|
||||
if (istype(A, /atom/movable))
|
||||
@@ -589,8 +518,8 @@ var/list/slot_equipment_priority = list( \
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.health - H.halloss <= config.health_threshold_softcrit)
|
||||
for(var/name in H.organs_by_name)
|
||||
var/datum/organ/external/e = H.organs_by_name[name]
|
||||
if(H.lying)
|
||||
var/obj/item/organ/external/e = H.organs_by_name[name]
|
||||
if(e && H.lying)
|
||||
if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100))
|
||||
return 1
|
||||
break
|
||||
@@ -1101,7 +1030,7 @@ mob/proc/yank_out_object()
|
||||
else
|
||||
U << "<span class='warning'>You attempt to get a good grip on [selection] in [S]'s body.</span>"
|
||||
|
||||
if(!do_after(U, 80))
|
||||
if(!do_after(U, 30))
|
||||
return
|
||||
if(!selection || !S || !U)
|
||||
return
|
||||
@@ -1116,9 +1045,9 @@ mob/proc/yank_out_object()
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/datum/organ/external/affected
|
||||
var/obj/item/organ/external/affected
|
||||
|
||||
for(var/datum/organ/external/organ in H.organs) //Grab the organ holding the implant.
|
||||
for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant.
|
||||
for(var/obj/item/O in organ.implants)
|
||||
if(O == selection)
|
||||
affected = organ
|
||||
@@ -1137,6 +1066,8 @@ mob/proc/yank_out_object()
|
||||
human_user.bloody_hands(H)
|
||||
|
||||
selection.loc = get_turf(src)
|
||||
if(!(U.l_hand && U.r_hand))
|
||||
U.put_in_hands(selection)
|
||||
|
||||
for(var/obj/item/weapon/O in pinned)
|
||||
if(O == selection)
|
||||
|
||||
@@ -92,13 +92,22 @@
|
||||
|
||||
/mob/living/silicon/ai/isAI()
|
||||
return 1
|
||||
|
||||
/mob/proc/isRobot()
|
||||
|
||||
/mob/proc/isRobot()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/isRobot()
|
||||
return 1
|
||||
|
||||
/mob/proc/isSynthetic()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/isSynthetic()
|
||||
return species.flags & IS_SYNTHETIC
|
||||
|
||||
/mob/living/silicon/isSynthetic()
|
||||
return 1
|
||||
|
||||
/proc/ispAI(A)
|
||||
if(istype(A, /mob/living/silicon/pai))
|
||||
return 1
|
||||
@@ -125,7 +134,7 @@ proc/isobserver(A)
|
||||
return 0
|
||||
|
||||
proc/isorgan(A)
|
||||
if(istype(A, /datum/organ/external))
|
||||
if(istype(A, /obj/item/organ/external))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -140,7 +149,7 @@ proc/isnewplayer(A)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/hasorgans(A)
|
||||
proc/hasorgans(A) // Fucking really??
|
||||
return ishuman(A)
|
||||
|
||||
proc/iscuffed(A)
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
|
||||
/client/verb/drop_item()
|
||||
set hidden = 1
|
||||
if(!isrobot(mob))
|
||||
mob.drop_item_v()
|
||||
if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc))
|
||||
return mob.drop_item()
|
||||
return
|
||||
|
||||
|
||||
@@ -289,8 +289,8 @@
|
||||
else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
if(ishuman(mob.buckled))
|
||||
var/mob/living/carbon/human/driver = mob.buckled
|
||||
var/datum/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
var/datum/organ/external/r_hand = driver.get_organ("r_hand")
|
||||
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
|
||||
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
|
||||
return // No hands to drive your chair? Tough luck!
|
||||
//drunk wheelchair driving
|
||||
|
||||
@@ -200,12 +200,13 @@ datum/preferences
|
||||
|
||||
for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
|
||||
if(organ_data[name] == "amputated") continue
|
||||
|
||||
var/icon/temp = new /icon(icobase, "[name]")
|
||||
if(organ_data[name] == "cyborg")
|
||||
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
|
||||
preview_icon.Blend(temp, ICON_OVERLAY)
|
||||
var/datum/robolimb/R
|
||||
if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]]
|
||||
if(!R) R = basic_robolimb
|
||||
preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic.
|
||||
continue
|
||||
preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY)
|
||||
|
||||
//Tail
|
||||
if(current_species && (current_species.tail))
|
||||
@@ -375,7 +376,7 @@ datum/preferences
|
||||
if(LAWYER)
|
||||
clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "briefcase"), ICON_UNDERLAY)
|
||||
if(prob(1))
|
||||
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "suitjacket_blue"), ICON_OVERLAY)
|
||||
switch(backbag)
|
||||
@@ -534,7 +535,7 @@ datum/preferences
|
||||
clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY)
|
||||
if(prob(1))
|
||||
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY)
|
||||
clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "toolbox_blue"), ICON_OVERLAY)
|
||||
switch(backbag)
|
||||
if(2)
|
||||
clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY)
|
||||
@@ -620,7 +621,7 @@ datum/preferences
|
||||
clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/head.dmi', "hardhat0_white"), ICON_OVERLAY)
|
||||
if(prob(1))
|
||||
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "blueprints"), ICON_OVERLAY)
|
||||
clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "blueprints"), ICON_OVERLAY)
|
||||
switch(backbag)
|
||||
if(2)
|
||||
clothes_s.Blend(new /icon('icons/mob/back.dmi', "engiepack"), ICON_OVERLAY)
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
//Most of these are defined at this level to reduce on checks elsewhere in the code.
|
||||
//Having them here also makes for a nice reference list of the various overlay-updating procs available
|
||||
|
||||
//default item on-mob icons
|
||||
#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi'
|
||||
#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi'
|
||||
|
||||
|
||||
/mob/proc/regenerate_icons() //TODO: phase this out completely if possible
|
||||
return
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
// Damaged heart virtually reduces the blood volume, as the blood isn't
|
||||
// being pumped properly anymore.
|
||||
if(species && species.has_organ["heart"])
|
||||
var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"]
|
||||
var/obj/item/organ/heart/heart = internal_organs_by_name["heart"]
|
||||
|
||||
if(!heart)
|
||||
blood_volume = 0
|
||||
@@ -127,7 +127,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
|
||||
//Bleeding out
|
||||
var/blood_max = 0
|
||||
for(var/datum/organ/external/temp in organs)
|
||||
for(var/obj/item/organ/external/temp in organs)
|
||||
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
|
||||
continue
|
||||
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
|
||||
|
||||
+270
-90
@@ -1,26 +1,154 @@
|
||||
/datum/organ
|
||||
var/name = "organ"
|
||||
var/list/organ_cache = list()
|
||||
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/status = 0
|
||||
var/vital //Lose a vital limb, die immediately.
|
||||
var/damage = 0 // amount of damage to the organ
|
||||
|
||||
var/min_bruised_damage = 10
|
||||
var/min_broken_damage = 30
|
||||
var/max_damage
|
||||
var/organ_tag = "organ"
|
||||
|
||||
var/parent_organ = "chest"
|
||||
var/robotic = 0 //For being a robot
|
||||
var/rejecting // Is this organ already being rejected?
|
||||
|
||||
var/list/transplant_data
|
||||
var/list/datum/autopsy_data/autopsy_data = list()
|
||||
var/list/trace_chemicals = list() // traces of chemicals in the organ,
|
||||
// links chemical IDs to number of ticks for which they'll stay in the blood
|
||||
germ_level = 0
|
||||
|
||||
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
|
||||
/obj/item/organ/proc/update_health()
|
||||
return
|
||||
|
||||
proc/process()
|
||||
return 0
|
||||
/obj/item/organ/New(var/mob/living/carbon/holder, var/internal)
|
||||
..(holder)
|
||||
create_reagents(5)
|
||||
if(!max_damage)
|
||||
max_damage = min_broken_damage * 2
|
||||
if(istype(holder))
|
||||
src.owner = holder
|
||||
var/mob/living/carbon/human/H = holder
|
||||
if(istype(H))
|
||||
if(internal)
|
||||
var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ]
|
||||
if(E)
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs |= src
|
||||
if(H.dna)
|
||||
if(!blood_DNA)
|
||||
blood_DNA = list()
|
||||
blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
if(internal)
|
||||
holder.internal_organs |= src
|
||||
|
||||
proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
/obj/item/organ/proc/die()
|
||||
name = "dead [initial(name)]"
|
||||
health = 0
|
||||
processing_objects -= src
|
||||
//TODO: Grey out the icon state.
|
||||
//TODO: Inject an organ with peridaxon to make it alive again.
|
||||
|
||||
/datum/organ/proc/get_icon(var/icon/race_icon, var/icon/deform_icon)
|
||||
return icon('icons/mob/human.dmi',"blank")
|
||||
/obj/item/organ/process()
|
||||
|
||||
// Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature?
|
||||
if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer))
|
||||
return
|
||||
|
||||
//Process infections
|
||||
if (robotic >= 2 || (owner && owner.species && (owner.species.flags & IS_PLANT)))
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
if(loc != owner)
|
||||
owner = null
|
||||
|
||||
if(!owner)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
if(B && prob(40))
|
||||
reagents.remove_reagent("blood",0.1)
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
health -= rand(1,3)
|
||||
if(health <= 0)
|
||||
die()
|
||||
else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
//** Handle antibiotics and curing infections
|
||||
handle_antibiotics()
|
||||
handle_rejection()
|
||||
handle_germ_effects()
|
||||
|
||||
/obj/item/organ/proc/handle_germ_effects()
|
||||
//** Handle the effects of infections
|
||||
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
|
||||
|
||||
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30))
|
||||
germ_level--
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_ONE/2)
|
||||
//aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
|
||||
if(antibiotics < 5 && prob(round(germ_level/6)))
|
||||
germ_level++
|
||||
|
||||
if(germ_level >= INFECTION_LEVEL_ONE)
|
||||
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature
|
||||
owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature)
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_TWO)
|
||||
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
|
||||
//spread germs
|
||||
if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
|
||||
parent.germ_level++
|
||||
|
||||
if (prob(3)) //about once every 30 seconds
|
||||
take_damage(1,silent=prob(30))
|
||||
|
||||
/obj/item/organ/proc/handle_rejection()
|
||||
// Process unsuitable transplants. TODO: consider some kind of
|
||||
// immunosuppressant that changes transplant data to make it match.
|
||||
if(transplant_data)
|
||||
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
|
||||
rejecting = 1
|
||||
else
|
||||
rejecting++ //Rejection severity increases over time.
|
||||
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
|
||||
switch(rejecting)
|
||||
if(1 to 50)
|
||||
take_damage(1)
|
||||
if(51 to 200)
|
||||
owner.reagents.add_reagent("toxin", 1)
|
||||
take_damage(1)
|
||||
if(201 to 500)
|
||||
take_damage(rand(2,3))
|
||||
owner.reagents.add_reagent("toxin", 2)
|
||||
if(501 to INFINITY)
|
||||
take_damage(4)
|
||||
owner.reagents.add_reagent("toxin", rand(3,5))
|
||||
|
||||
/obj/item/organ/proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
|
||||
/obj/item/organ/proc/rejuvenate()
|
||||
damage = 0
|
||||
|
||||
/obj/item/organ/proc/is_damaged()
|
||||
return damage > 0
|
||||
|
||||
/obj/item/organ/proc/is_bruised()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/obj/item/organ/proc/is_broken()
|
||||
return (damage >= min_broken_damage || (status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED)))
|
||||
|
||||
//Germs
|
||||
/datum/organ/proc/handle_antibiotics()
|
||||
/obj/item/organ/proc/handle_antibiotics()
|
||||
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
|
||||
|
||||
if (!germ_level || antibiotics < 5)
|
||||
@@ -33,15 +161,8 @@
|
||||
else
|
||||
germ_level -= 2 //at germ_level == 1000, this will cure the infection in 5 minutes
|
||||
|
||||
//Handles chem traces
|
||||
/mob/living/carbon/human/proc/handle_trace_chems()
|
||||
//New are added for reagents to random organs.
|
||||
for(var/datum/reagent/A in reagents.reagent_list)
|
||||
var/datum/organ/O = pick(organs)
|
||||
O.trace_chemicals[A.name] = 100
|
||||
|
||||
//Adds autopsy data for used_weapon.
|
||||
/datum/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
|
||||
/obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
|
||||
var/datum/autopsy_data/W = autopsy_data[used_weapon]
|
||||
if(!W)
|
||||
W = new()
|
||||
@@ -52,88 +173,147 @@
|
||||
W.damage += damage
|
||||
W.time_inflicted = world.time
|
||||
|
||||
/mob/living/carbon/human/var/list/organs = list()
|
||||
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
|
||||
/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too
|
||||
/obj/item/organ/proc/take_damage(amount, var/silent=0)
|
||||
if(src.robotic == 2)
|
||||
src.damage += (amount * 0.8)
|
||||
else
|
||||
src.damage += amount
|
||||
|
||||
// Takes care of organ related updates, such as broken and missing limbs
|
||||
/mob/living/carbon/human/proc/handle_organs()
|
||||
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if (!silent)
|
||||
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
|
||||
|
||||
number_wounds = 0
|
||||
var/force_process = 0
|
||||
var/damage_this_tick = getBruteLoss() + getFireLoss() + getToxLoss()
|
||||
if(damage_this_tick > last_dam)
|
||||
force_process = 1
|
||||
last_dam = damage_this_tick
|
||||
if(force_process)
|
||||
bad_external_organs.Cut()
|
||||
for(var/datum/organ/external/Ex in organs)
|
||||
bad_external_organs += Ex
|
||||
/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc
|
||||
robotic = 2
|
||||
src.status &= ~ORGAN_BROKEN
|
||||
src.status &= ~ORGAN_BLEEDING
|
||||
src.status &= ~ORGAN_SPLINTED
|
||||
src.status &= ~ORGAN_CUT_AWAY
|
||||
src.status &= ~ORGAN_ATTACHABLE
|
||||
src.status &= ~ORGAN_DESTROYED
|
||||
src.status |= ORGAN_ROBOT
|
||||
src.status |= ORGAN_ASSISTED
|
||||
|
||||
//processing internal organs is pretty cheap, do that first.
|
||||
for(var/datum/organ/internal/I in internal_organs)
|
||||
I.process()
|
||||
/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc
|
||||
robotize()
|
||||
src.status &= ~ORGAN_ROBOT
|
||||
robotic = 1
|
||||
min_bruised_damage = 15
|
||||
min_broken_damage = 35
|
||||
|
||||
//losing a limb stops it from processing, so this has to be done separately
|
||||
handle_stance()
|
||||
/obj/item/organ/emp_act(severity)
|
||||
switch(robotic)
|
||||
if(0)
|
||||
return
|
||||
if(1)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(20,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(7,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(3,0)
|
||||
return
|
||||
if(2)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(40,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(15,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(10,0)
|
||||
return
|
||||
|
||||
if(!force_process && !bad_external_organs.len)
|
||||
/obj/item/organ/proc/removed(var/mob/living/user)
|
||||
|
||||
if(!istype(owner))
|
||||
return
|
||||
|
||||
for(var/datum/organ/external/E in bad_external_organs)
|
||||
if(!E)
|
||||
continue
|
||||
if(!E.need_process())
|
||||
bad_external_organs -= E
|
||||
continue
|
||||
else
|
||||
E.process()
|
||||
number_wounds += E.number_wounds
|
||||
owner.internal_organs_by_name[organ_tag] = null
|
||||
owner.internal_organs_by_name -= organ_tag
|
||||
owner.internal_organs -= src
|
||||
|
||||
if (!lying && world.time - l_move_time < 15)
|
||||
//Moving around with fractured ribs won't do you any good
|
||||
if (E.is_broken() && E.internal_organs && prob(15))
|
||||
var/datum/organ/internal/I = pick(E.internal_organs)
|
||||
custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
|
||||
I.take_damage(rand(3,5))
|
||||
var/obj/item/organ/external/affected = owner.get_organ(parent_organ)
|
||||
if(affected) affected.internal_organs -= src
|
||||
|
||||
//Moving makes open wounds get infected much faster
|
||||
if (E.wounds.len)
|
||||
for(var/datum/wound/W in E.wounds)
|
||||
if (W.infection_check())
|
||||
W.germ_level += 1
|
||||
loc = owner.loc
|
||||
rejecting = null
|
||||
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
if(!organ_blood || !organ_blood.data["blood_DNA"])
|
||||
owner.vessel.trans_to(src, 5, 1, 1)
|
||||
|
||||
/mob/living/carbon/human/proc/handle_stance()
|
||||
// Don't need to process any of this if they aren't standing anyways
|
||||
// unless their stance is damaged, and we want to check if they should stay down
|
||||
if (!stance_damage && (lying || resting) && (life_tick % 4) == 0)
|
||||
return
|
||||
|
||||
stance_damage = 0
|
||||
|
||||
// Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid
|
||||
if (istype(buckled, /obj/structure/bed))
|
||||
if(owner && vital)
|
||||
if(user)
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
owner.attack_log += "\[[time_stamp()]\]<font color='orange'> had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [owner.name] ([owner.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
owner.death()
|
||||
|
||||
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
|
||||
|
||||
if(!istype(target)) return
|
||||
|
||||
var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
transplant_data = list()
|
||||
if(!transplant_blood)
|
||||
transplant_data["species"] = target.species.name
|
||||
transplant_data["blood_type"] = target.dna.b_type
|
||||
transplant_data["blood_DNA"] = target.dna.unique_enzymes
|
||||
else
|
||||
transplant_data["species"] = transplant_blood.data["species"]
|
||||
transplant_data["blood_type"] = transplant_blood.data["blood_type"]
|
||||
transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
|
||||
|
||||
owner = target
|
||||
target.internal_organs |= src
|
||||
affected.internal_organs |= src
|
||||
target.internal_organs_by_name[organ_tag] = src
|
||||
status |= ORGAN_CUT_AWAY
|
||||
|
||||
del(src)
|
||||
|
||||
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
|
||||
|
||||
// Apply our eye colour to the target.
|
||||
if(istype(target) && eye_colour)
|
||||
target.r_eyes = eye_colour[1]
|
||||
target.g_eyes = eye_colour[2]
|
||||
target.b_eyes = eye_colour[3]
|
||||
target.update_body()
|
||||
..()
|
||||
|
||||
/obj/item/organ/proc/bitten(mob/user)
|
||||
|
||||
if(robotic)
|
||||
return
|
||||
|
||||
for (var/organ in list("l_leg","l_foot","r_leg","r_foot"))
|
||||
var/datum/organ/external/E = organs_by_name[organ]
|
||||
if (E.status & ORGAN_DESTROYED)
|
||||
stance_damage += 2 // let it fail even if just foot&leg
|
||||
else if (E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)) || !E.is_usable())
|
||||
stance_damage += 1
|
||||
|
||||
// Canes and crutches help you stand (if the latter is ever added)
|
||||
// One cane mitigates a broken leg+foot, or a missing foot.
|
||||
// Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you.
|
||||
if (istype(l_hand, /obj/item/weapon/cane))
|
||||
stance_damage -= 2
|
||||
if (istype(l_hand, /obj/item/weapon/cane))
|
||||
stance_damage -= 2
|
||||
user << "\blue You take an experimental bite out of \the [src]."
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
// standing is poor
|
||||
if(stance_damage >= 4 || (stance_damage >= 2 && prob(5)))
|
||||
if(!(lying || resting))
|
||||
if(species && !(species.flags & NO_PAIN))
|
||||
emote("scream")
|
||||
custom_emote(1, "collapses!")
|
||||
Weaken(5) //can't emote while weakened, apparently.
|
||||
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
|
||||
O.name = name
|
||||
O.icon_state = icon_state
|
||||
|
||||
// Pass over the blood.
|
||||
reagents.trans_to(O, reagents.total_volume)
|
||||
|
||||
if(fingerprints) O.fingerprints = fingerprints.Copy()
|
||||
if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy()
|
||||
if(fingerprintslast) O.fingerprintslast = fingerprintslast
|
||||
|
||||
user.put_in_active_hand(O)
|
||||
del(src)
|
||||
|
||||
/obj/item/organ/attack_self(mob/user as mob)
|
||||
|
||||
// Convert it to an edible form, yum yum.
|
||||
if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth")
|
||||
bitten(user)
|
||||
return
|
||||
|
||||
@@ -1,51 +1,6 @@
|
||||
//DIONA ORGANS.
|
||||
/datum/organ/internal/diona
|
||||
removed_type = /obj/item/organ/diona
|
||||
|
||||
/datum/organ/internal/diona/process()
|
||||
return
|
||||
|
||||
/datum/organ/internal/diona/strata
|
||||
name = "neural strata"
|
||||
parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/diona/bladder
|
||||
name = "gas bladder"
|
||||
parent_organ = "head"
|
||||
|
||||
/datum/organ/internal/diona/polyp
|
||||
name = "polyp segment"
|
||||
parent_organ = "groin"
|
||||
|
||||
/datum/organ/internal/diona/ligament
|
||||
name = "anchoring ligament"
|
||||
parent_organ = "groin"
|
||||
|
||||
/datum/organ/internal/diona/node
|
||||
name = "receptor node"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/diona/node
|
||||
|
||||
/datum/organ/internal/diona/nutrients
|
||||
name = "nutrient vessel"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/diona/nutrients
|
||||
|
||||
/obj/item/organ/diona
|
||||
name = "diona nymph"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "nymph"
|
||||
organ_tag = "special" // Turns into a nymph instantly, no transplanting possible.
|
||||
|
||||
/obj/item/organ/diona/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
..()
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!istype(target))
|
||||
del(src)
|
||||
|
||||
if(!H.internal_organs.len)
|
||||
H.death()
|
||||
/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ)
|
||||
if(!istype(organ))
|
||||
return
|
||||
|
||||
//This is a terrible hack and I should be ashamed.
|
||||
var/datum/seed/diona = plant_controller.seeds["diona"]
|
||||
@@ -53,10 +8,180 @@
|
||||
del(src)
|
||||
|
||||
spawn(1) // So it has time to be thrown about by the gib() proc.
|
||||
var/mob/living/carbon/alien/diona/D = new(get_turf(src))
|
||||
var/mob/living/carbon/alien/diona/D = new(get_turf(organ))
|
||||
diona.request_player(D)
|
||||
del(organ)
|
||||
|
||||
/obj/item/organ/external/diona
|
||||
name = "tendril"
|
||||
cannot_break = 1
|
||||
amputation_point = "branch"
|
||||
joint = "structural ligament"
|
||||
dislocated = -1
|
||||
|
||||
/obj/item/organ/external/diona/chest
|
||||
name = "core trunk"
|
||||
limb_name = "chest"
|
||||
icon_name = "torso"
|
||||
health = 200
|
||||
min_broken_damage = 50
|
||||
body_part = UPPER_TORSO
|
||||
vital = 1
|
||||
cannot_amputate = 1
|
||||
parent_organ = null
|
||||
|
||||
/obj/item/organ/external/diona/groin
|
||||
name = "fork"
|
||||
limb_name = "groin"
|
||||
icon_name = "groin"
|
||||
health = 100
|
||||
min_broken_damage = 50
|
||||
body_part = LOWER_TORSO
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/external/diona/arm
|
||||
name = "left upper tendril"
|
||||
limb_name = "l_arm"
|
||||
icon_name = "l_arm"
|
||||
health = 35
|
||||
min_broken_damage = 20
|
||||
body_part = ARM_LEFT
|
||||
parent_organ = "chest"
|
||||
can_grasp = 1
|
||||
|
||||
/obj/item/organ/external/diona/arm/right
|
||||
name = "right upper tendril"
|
||||
limb_name = "r_arm"
|
||||
icon_name = "r_arm"
|
||||
body_part = ARM_RIGHT
|
||||
|
||||
/obj/item/organ/external/diona/leg
|
||||
name = "left lower tendril"
|
||||
limb_name = "l_leg"
|
||||
icon_name = "l_leg"
|
||||
health = 35
|
||||
min_broken_damage = 20
|
||||
body_part = LEG_LEFT
|
||||
icon_position = LEFT
|
||||
parent_organ = "groin"
|
||||
can_stand = 1
|
||||
|
||||
/obj/item/organ/external/diona/leg/right
|
||||
name = "right lower tendril"
|
||||
limb_name = "r_leg"
|
||||
icon_name = "r_leg"
|
||||
body_part = LEG_RIGHT
|
||||
icon_position = RIGHT
|
||||
|
||||
/obj/item/organ/external/diona/foot
|
||||
name = "left foot"
|
||||
limb_name = "l_foot"
|
||||
icon_name = "l_foot"
|
||||
health = 20
|
||||
min_broken_damage = 10
|
||||
body_part = FOOT_LEFT
|
||||
icon_position = LEFT
|
||||
parent_organ = "l_leg"
|
||||
can_stand = 1
|
||||
|
||||
/obj/item/organ/external/diona/foot/right
|
||||
name = "right foot"
|
||||
limb_name = "r_foot"
|
||||
icon_name = "r_foot"
|
||||
body_part = FOOT_RIGHT
|
||||
icon_position = RIGHT
|
||||
parent_organ = "r_leg"
|
||||
joint = "right ankle"
|
||||
amputation_point = "right ankle"
|
||||
|
||||
/obj/item/organ/external/diona/hand
|
||||
name = "left grasper"
|
||||
limb_name = "l_hand"
|
||||
icon_name = "l_hand"
|
||||
health = 30
|
||||
min_broken_damage = 15
|
||||
body_part = HAND_LEFT
|
||||
parent_organ = "l_arm"
|
||||
can_grasp = 1
|
||||
|
||||
/obj/item/organ/external/diona/hand/right
|
||||
name = "right grasper"
|
||||
limb_name = "r_hand"
|
||||
icon_name = "r_hand"
|
||||
body_part = HAND_RIGHT
|
||||
parent_organ = "r_arm"
|
||||
|
||||
/obj/item/organ/external/diona/head
|
||||
limb_name = "head"
|
||||
icon_name = "head"
|
||||
name = "head"
|
||||
health = 50
|
||||
min_broken_damage = 25
|
||||
body_part = HEAD
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/external/diona/head/removed()
|
||||
if(owner)
|
||||
owner.u_equip(owner.head)
|
||||
owner.u_equip(owner.l_ear)
|
||||
..()
|
||||
|
||||
//DIONA ORGANS.
|
||||
/obj/item/organ/external/diona/removed()
|
||||
..()
|
||||
if(!istype(owner))
|
||||
del(src)
|
||||
|
||||
if(!owner.organs.len)
|
||||
owner.death()
|
||||
|
||||
if(prob(50))
|
||||
spawn_diona_nymph_from_organ(src)
|
||||
|
||||
/obj/item/organ/diona/process()
|
||||
return
|
||||
|
||||
/obj/item/organ/diona/strata
|
||||
name = "neural strata"
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/diona/bladder
|
||||
name = "gas bladder"
|
||||
parent_organ = "head"
|
||||
|
||||
/obj/item/organ/diona/polyp
|
||||
name = "polyp segment"
|
||||
parent_organ = "groin"
|
||||
|
||||
/obj/item/organ/diona/ligament
|
||||
name = "anchoring ligament"
|
||||
parent_organ = "groin"
|
||||
|
||||
/obj/item/organ/diona/node
|
||||
name = "receptor node"
|
||||
parent_organ = "head"
|
||||
|
||||
/obj/item/organ/diona/nutrients
|
||||
name = "nutrient vessel"
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/diona
|
||||
name = "diona nymph"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "nymph"
|
||||
organ_tag = "special" // Turns into a nymph instantly, no transplanting possible.
|
||||
|
||||
/obj/item/organ/diona/removed(var/mob/living/user)
|
||||
|
||||
..()
|
||||
if(!istype(owner))
|
||||
del(src)
|
||||
|
||||
if(!owner.internal_organs.len)
|
||||
owner.death()
|
||||
|
||||
spawn_diona_nymph_from_organ(src)
|
||||
|
||||
// These are different to the standard diona organs as they have a purpose in other
|
||||
// species (absorbing radiation and light respectively)
|
||||
/obj/item/organ/diona/nutrients
|
||||
@@ -78,13 +203,12 @@
|
||||
return
|
||||
|
||||
//CORTICAL BORER ORGANS.
|
||||
/datum/organ/internal/borer
|
||||
/obj/item/organ/borer
|
||||
name = "cortical borer"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/borer
|
||||
vital = 1
|
||||
|
||||
/datum/organ/internal/borer/process()
|
||||
/obj/item/organ/borer/process()
|
||||
|
||||
// Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss.
|
||||
for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine"))
|
||||
@@ -113,59 +237,54 @@
|
||||
organ_tag = "brain"
|
||||
desc = "A disgusting space slug."
|
||||
|
||||
/obj/item/organ/borer/removed(var/mob/living/target,var/mob/living/user)
|
||||
/obj/item/organ/borer/removed(var/mob/living/user)
|
||||
|
||||
..()
|
||||
|
||||
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
|
||||
var/mob/living/simple_animal/borer/B = owner.has_brain_worms()
|
||||
if(B)
|
||||
B.leave_host()
|
||||
B.ckey = target.ckey
|
||||
B.ckey = owner.ckey
|
||||
|
||||
spawn(0)
|
||||
del(src)
|
||||
|
||||
//XENOMORPH ORGANS
|
||||
/datum/organ/internal/xenos/eggsac
|
||||
/obj/item/organ/xenos/eggsac
|
||||
name = "egg sac"
|
||||
parent_organ = "groin"
|
||||
removed_type = /obj/item/organ/xenos/eggsac
|
||||
|
||||
/datum/organ/internal/xenos/plasmavessel
|
||||
/obj/item/organ/xenos/plasmavessel
|
||||
name = "plasma vessel"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/xenos/plasmavessel
|
||||
var/stored_plasma = 0
|
||||
var/max_plasma = 500
|
||||
|
||||
/datum/organ/internal/xenos/plasmavessel/queen
|
||||
/obj/item/organ/xenos/plasmavessel/queen
|
||||
name = "bloated plasma vessel"
|
||||
stored_plasma = 200
|
||||
max_plasma = 500
|
||||
|
||||
/datum/organ/internal/xenos/plasmavessel/sentinel
|
||||
/obj/item/organ/xenos/plasmavessel/sentinel
|
||||
stored_plasma = 100
|
||||
max_plasma = 250
|
||||
|
||||
/datum/organ/internal/xenos/plasmavessel/hunter
|
||||
/obj/item/organ/xenos/plasmavessel/hunter
|
||||
name = "tiny plasma vessel"
|
||||
stored_plasma = 100
|
||||
max_plasma = 150
|
||||
|
||||
/datum/organ/internal/xenos/acidgland
|
||||
/obj/item/organ/xenos/acidgland
|
||||
name = "acid gland"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/xenos/acidgland
|
||||
|
||||
/datum/organ/internal/xenos/hivenode
|
||||
/obj/item/organ/xenos/hivenode
|
||||
name = "hive node"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/xenos/hivenode
|
||||
|
||||
/datum/organ/internal/xenos/resinspinner
|
||||
/obj/item/organ/xenos/resinspinner
|
||||
name = "resin spinner"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/xenos/resinspinner
|
||||
|
||||
/obj/item/organ/xenos
|
||||
name = "xeno organ"
|
||||
@@ -198,32 +317,28 @@
|
||||
organ_tag = "resin spinner"
|
||||
|
||||
//VOX ORGANS.
|
||||
/datum/organ/internal/stack
|
||||
/obj/item/organ/stack
|
||||
name = "cortical stack"
|
||||
removed_type = /obj/item/organ/stack
|
||||
parent_organ = "head"
|
||||
robotic = 2
|
||||
vital = 1
|
||||
var/backup_time = 0
|
||||
var/datum/mind/backup
|
||||
|
||||
/datum/organ/internal/stack/process()
|
||||
/obj/item/organ/stack/process()
|
||||
if(owner && owner.stat != 2 && !is_broken())
|
||||
backup_time = world.time
|
||||
if(owner.mind) backup = owner.mind
|
||||
|
||||
/datum/organ/internal/stack/vox
|
||||
removed_type = /obj/item/organ/stack/vox
|
||||
/obj/item/organ/stack/vox
|
||||
|
||||
/datum/organ/internal/stack/vox/stack
|
||||
/obj/item/organ/stack/vox/stack
|
||||
|
||||
/obj/item/organ/stack
|
||||
name = "cortical stack"
|
||||
icon_state = "brain-prosthetic"
|
||||
organ_tag = "stack"
|
||||
robotic = 2
|
||||
prosthetic_name = null
|
||||
prosthetic_icon = null
|
||||
|
||||
/obj/item/organ/stack/vox
|
||||
name = "vox cortical stack"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/obj/item/organ/external/set_dir()
|
||||
return
|
||||
|
||||
/obj/item/organ/external/proc/compile_icon()
|
||||
overlays.Cut()
|
||||
get_icon()
|
||||
// This is a kludge, only one icon has more than one generation of children though.
|
||||
for(var/obj/item/organ/external/organ in contents)
|
||||
if(organ.children && organ.children.len)
|
||||
for(var/obj/item/organ/external/child in organ.children)
|
||||
overlays += child.get_icon()
|
||||
overlays += organ.get_icon()
|
||||
|
||||
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
|
||||
s_tone = null
|
||||
s_col = null
|
||||
if(human.s_tone && (human.species.flags & HAS_SKIN_TONE))
|
||||
s_tone = human.s_tone
|
||||
if(human.species.flags & HAS_SKIN_COLOR)
|
||||
s_col = list(human.r_skin, human.g_skin, human.b_skin)
|
||||
|
||||
/obj/item/organ/external/proc/get_icon(var/skeletal)
|
||||
|
||||
var/gender
|
||||
if(force_icon)
|
||||
mob_icon = new /icon(force_icon, "[icon_name]")
|
||||
else
|
||||
if(!owner)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]")
|
||||
else
|
||||
|
||||
if(gendered_icon)
|
||||
if(owner.gender == FEMALE)
|
||||
gender = "f"
|
||||
else
|
||||
gender = "m"
|
||||
|
||||
if(skeletal)
|
||||
mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else if ((status & ORGAN_ROBOT) && !(owner.species && owner.species.flags & IS_SYNTHETIC))
|
||||
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else
|
||||
if (status & ORGAN_MUTATED)
|
||||
mob_icon = new /icon(owner.species.deform, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else
|
||||
mob_icon = new /icon(owner.species.icobase, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
|
||||
if(status & ORGAN_DEAD)
|
||||
mob_icon.ColorTone(rgb(10,50,0))
|
||||
mob_icon.SetIntensity(0.7)
|
||||
|
||||
if(!isnull(s_tone))
|
||||
if(s_tone >= 0)
|
||||
mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
|
||||
else
|
||||
mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
|
||||
else if(s_col && s_col.len >= 3)
|
||||
mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
|
||||
|
||||
dir = EAST
|
||||
icon = mob_icon
|
||||
|
||||
return mob_icon
|
||||
|
||||
/obj/item/organ/external/head/get_icon(var/skeletal)
|
||||
|
||||
if(skeletal || !owner)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(owner.species.has_organ["eyes"])
|
||||
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
|
||||
if(eyes && owner.species.eyes)
|
||||
var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', owner.species.eyes)
|
||||
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
|
||||
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
|
||||
|
||||
if(owner.lip_style && (owner.species && (owner.species.flags & HAS_LIPS)))
|
||||
mob_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s"), ICON_OVERLAY)
|
||||
|
||||
if(owner.f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
|
||||
if(facial_hair_style)
|
||||
var/icon/facial = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
if(facial_hair_style.do_colouration)
|
||||
facial.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
|
||||
mob_icon.Blend(facial, ICON_OVERLAY)
|
||||
|
||||
if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
|
||||
if(hair_style)
|
||||
var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
if(hair_style.do_colouration)
|
||||
hair.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD)
|
||||
|
||||
mob_icon.Blend(hair, ICON_OVERLAY)
|
||||
|
||||
icon = mob_icon
|
||||
return mob_icon
|
||||
|
||||
// new damage icon system
|
||||
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
|
||||
/obj/item/organ/external/update_icon()
|
||||
var/n_is = damage_state_text()
|
||||
if (n_is != damage_state)
|
||||
damage_state = n_is
|
||||
return 1
|
||||
return 0
|
||||
@@ -1,296 +1,191 @@
|
||||
#define PROCESS_ACCURACY 10
|
||||
|
||||
/****************************************************
|
||||
INTERNAL ORGANS
|
||||
****************************************************/
|
||||
|
||||
/mob/living/carbon/var/list/internal_organs = list()
|
||||
|
||||
/datum/organ/internal
|
||||
var/damage = 0 // amount of damage to the organ
|
||||
var/min_bruised_damage = 10
|
||||
var/min_broken_damage = 30
|
||||
var/parent_organ = "chest"
|
||||
var/robotic = 0 //For being a robot
|
||||
var/removed_type //When removed, forms this object.
|
||||
var/rejecting // Is this organ already being rejected?
|
||||
var/obj/item/organ/organ_holder // If not in a body, held in this item.
|
||||
var/list/transplant_data
|
||||
|
||||
/datum/organ/internal/proc/rejuvenate()
|
||||
damage=0
|
||||
|
||||
/datum/organ/internal/proc/is_bruised()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/datum/organ/internal/proc/is_broken()
|
||||
return damage >= min_broken_damage || status & ORGAN_CUT_AWAY
|
||||
|
||||
/datum/organ/internal/New(mob/living/carbon/M)
|
||||
..()
|
||||
if(M && istype(M))
|
||||
|
||||
M.internal_organs |= src
|
||||
src.owner = M
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H))
|
||||
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs |= src
|
||||
|
||||
/datum/organ/internal/process()
|
||||
|
||||
//Process infections
|
||||
if (robotic >= 2 || (owner.species && owner.species.flags & IS_PLANT)) //TODO make robotic internal and external organs separate types of organ instead of a flag
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
//** Handle antibiotics and curing infections
|
||||
handle_antibiotics()
|
||||
|
||||
//** Handle the effects of infections
|
||||
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
|
||||
|
||||
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30))
|
||||
germ_level--
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_ONE/2)
|
||||
//aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
|
||||
if(antibiotics < 5 && prob(round(germ_level/6)))
|
||||
germ_level++
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_TWO)
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
//spread germs
|
||||
if (antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
|
||||
parent.germ_level++
|
||||
|
||||
if (prob(3)) //about once every 30 seconds
|
||||
take_damage(1,silent=prob(30))
|
||||
|
||||
// Process unsuitable transplants. TODO: consider some kind of
|
||||
// immunosuppressant that changes transplant data to make it match.
|
||||
if(transplant_data)
|
||||
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
|
||||
rejecting = 1
|
||||
else
|
||||
rejecting++ //Rejection severity increases over time.
|
||||
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
|
||||
switch(rejecting)
|
||||
if(1 to 50)
|
||||
take_damage(1)
|
||||
if(51 to 200)
|
||||
owner.reagents.add_reagent("toxin", 1)
|
||||
take_damage(1)
|
||||
if(201 to 500)
|
||||
take_damage(rand(2,3))
|
||||
owner.reagents.add_reagent("toxin", 2)
|
||||
if(501 to INFINITY)
|
||||
take_damage(4)
|
||||
owner.reagents.add_reagent("toxin", rand(3,5))
|
||||
|
||||
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
|
||||
if(src.robotic == 2)
|
||||
src.damage += (amount * 0.8)
|
||||
else
|
||||
src.damage += amount
|
||||
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if (!silent)
|
||||
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
|
||||
|
||||
/datum/organ/internal/proc/emp_act(severity)
|
||||
switch(robotic)
|
||||
if(0)
|
||||
return
|
||||
if(1)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(20,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(7,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(3,0)
|
||||
return
|
||||
if(2)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(40,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(15,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(10,0)
|
||||
return
|
||||
|
||||
/datum/organ/internal/proc/mechanize() //Being used to make robutt hearts, etc
|
||||
robotic = 2
|
||||
|
||||
/datum/organ/internal/proc/mechassist() //Used to add things like pacemakers, etc
|
||||
robotic = 1
|
||||
min_bruised_damage = 15
|
||||
min_broken_damage = 35
|
||||
|
||||
/****************************************************
|
||||
INTERNAL ORGANS DEFINES
|
||||
****************************************************/
|
||||
|
||||
/datum/organ/internal/heart // This is not set to vital because death immediately occurs in blood.dm if it is removed.
|
||||
|
||||
// Brain is defined in brain_item.dm.
|
||||
/obj/item/organ/heart
|
||||
name = "heart"
|
||||
icon_state = "heart-on"
|
||||
organ_tag = "heart"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/heart
|
||||
|
||||
/datum/organ/internal/lungs
|
||||
/obj/item/organ/lungs
|
||||
name = "lungs"
|
||||
icon_state = "lungs"
|
||||
gender = PLURAL
|
||||
organ_tag = "lungs"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/lungs
|
||||
|
||||
process()
|
||||
..()
|
||||
if (germ_level > INFECTION_LEVEL_ONE)
|
||||
if(prob(5))
|
||||
owner.emote("cough") //respitory tract infection
|
||||
/obj/item/organ/lungs/process()
|
||||
..()
|
||||
|
||||
if(is_bruised())
|
||||
if(prob(2))
|
||||
spawn owner.emote("me", 1, "coughs up blood!")
|
||||
owner.drip(10)
|
||||
if(prob(4))
|
||||
spawn owner.emote("me", 1, "gasps for air!")
|
||||
owner.losebreath += 15
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
/datum/organ/internal/liver
|
||||
name = "liver"
|
||||
parent_organ = "chest"
|
||||
removed_type = /obj/item/organ/liver
|
||||
if (germ_level > INFECTION_LEVEL_ONE)
|
||||
if(prob(5))
|
||||
owner.emote("cough") //respitory tract infection
|
||||
|
||||
process()
|
||||
if(is_bruised())
|
||||
if(prob(2))
|
||||
spawn owner.emote("me", 1, "coughs up blood!")
|
||||
owner.drip(10)
|
||||
if(prob(4))
|
||||
spawn owner.emote("me", 1, "gasps for air!")
|
||||
owner.losebreath += 15
|
||||
|
||||
..()
|
||||
|
||||
if (germ_level > INFECTION_LEVEL_ONE)
|
||||
if(prob(1))
|
||||
owner << "\red Your skin itches."
|
||||
if (germ_level > INFECTION_LEVEL_TWO)
|
||||
if(prob(1))
|
||||
spawn owner.vomit()
|
||||
|
||||
if(owner.life_tick % PROCESS_ACCURACY == 0)
|
||||
|
||||
//High toxins levels are dangerous
|
||||
if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin"))
|
||||
//Healthy liver suffers on its own
|
||||
if (src.damage < min_broken_damage)
|
||||
src.damage += 0.2 * PROCESS_ACCURACY
|
||||
//Damaged one shares the fun
|
||||
else
|
||||
var/datum/organ/internal/O = pick(owner.internal_organs)
|
||||
if(O)
|
||||
O.damage += 0.2 * PROCESS_ACCURACY
|
||||
|
||||
//Detox can heal small amounts of damage
|
||||
if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin"))
|
||||
src.damage -= 0.2 * PROCESS_ACCURACY
|
||||
|
||||
if(src.damage < 0)
|
||||
src.damage = 0
|
||||
|
||||
// Get the effectiveness of the liver.
|
||||
var/filter_effect = 3
|
||||
if(is_bruised())
|
||||
filter_effect -= 1
|
||||
if(is_broken())
|
||||
filter_effect -= 2
|
||||
|
||||
// Do some reagent filtering/processing.
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
// Damaged liver means some chemicals are very dangerous
|
||||
// The liver is also responsible for clearing out alcohol and toxins.
|
||||
// Ethanol and all drinks are bad.K
|
||||
if(istype(R, /datum/reagent/ethanol))
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
|
||||
owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect)
|
||||
// Can't cope with toxins at all
|
||||
else if(istype(R, /datum/reagent/toxin))
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
|
||||
owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect)
|
||||
|
||||
/datum/organ/internal/kidney
|
||||
/obj/item/organ/kidneys
|
||||
name = "kidneys"
|
||||
icon_state = "kidneys"
|
||||
gender = PLURAL
|
||||
organ_tag = "kidneys"
|
||||
parent_organ = "groin"
|
||||
removed_type = /obj/item/organ/kidneys
|
||||
|
||||
process()
|
||||
/obj/item/organ/kidney/process()
|
||||
|
||||
..()
|
||||
..()
|
||||
|
||||
// Coffee is really bad for you with busted kidneys.
|
||||
// This should probably be expanded in some way, but fucked if I know
|
||||
// what else kidneys can process in our reagent list.
|
||||
var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
|
||||
if(coffee)
|
||||
if(is_bruised())
|
||||
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
|
||||
else if(is_broken())
|
||||
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
/datum/organ/internal/brain
|
||||
name = "brain"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/brain
|
||||
vital = 1
|
||||
|
||||
/datum/organ/internal/brain/xeno
|
||||
removed_type = /obj/item/organ/brain/xeno
|
||||
|
||||
/datum/organ/internal/brain/golem
|
||||
name = "golem chem"
|
||||
removed_type = /obj/item/organ/brain/golem
|
||||
|
||||
/datum/organ/internal/brain/slime
|
||||
name = "slime core"
|
||||
removed_type = /obj/item/organ/brain/slime
|
||||
|
||||
/datum/organ/internal/eyes
|
||||
name = "eyes"
|
||||
parent_organ = "head"
|
||||
removed_type = /obj/item/organ/eyes
|
||||
|
||||
process() //Eye damage replaces the old eye_stat var.
|
||||
..()
|
||||
// Coffee is really bad for you with busted kidneys.
|
||||
// This should probably be expanded in some way, but fucked if I know
|
||||
// what else kidneys can process in our reagent list.
|
||||
var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
|
||||
if(coffee)
|
||||
if(is_bruised())
|
||||
owner.eye_blurry = 20
|
||||
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
|
||||
else if(is_broken())
|
||||
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
|
||||
|
||||
|
||||
/obj/item/organ/eyes
|
||||
name = "eyeballs"
|
||||
icon_state = "eyes"
|
||||
gender = PLURAL
|
||||
organ_tag = "eyes"
|
||||
parent_organ = "head"
|
||||
var/list/eye_colour = list(0,0,0)
|
||||
|
||||
/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var.
|
||||
..()
|
||||
if(!owner)
|
||||
return
|
||||
if(is_bruised())
|
||||
owner.eye_blurry = 20
|
||||
if(is_broken())
|
||||
owner.eye_blind = 20
|
||||
|
||||
/obj/item/organ/eyes/New()
|
||||
..()
|
||||
if(owner)
|
||||
eye_colour = list(
|
||||
owner.r_eyes ? owner.r_eyes : 0,
|
||||
owner.g_eyes ? owner.g_eyes : 0,
|
||||
owner.b_eyes ? owner.b_eyes : 0
|
||||
)
|
||||
|
||||
/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
if(!eye_colour)
|
||||
eye_colour = list(0,0,0)
|
||||
|
||||
..() //Make sure target is set so we can steal their eye colour for later.
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(istype(H))
|
||||
eye_colour = list(
|
||||
H.r_eyes ? H.r_eyes : 0,
|
||||
H.g_eyes ? H.g_eyes : 0,
|
||||
H.b_eyes ? H.b_eyes : 0
|
||||
)
|
||||
|
||||
// Leave bloody red pits behind!
|
||||
H.r_eyes = 128
|
||||
H.g_eyes = 0
|
||||
H.b_eyes = 0
|
||||
H.update_body()
|
||||
|
||||
|
||||
/obj/item/organ/liver
|
||||
name = "liver"
|
||||
icon_state = "liver"
|
||||
organ_tag = "liver"
|
||||
parent_organ = "chest"
|
||||
|
||||
/obj/item/organ/liver/process()
|
||||
|
||||
..()
|
||||
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
if (germ_level > INFECTION_LEVEL_ONE)
|
||||
if(prob(1))
|
||||
owner << "\red Your skin itches."
|
||||
if (germ_level > INFECTION_LEVEL_TWO)
|
||||
if(prob(1))
|
||||
spawn owner.vomit()
|
||||
|
||||
if(owner.life_tick % PROCESS_ACCURACY == 0)
|
||||
|
||||
//High toxins levels are dangerous
|
||||
if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin"))
|
||||
//Healthy liver suffers on its own
|
||||
if (src.damage < min_broken_damage)
|
||||
src.damage += 0.2 * PROCESS_ACCURACY
|
||||
//Damaged one shares the fun
|
||||
else
|
||||
var/obj/item/organ/O = pick(owner.internal_organs)
|
||||
if(O)
|
||||
O.damage += 0.2 * PROCESS_ACCURACY
|
||||
|
||||
//Detox can heal small amounts of damage
|
||||
if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin"))
|
||||
src.damage -= 0.2 * PROCESS_ACCURACY
|
||||
|
||||
if(src.damage < 0)
|
||||
src.damage = 0
|
||||
|
||||
// Get the effectiveness of the liver.
|
||||
var/filter_effect = 3
|
||||
if(is_bruised())
|
||||
filter_effect -= 1
|
||||
if(is_broken())
|
||||
owner.eye_blind = 20
|
||||
filter_effect -= 2
|
||||
|
||||
/datum/organ/internal/appendix
|
||||
// Do some reagent filtering/processing.
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
// Damaged liver means some chemicals are very dangerous
|
||||
// The liver is also responsible for clearing out alcohol and toxins.
|
||||
// Ethanol and all drinks are bad.K
|
||||
if(istype(R, /datum/reagent/ethanol))
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
|
||||
owner.reagents.remove_reagent(R.id, R.custom_metabolism*filter_effect)
|
||||
// Can't cope with toxins at all
|
||||
else if(istype(R, /datum/reagent/toxin))
|
||||
if(filter_effect < 3)
|
||||
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
|
||||
owner.reagents.remove_reagent(R.id, ALCOHOL_METABOLISM*filter_effect)
|
||||
|
||||
/obj/item/organ/appendix
|
||||
name = "appendix"
|
||||
icon_state = "appendix"
|
||||
parent_organ = "groin"
|
||||
removed_type = /obj/item/organ/appendix
|
||||
|
||||
/datum/organ/internal/proc/remove(var/mob/user)
|
||||
/obj/item/organ/appendix/removed()
|
||||
|
||||
if(!removed_type) return 0
|
||||
..()
|
||||
|
||||
var/turf/target_loc
|
||||
if(user)
|
||||
target_loc = get_turf(user)
|
||||
else
|
||||
target_loc = get_turf(owner)
|
||||
var/inflamed = 0
|
||||
for(var/datum/disease/appendicitis/appendicitis in owner.viruses)
|
||||
inflamed = 1
|
||||
appendicitis.cure()
|
||||
owner.resistances += appendicitis
|
||||
|
||||
var/obj/item/organ/removed_organ = new removed_type(target_loc)
|
||||
|
||||
if(istype(removed_organ))
|
||||
removed_organ.organ_data = src
|
||||
removed_organ.update()
|
||||
organ_holder = removed_organ
|
||||
|
||||
return removed_organ
|
||||
if(inflamed)
|
||||
icon_state = "appendixinflamed"
|
||||
name = "inflamed appendix"
|
||||
@@ -1,275 +0,0 @@
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
desc = "It looks like it probably just plopped out."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "appendix"
|
||||
|
||||
health = 100 // Process() ticks before death.
|
||||
|
||||
var/fresh = 3 // Squirts of blood left in it.
|
||||
var/dead_icon // Icon used when the organ dies.
|
||||
var/robotic // Is the limb prosthetic?
|
||||
var/organ_tag // What slot does it go in?
|
||||
var/organ_type = /datum/organ/internal // Used to spawn the relevant organ data when produced via a machine or spawn().
|
||||
var/datum/organ/internal/organ_data // Stores info when removed.
|
||||
var/prosthetic_name = "prosthetic organ" // Flavour string for robotic organ.
|
||||
var/prosthetic_icon // Icon for robotic organ.
|
||||
|
||||
/obj/item/organ/attack_self(mob/user as mob)
|
||||
|
||||
// Convert it to an edible form, yum yum.
|
||||
if(!robotic && user.a_intent == I_HELP && user.zone_sel.selecting == "mouth")
|
||||
bitten(user)
|
||||
return
|
||||
|
||||
/obj/item/organ/New()
|
||||
..()
|
||||
create_reagents(5)
|
||||
if(!robotic)
|
||||
processing_objects += src
|
||||
spawn(1)
|
||||
update()
|
||||
|
||||
/obj/item/organ/Del()
|
||||
if(!robotic) processing_objects -= src
|
||||
..()
|
||||
|
||||
/obj/item/organ/process()
|
||||
|
||||
if(robotic)
|
||||
processing_objects -= src
|
||||
return
|
||||
|
||||
// Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature?
|
||||
if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer))
|
||||
return
|
||||
|
||||
if(fresh && prob(40))
|
||||
fresh--
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
health -= rand(1,3)
|
||||
if(health <= 0)
|
||||
die()
|
||||
|
||||
/obj/item/organ/proc/die()
|
||||
name = "dead [initial(name)]"
|
||||
if(dead_icon) icon_state = dead_icon
|
||||
health = 0
|
||||
processing_objects -= src
|
||||
//TODO: Grey out the icon state.
|
||||
//TODO: Inject an organ with peridaxon to make it alive again.
|
||||
|
||||
/obj/item/organ/proc/roboticize()
|
||||
|
||||
robotic = (organ_data && organ_data.robotic) ? organ_data.robotic : 1
|
||||
|
||||
if(prosthetic_name)
|
||||
name = prosthetic_name
|
||||
|
||||
if(prosthetic_icon)
|
||||
icon_state = prosthetic_icon
|
||||
else
|
||||
//TODO: convert to greyscale.
|
||||
|
||||
/obj/item/organ/proc/update()
|
||||
|
||||
if(!organ_data)
|
||||
organ_data = new organ_type()
|
||||
|
||||
if(robotic)
|
||||
organ_data.robotic = robotic
|
||||
|
||||
if(organ_data.robotic >= 2)
|
||||
roboticize()
|
||||
|
||||
// Brain is defined in brain_item.dm.
|
||||
/obj/item/organ/heart
|
||||
name = "heart"
|
||||
icon_state = "heart-on"
|
||||
prosthetic_name = "circulatory pump"
|
||||
prosthetic_icon = "heart-prosthetic"
|
||||
organ_tag = "heart"
|
||||
fresh = 6 // Juicy.
|
||||
dead_icon = "heart-off"
|
||||
organ_type = /datum/organ/internal/heart
|
||||
|
||||
/obj/item/organ/lungs
|
||||
name = "lungs"
|
||||
icon_state = "lungs"
|
||||
gender = PLURAL
|
||||
prosthetic_name = "gas exchange system"
|
||||
prosthetic_icon = "lungs-prosthetic"
|
||||
organ_tag = "lungs"
|
||||
organ_type = /datum/organ/internal/lungs
|
||||
|
||||
/obj/item/organ/kidneys
|
||||
name = "kidneys"
|
||||
icon_state = "kidneys"
|
||||
gender = PLURAL
|
||||
prosthetic_name = "prosthetic kidneys"
|
||||
prosthetic_icon = "kidneys-prosthetic"
|
||||
organ_tag = "kidneys"
|
||||
organ_type = /datum/organ/internal/kidney
|
||||
|
||||
/obj/item/organ/eyes
|
||||
name = "eyeballs"
|
||||
icon_state = "eyes"
|
||||
gender = PLURAL
|
||||
prosthetic_name = "visual prosthesis"
|
||||
prosthetic_icon = "eyes-prosthetic"
|
||||
organ_tag = "eyes"
|
||||
organ_type = /datum/organ/internal/eyes
|
||||
var/eye_colour
|
||||
|
||||
/obj/item/organ/liver
|
||||
name = "liver"
|
||||
icon_state = "liver"
|
||||
prosthetic_name = "toxin filter"
|
||||
prosthetic_icon = "liver-prosthetic"
|
||||
organ_tag = "liver"
|
||||
organ_type = /datum/organ/internal/liver
|
||||
|
||||
/obj/item/organ/appendix
|
||||
name = "appendix"
|
||||
icon_state = "appendix"
|
||||
organ_tag = "appendix"
|
||||
organ_type = /datum/organ/internal/appendix
|
||||
|
||||
//These are here so they can be printed out via the fabricator.
|
||||
/obj/item/organ/heart/prosthetic
|
||||
robotic = 2
|
||||
|
||||
/obj/item/organ/lungs/prosthetic
|
||||
robotic = 2
|
||||
|
||||
/obj/item/organ/kidneys/prosthetic
|
||||
robotic = 2
|
||||
|
||||
/obj/item/organ/eyes/prosthetic
|
||||
robotic = 2
|
||||
|
||||
/obj/item/organ/liver/prosthetic
|
||||
robotic = 2
|
||||
|
||||
/obj/item/organ/appendix
|
||||
name = "appendix"
|
||||
|
||||
/obj/item/organ/proc/removed(var/mob/living/carbon/human/target,var/mob/living/user)
|
||||
|
||||
if(!istype(target) || !organ_data)
|
||||
return
|
||||
|
||||
target.internal_organs_by_name[organ_tag] = null
|
||||
target.internal_organs_by_name -= organ_tag
|
||||
target.internal_organs -= organ_data
|
||||
|
||||
var/datum/organ/external/affected = target.get_organ(organ_data.parent_organ)
|
||||
affected.internal_organs -= organ_data
|
||||
|
||||
loc = target.loc
|
||||
organ_data.rejecting = null
|
||||
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
if(!organ_blood || !organ_blood.data["blood_DNA"])
|
||||
target.vessel.trans_to(src, 5, 1, 1)
|
||||
|
||||
if(target && user && organ_data.vital)
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
target.attack_log += "\[[time_stamp()]\]<font color='orange'> had a vital organ ([src]) removed by [user.name] ([user.ckey]) (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
msg_admin_attack("[user.name] ([user.ckey]) removed a vital organ ([src]) from [target.name] ([target.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
target.death()
|
||||
|
||||
/obj/item/organ/appendix/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
..()
|
||||
|
||||
var/inflamed = 0
|
||||
for(var/datum/disease/appendicitis/appendicitis in target.viruses)
|
||||
inflamed = 1
|
||||
appendicitis.cure()
|
||||
target.resistances += appendicitis
|
||||
|
||||
if(inflamed)
|
||||
icon_state = "appendixinflamed"
|
||||
name = "inflamed appendix"
|
||||
|
||||
/obj/item/organ/eyes/removed(var/mob/living/target,var/mob/living/user)
|
||||
|
||||
if(!eye_colour)
|
||||
eye_colour = list(0,0,0)
|
||||
|
||||
..() //Make sure target is set so we can steal their eye colour for later.
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(istype(H))
|
||||
eye_colour = list(
|
||||
H.r_eyes ? H.r_eyes : 0,
|
||||
H.g_eyes ? H.g_eyes : 0,
|
||||
H.b_eyes ? H.b_eyes : 0
|
||||
)
|
||||
|
||||
// Leave bloody red pits behind!
|
||||
H.r_eyes = 128
|
||||
H.g_eyes = 0
|
||||
H.b_eyes = 0
|
||||
H.update_body()
|
||||
|
||||
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/datum/organ/external/affected)
|
||||
|
||||
if(!istype(target)) return
|
||||
|
||||
var/datum/reagent/blood/transplant_blood = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
if(!transplant_blood)
|
||||
organ_data.transplant_data = list()
|
||||
organ_data.transplant_data["species"] = target.species.name
|
||||
organ_data.transplant_data["blood_type"] = target.dna.b_type
|
||||
organ_data.transplant_data["blood_DNA"] = target.dna.unique_enzymes
|
||||
else
|
||||
organ_data.transplant_data = list()
|
||||
organ_data.transplant_data["species"] = transplant_blood.data["species"]
|
||||
organ_data.transplant_data["blood_type"] = transplant_blood.data["blood_type"]
|
||||
organ_data.transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
|
||||
|
||||
organ_data.organ_holder = null
|
||||
organ_data.owner = target
|
||||
target.internal_organs |= organ_data
|
||||
affected.internal_organs |= organ_data
|
||||
target.internal_organs_by_name[organ_tag] = organ_data
|
||||
organ_data.status |= ORGAN_CUT_AWAY
|
||||
|
||||
del(src)
|
||||
|
||||
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
|
||||
|
||||
// Apply our eye colour to the target.
|
||||
if(istype(target) && eye_colour)
|
||||
target.r_eyes = eye_colour[1]
|
||||
target.g_eyes = eye_colour[2]
|
||||
target.b_eyes = eye_colour[3]
|
||||
target.update_body()
|
||||
..()
|
||||
|
||||
/obj/item/organ/proc/bitten(mob/user)
|
||||
|
||||
if(robotic)
|
||||
return
|
||||
|
||||
user << "\blue You take an experimental bite out of \the [src]."
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
|
||||
blood_splatter(src,B,1)
|
||||
|
||||
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
|
||||
O.name = name
|
||||
O.icon_state = dead_icon ? dead_icon : icon_state
|
||||
|
||||
// Pass over the blood.
|
||||
reagents.trans_to(O, reagents.total_volume)
|
||||
|
||||
if(fingerprints) O.fingerprints = fingerprints.Copy()
|
||||
if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy()
|
||||
if(fingerprintslast) O.fingerprintslast = fingerprintslast
|
||||
|
||||
user.put_in_active_hand(O)
|
||||
del(src)
|
||||
@@ -0,0 +1,24 @@
|
||||
/obj/item/organ/external/stump
|
||||
name = "limb stump"
|
||||
icon_name = ""
|
||||
dislocated = -1
|
||||
cannot_amputate = 1
|
||||
|
||||
/obj/item/organ/external/stump/New(var/mob/living/carbon/holder, var/internal, var/obj/item/organ/external/limb)
|
||||
if(istype(limb))
|
||||
limb_name = limb.limb_name
|
||||
body_part = limb.body_part
|
||||
amputation_point = limb.amputation_point
|
||||
joint = limb.joint
|
||||
parent_organ = limb.parent_organ
|
||||
wounds = limb.wounds
|
||||
..(holder, internal)
|
||||
if(istype(limb))
|
||||
max_damage = limb.max_damage
|
||||
|
||||
/obj/item/organ/external/stump/is_stump()
|
||||
return 1
|
||||
|
||||
/obj/item/organ/external/stump/removed()
|
||||
..()
|
||||
del(src)
|
||||
@@ -87,10 +87,8 @@ mob/living/carbon/human/proc/handle_pain()
|
||||
if(analgesic)
|
||||
return
|
||||
var/maxdam = 0
|
||||
var/datum/organ/external/damaged_organ = null
|
||||
for(var/datum/organ/external/E in organs)
|
||||
// amputated limbs don't cause pain
|
||||
if(E.amputated) continue
|
||||
var/obj/item/organ/external/damaged_organ = null
|
||||
for(var/obj/item/organ/external/E in organs)
|
||||
if(E.status & ORGAN_DEAD) continue
|
||||
var/dam = E.get_damage()
|
||||
// make the choice of the organ depend on damage,
|
||||
@@ -99,13 +97,13 @@ mob/living/carbon/human/proc/handle_pain()
|
||||
damaged_organ = E
|
||||
maxdam = dam
|
||||
if(damaged_organ)
|
||||
pain(damaged_organ.display_name, maxdam, 0)
|
||||
pain(damaged_organ.name, maxdam, 0)
|
||||
|
||||
// Damage to internal organs hurts a lot.
|
||||
for(var/datum/organ/internal/I in internal_organs)
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
if(I.damage > 2) if(prob(2))
|
||||
var/datum/organ/external/parent = get_organ(I.parent_organ)
|
||||
src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1)
|
||||
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
|
||||
src.custom_pain("You feel a sharp pain in your [parent.name]", 1)
|
||||
|
||||
var/toxDamageMessage = null
|
||||
var/toxMessageProb = 1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
var/global/list/all_robolimbs = list()
|
||||
var/global/list/chargen_robolimbs = list()
|
||||
var/global/datum/robolimb/basic_robolimb
|
||||
|
||||
/proc/populate_robolimb_list()
|
||||
basic_robolimb = new()
|
||||
for(var/limb_type in typesof(/datum/robolimb))
|
||||
var/datum/robolimb/R = new limb_type()
|
||||
all_robolimbs[R.company] = R
|
||||
if(!R.unavailable_at_chargen)
|
||||
chargen_robolimbs[R.company] = R
|
||||
|
||||
/datum/robolimb
|
||||
var/company = "Unbranded" // Shown when selecting the limb.
|
||||
var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb.
|
||||
var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from.
|
||||
var/unavailable_at_chargen // If set, not available at chargen.
|
||||
|
||||
/datum/robolimb/bishop
|
||||
company = "Bishop Cybernetics"
|
||||
desc = "This limb has a white polymer casing with blue holo-displays."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/bishop.dmi'
|
||||
|
||||
/datum/robolimb/hesphaistos
|
||||
company = "Hesphiastos Industries"
|
||||
desc = "This limb has a militaristic black and green casing with gold stripes."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/hesphaistos.dmi'
|
||||
|
||||
/datum/robolimb/zenghu
|
||||
company = "Zeng-Hu Pharmaceuticals"
|
||||
desc = "This limb has a rubbery fleshtone covering with visible seams."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/zenghu.dmi'
|
||||
|
||||
/datum/robolimb/xion
|
||||
company = "Xion Manufacturing Group"
|
||||
desc = "This limb has a minimalist black and red casing."
|
||||
icon = 'icons/mob/human_races/cyberlimbs/xion.dmi'
|
||||
@@ -22,12 +22,13 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/paper_bin/attack_hand(mob/user as mob)
|
||||
if (hasorgans(user))
|
||||
var/datum/organ/external/temp = user:organs_by_name["r_hand"]
|
||||
if (user.hand)
|
||||
temp = user:organs_by_name["l_hand"]
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
||||
if (H.hand)
|
||||
temp = H.organs_by_name["l_hand"]
|
||||
if(temp && !temp.is_usable())
|
||||
user << "<span class='notice'>You try to move your [temp.display_name], but cannot!"
|
||||
user << "<span class='notice'>You try to move your [temp.name], but cannot!"
|
||||
return
|
||||
var/response = ""
|
||||
if(!papers.len > 0)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
src.state = STATE_DEFAULT
|
||||
if("login")
|
||||
var/mob/M = usr
|
||||
var/obj/item/weapon/card/id/I = M.equipped()
|
||||
var/obj/item/weapon/card/id/I = M.get_active_hand()
|
||||
if (I && istype(I))
|
||||
if(src.check_access(I))
|
||||
authenticated = 1
|
||||
|
||||
@@ -171,10 +171,8 @@
|
||||
user << "\red There is already a [fueljar] inside!"
|
||||
return
|
||||
fueljar = W
|
||||
user.remove_from_mob(W)
|
||||
W.loc = src
|
||||
if(user.client)
|
||||
user.client.screen -= W
|
||||
user.u_equip(W)
|
||||
user.update_icons()
|
||||
user.visible_message("[user.name] loads an [W.name] into the [src.name].", \
|
||||
"You load an [W.name].", \
|
||||
|
||||
@@ -516,8 +516,8 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
|
||||
var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
|
||||
return ..()
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
@@ -527,7 +527,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].")
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
@@ -0,0 +1,934 @@
|
||||
///////////////////////////////
|
||||
//CABLE STRUCTURE
|
||||
///////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
/* Cable directions (d1 and d2)
|
||||
|
||||
|
||||
9 1 5
|
||||
\ | /
|
||||
8 - 0 - 4
|
||||
/ | \
|
||||
10 2 6
|
||||
|
||||
If d1 = 0 and d2 = 0, there's no cable
|
||||
If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to dir (knot cable)
|
||||
If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2
|
||||
By design, d1 is the smallest direction and d2 is the highest
|
||||
*/
|
||||
|
||||
/obj/structure/cable
|
||||
level = 1
|
||||
anchored =1
|
||||
var/datum/powernet/powernet
|
||||
name = "power cable"
|
||||
desc = "A flexible superconducting cable for heavy-duty power transfer"
|
||||
icon = 'icons/obj/power_cond_white.dmi'
|
||||
icon_state = "0-1"
|
||||
var/d1 = 0
|
||||
var/d2 = 1
|
||||
layer = 2.44 //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4
|
||||
color = COLOR_RED
|
||||
var/obj/machinery/power/breakerbox/breaker_box
|
||||
|
||||
/obj/structure/cable/drain_power(var/drain_check, var/surge, var/amount = 0)
|
||||
|
||||
if(drain_check)
|
||||
return 1
|
||||
|
||||
var/datum/powernet/PN = get_powernet()
|
||||
if(!PN) return 0
|
||||
|
||||
return PN.draw_power(amount)
|
||||
|
||||
/obj/structure/cable/yellow
|
||||
color = COLOR_YELLOW
|
||||
|
||||
/obj/structure/cable/green
|
||||
color = COLOR_GREEN
|
||||
|
||||
/obj/structure/cable/blue
|
||||
color = COLOR_BLUE
|
||||
|
||||
/obj/structure/cable/pink
|
||||
color = COLOR_PINK
|
||||
|
||||
/obj/structure/cable/orange
|
||||
color = COLOR_ORANGE
|
||||
|
||||
/obj/structure/cable/cyan
|
||||
color = COLOR_CYAN
|
||||
|
||||
/obj/structure/cable/white
|
||||
color = COLOR_WHITE
|
||||
|
||||
/obj/structure/cable/New()
|
||||
..()
|
||||
|
||||
|
||||
// ensure d1 & d2 reflect the icon_state for entering and exiting cable
|
||||
|
||||
var/dash = findtext(icon_state, "-")
|
||||
|
||||
d1 = text2num( copytext( icon_state, 1, dash ) )
|
||||
|
||||
d2 = text2num( copytext( icon_state, dash+1 ) )
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
|
||||
if(level==1) hide(T.intact)
|
||||
cable_list += src //add it to the global cable list
|
||||
|
||||
|
||||
/obj/structure/cable/Del() // called when a cable is deleted
|
||||
if(powernet)
|
||||
cut_cable_from_powernet() // update the powernets
|
||||
cable_list -= src //remove it from global cable list
|
||||
..() // then go ahead and delete the cable
|
||||
|
||||
///////////////////////////////////
|
||||
// General procedures
|
||||
///////////////////////////////////
|
||||
|
||||
//If underfloor, hide the cable
|
||||
/obj/structure/cable/hide(var/i)
|
||||
|
||||
if(level == 1 && istype(loc, /turf))
|
||||
invisibility = i ? 101 : 0
|
||||
updateicon()
|
||||
|
||||
/obj/structure/cable/proc/updateicon()
|
||||
icon_state = "[d1]-[d2]"
|
||||
alpha = invisibility ? 127 : 255
|
||||
|
||||
// returns the powernet this cable belongs to
|
||||
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
|
||||
return powernet
|
||||
|
||||
//Telekinesis has no effect on a cable
|
||||
/obj/structure/cable/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
// Items usable on a cable :
|
||||
// - Wirecutters : cut it duh !
|
||||
// - Cable coil : merge cables
|
||||
// - Multitool : get the power currently passing through the cable
|
||||
//
|
||||
/obj/structure/cable/attackby(obj/item/W, mob/user)
|
||||
|
||||
var/turf/T = src.loc
|
||||
if(T.intact)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
///// Z-Level Stuff
|
||||
if(src.d1 == 12 || src.d2 == 12)
|
||||
user << "<span class='warning'>You must cut this cable from above.</span>"
|
||||
return
|
||||
///// Z-Level Stuff
|
||||
if(breaker_box)
|
||||
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
|
||||
return
|
||||
|
||||
if (shock(user, 50))
|
||||
return
|
||||
|
||||
if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long
|
||||
new/obj/item/stack/cable_coil(T, 2, color)
|
||||
else
|
||||
new/obj/item/stack/cable_coil(T, 1, color)
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span class='warning'>[user] cuts the cable.</span>", 1)
|
||||
|
||||
///// Z-Level Stuff
|
||||
if(src.d1 == 11 || src.d2 == 11)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
for(var/obj/structure/cable/c in below)
|
||||
if(c.d1 == 12 || c.d2 == 12)
|
||||
c.Del()
|
||||
///// Z-Level Stuff
|
||||
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
|
||||
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if (coil.get_amount() < 1)
|
||||
user << "Not enough cable"
|
||||
return
|
||||
coil.cable_join(src, user)
|
||||
|
||||
else if(istype(W, /obj/item/device/multitool))
|
||||
|
||||
if(powernet && (powernet.avail > 0)) // is it powered?
|
||||
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
|
||||
|
||||
else
|
||||
user << "<span class='warning'>The cable is not powered.</span>"
|
||||
|
||||
shock(user, 5, 0.2)
|
||||
|
||||
else
|
||||
if (W.flags & CONDUCT)
|
||||
shock(user, 50, 0.7)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
// shock the user with probability prb
|
||||
/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0)
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
if (electrocute_mob(user, powernet, src, siemens_coeff))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if(usr.stunned)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//explosion handling
|
||||
/obj/structure/cable/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
del(src) // qdel
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
|
||||
del(src) // qdel
|
||||
|
||||
if(3.0)
|
||||
if (prob(25))
|
||||
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
obj/structure/cable/proc/cableColor(var/colorC)
|
||||
var/color_n = "#DD0000"
|
||||
if(colorC)
|
||||
color_n = colorC
|
||||
color = color_n
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Cable laying helpers
|
||||
////////////////////////////////////////////////
|
||||
|
||||
//handles merging diagonally matching cables
|
||||
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
|
||||
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
|
||||
|
||||
//search for and merge diagonally matching cables from the first direction component (north/south)
|
||||
var/turf/T = get_step(src, direction&3)//go north/south
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
|
||||
if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
//the same from the second direction component (east/west)
|
||||
T = get_step(src, direction&12)//go east/west
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
// merge with the powernets of power objects in the given direction
|
||||
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
|
||||
|
||||
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
|
||||
|
||||
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
|
||||
return
|
||||
|
||||
var/turf/TB = get_step(src, direction)
|
||||
|
||||
for(var/obj/structure/cable/C in TB)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
|
||||
if(C.d1 == fdir || C.d2 == fdir) //we've got a matching cable in the neighbor turf
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
// merge with the powernets of power objects in the source turf
|
||||
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
|
||||
var/list/to_connect = list()
|
||||
|
||||
if(!powernet) //if we somehow have no powernet, make one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(src)
|
||||
|
||||
//first let's add turf cables to our powernet
|
||||
//then we'll connect machines on turf with a node cable is present
|
||||
for(var/AM in loc)
|
||||
if(istype(AM,/obj/structure/cable))
|
||||
var/obj/structure/cable/C = AM
|
||||
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
|
||||
if(C.powernet == powernet) continue
|
||||
if(C.powernet)
|
||||
merge_powernets(powernet, C.powernet)
|
||||
else
|
||||
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
|
||||
|
||||
else if(istype(AM,/obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/N = AM
|
||||
if(!N.terminal) continue // APC are connected through their terminal
|
||||
|
||||
if(N.terminal.powernet == powernet)
|
||||
continue
|
||||
|
||||
to_connect += N.terminal //we'll connect the machines after all cables are merged
|
||||
|
||||
else if(istype(AM,/obj/machinery/power)) //other power machines
|
||||
var/obj/machinery/power/M = AM
|
||||
|
||||
if(M.powernet == powernet)
|
||||
continue
|
||||
|
||||
to_connect += M //we'll connect the machines after all cables are merged
|
||||
|
||||
//now that cables are done, let's connect found machines
|
||||
for(var/obj/machinery/power/PM in to_connect)
|
||||
if(!PM.connect_to_network())
|
||||
PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Powernets handling helpers
|
||||
//////////////////////////////////////////////
|
||||
|
||||
//if powernetless_only = 1, will only get connections without powernet
|
||||
/obj/structure/cable/proc/get_connections(var/powernetless_only = 0)
|
||||
. = list() // this will be a list of all connected power objects
|
||||
var/turf/T
|
||||
|
||||
///// Z-Level Stuff
|
||||
if (d1 == 11 || d1 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d1 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d1 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
///// Z-Level Stuff
|
||||
//get matching cables from the first direction
|
||||
else if(d1) //if not a node cable
|
||||
T = get_step(src, d1)
|
||||
if(T)
|
||||
. += power_list(T, src, turn(d1, 180), powernetless_only) //get adjacents matching cables
|
||||
|
||||
if(d1&(d1-1)) //diagonal direction, must check the 4 possibles adjacents tiles
|
||||
T = get_step(src,d1&3) // go north/south
|
||||
if(T)
|
||||
. += power_list(T, src, d1 ^ 3, powernetless_only) //get diagonally matching cables
|
||||
T = get_step(src,d1&12) // go east/west
|
||||
if(T)
|
||||
. += power_list(T, src, d1 ^ 12, powernetless_only) //get diagonally matching cables
|
||||
|
||||
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
|
||||
|
||||
///// Z-Level Stuff
|
||||
if(d2 == 11 || d2 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d2 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d2 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
///// Z-Level Stuff
|
||||
else
|
||||
//do the same on the second direction (which can't be 0)
|
||||
T = get_step(src, d2)
|
||||
if(T)
|
||||
. += power_list(T, src, turn(d2, 180), powernetless_only) //get adjacents matching cables
|
||||
|
||||
if(d2&(d2-1)) //diagonal direction, must check the 4 possibles adjacents tiles
|
||||
T = get_step(src,d2&3) // go north/south
|
||||
if(T)
|
||||
. += power_list(T, src, d2 ^ 3, powernetless_only) //get diagonally matching cables
|
||||
T = get_step(src,d2&12) // go east/west
|
||||
if(T)
|
||||
. += power_list(T, src, d2 ^ 12, powernetless_only) //get diagonally matching cables
|
||||
. += power_list(loc, src, d2, powernetless_only) //get on turf matching cables
|
||||
|
||||
return .
|
||||
|
||||
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
|
||||
//needed as this can, unlike other placements, disconnect cables
|
||||
/obj/structure/cable/proc/denode()
|
||||
var/turf/T1 = loc
|
||||
if(!T1) return
|
||||
|
||||
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
|
||||
if(powerlist.len>0)
|
||||
var/datum/powernet/PN = new()
|
||||
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
|
||||
|
||||
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
|
||||
del(PN) // qdel
|
||||
|
||||
// cut the cable's powernet at this cable and updates the powergrid
|
||||
/obj/structure/cable/proc/cut_cable_from_powernet()
|
||||
var/turf/T1 = loc
|
||||
var/list/P_list
|
||||
if(!T1) return
|
||||
if(d1)
|
||||
T1 = get_step(T1, d1)
|
||||
P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable...
|
||||
|
||||
P_list += power_list(loc, src, d1, 0, cable_only = 1)//... and on turf
|
||||
|
||||
|
||||
if(P_list.len == 0)//if nothing in both list, then the cable was a lone cable, just delete it and its powernet
|
||||
powernet.remove_cable(src)
|
||||
|
||||
for(var/obj/machinery/power/P in T1)//check if it was powering a machine
|
||||
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
|
||||
P.disconnect_from_network() //remove from current network (and delete powernet)
|
||||
return
|
||||
|
||||
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
|
||||
loc = null
|
||||
powernet.remove_cable(src) //remove the cut cable from its powernet
|
||||
|
||||
var/datum/powernet/newPN = new()// creates a new powernet...
|
||||
propagate_network(P_list[1], newPN)//... and propagates it to the other side of the cable
|
||||
|
||||
// Disconnect machines connected to nodes
|
||||
if(d1 == 0) // if we cut a node (O-X) cable
|
||||
for(var/obj/machinery/power/P in T1)
|
||||
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
|
||||
P.disconnect_from_network() //remove from current network
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// The cable coil object, used for laying cable
|
||||
///////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
#define MAXCOIL 30
|
||||
|
||||
/obj/item/stack/cable_coil
|
||||
name = "cable coil"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "coil"
|
||||
amount = MAXCOIL
|
||||
max_amount = MAXCOIL
|
||||
color = COLOR_RED
|
||||
//item_color = COLOR_RED Use regular "color" var instead. No need to have it duplicate in two vars. Causes confusion.
|
||||
desc = "A coil of power cable."
|
||||
throwforce = 10
|
||||
w_class = 2.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
matter = list("metal" = 50, "glass" = 20)
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "coil"
|
||||
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
|
||||
|
||||
/obj/item/stack/cable_coil/cyborg
|
||||
name = "cable coil synthesizer"
|
||||
desc = "A device that makes cable."
|
||||
gender = NEUTER
|
||||
matter = null
|
||||
uses_charge = 1
|
||||
charge_costs = list(1)
|
||||
stacktype = /obj/item/stack/cable_coil
|
||||
|
||||
/obj/item/stack/cable_coil/suicide_act(mob/user)
|
||||
if(locate(/obj/item/weapon/stool) in user.loc)
|
||||
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
return(OXYLOSS)
|
||||
|
||||
/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
|
||||
..()
|
||||
src.amount = length
|
||||
if (param_color) // It should be red by default, so only recolor it if parameter was specified.
|
||||
color = param_color
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
update_icon()
|
||||
update_wclass()
|
||||
|
||||
///////////////////////////////////
|
||||
// General procedures
|
||||
///////////////////////////////////
|
||||
|
||||
//you can use wires to heal robotics
|
||||
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
<<<<<<< HEAD
|
||||
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
|
||||
=======
|
||||
var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
|
||||
>>>>>>> d77010221cbd08f6373edebee25d727b6409413b
|
||||
return ..()
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
if(M == user)
|
||||
user << "\red You can't repair damage to your own body - it's against OH&S."
|
||||
return
|
||||
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].")
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/stack/cable_coil/update_icon()
|
||||
if (!color)
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
if(amount == 1)
|
||||
icon_state = "coil1"
|
||||
name = "cable piece"
|
||||
else if(amount == 2)
|
||||
icon_state = "coil2"
|
||||
name = "cable piece"
|
||||
else
|
||||
icon_state = "coil"
|
||||
name = "cable coil"
|
||||
|
||||
/obj/item/stack/cable_coil/proc/update_wclass()
|
||||
if(amount == 1)
|
||||
w_class = 1.0
|
||||
else
|
||||
w_class = 2.0
|
||||
|
||||
/obj/item/stack/cable_coil/examine(mob/user)
|
||||
if(get_dist(src, user) > 1)
|
||||
return
|
||||
|
||||
if(get_amount() == 1)
|
||||
user << "A short piece of power cable."
|
||||
else if(get_amount() == 2)
|
||||
user << "A piece of power cable."
|
||||
else
|
||||
user << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
|
||||
|
||||
|
||||
/obj/item/stack/cable_coil/verb/make_restraint()
|
||||
set name = "Make Cable Restraints"
|
||||
set category = "Object"
|
||||
var/mob/M = usr
|
||||
|
||||
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
|
||||
if(!istype(usr.loc,/turf)) return
|
||||
if(src.amount <= 14)
|
||||
usr << "\red You need at least 15 lengths to make restraints!"
|
||||
return
|
||||
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
|
||||
B.color = color
|
||||
usr << "<span class='notice'>You wind some cable together to make some restraints.</span>"
|
||||
src.use(15)
|
||||
else
|
||||
usr << "\blue You cannot do that."
|
||||
..()
|
||||
|
||||
/obj/item/stack/cable_coil/cyborg/verb/set_colour()
|
||||
set name = "Change Colour"
|
||||
set category = "Object"
|
||||
|
||||
var/list/possible_colours = list ("Yellow", "Green", "Pink", "Blue", "Orange", "Cyan", "Red")
|
||||
var/selected_type = input("Pick new colour.", "Cable Colour", null, null) as null|anything in possible_colours
|
||||
|
||||
if(selected_type)
|
||||
switch(selected_type)
|
||||
if("Yellow")
|
||||
color = COLOR_YELLOW
|
||||
if("Green")
|
||||
color = COLOR_GREEN
|
||||
if("Pink")
|
||||
color = COLOR_PINK
|
||||
if("Blue")
|
||||
color = COLOR_BLUE
|
||||
if("Orange")
|
||||
color = COLOR_ORANGE
|
||||
if("Cyan")
|
||||
color = COLOR_CYAN
|
||||
else
|
||||
color = COLOR_RED
|
||||
usr << "You change your cable coil's colour to [selected_type]"
|
||||
|
||||
// Items usable on a cable coil :
|
||||
// - Wirecutters : cut them duh !
|
||||
// - Cable coil : merge cables
|
||||
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1)
|
||||
src.use(1)
|
||||
new/obj/item/stack/cable_coil(user.loc, 1,color)
|
||||
user << "You cut a piece off the cable coil."
|
||||
src.update_icon()
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if(C.get_amount() >= get_max_amount())
|
||||
user << "The coil is too long, you cannot add any more cable to it."
|
||||
return
|
||||
|
||||
if( (C.get_amount() + src.get_amount() <= get_max_amount()) )
|
||||
user << "You join the cable coils together."
|
||||
C.give(src.get_amount()) // give it cable
|
||||
src.use(src.get_amount()) // make sure this one cleans up right
|
||||
return
|
||||
|
||||
else
|
||||
var/amt = get_max_amount() - C.get_amount()
|
||||
user << "You transfer [amt] length\s of cable from one coil to the other."
|
||||
C.give(amt)
|
||||
src.use(amt)
|
||||
return
|
||||
|
||||
//remove cables from the stack
|
||||
/* This is probably reduntant
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
if(src.amount < used)
|
||||
return 0
|
||||
else if (src.amount == used)
|
||||
if(ismob(loc)) //handle mob icon update
|
||||
var/mob/M = loc
|
||||
M.unEquip(src)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
amount -= used
|
||||
update_icon()
|
||||
return 1
|
||||
*/
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
. = ..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//add cables to the stack
|
||||
/obj/item/stack/cable_coil/proc/give(var/extra)
|
||||
if(amount + extra > MAXCOIL)
|
||||
amount = MAXCOIL
|
||||
else
|
||||
amount += extra
|
||||
update_icon()
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Cable laying procedures
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// called when cable_coil is clicked on a turf/simulated/floor
|
||||
/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user)
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
|
||||
if(get_amount() < 1) // Out of cable
|
||||
user << "There is no cable left."
|
||||
return
|
||||
|
||||
if(get_dist(F,user) > 1) // Too far
|
||||
user << "You can't lay cable at a place that far away."
|
||||
return
|
||||
|
||||
if(F.intact) // Ff floor is intact, complain
|
||||
user << "You can't lay cable there unless the floor tiles are removed."
|
||||
return
|
||||
|
||||
else
|
||||
var/dirn
|
||||
|
||||
if(user.loc == F)
|
||||
dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing
|
||||
else
|
||||
dirn = get_dir(F, user)
|
||||
|
||||
for(var/obj/structure/cable/LC in F)
|
||||
if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0))
|
||||
user << "<span class='warning'>There's already a cable at that position.</span>"
|
||||
return
|
||||
///// Z-Level Stuff
|
||||
// check if the target is open space
|
||||
if(istype(F, /turf/simulated/floor/open))
|
||||
for(var/obj/structure/cable/LC in F)
|
||||
if((LC.d1 == dirn && LC.d2 == 11 ) || ( LC.d2 == dirn && LC.d1 == 11))
|
||||
user << "<span class='warning'>There's already a cable at that position.</span>"
|
||||
return
|
||||
|
||||
var/turf/simulated/floor/open/temp = F
|
||||
var/obj/structure/cable/C = new(F)
|
||||
var/obj/structure/cable/D = new(temp.floorbelow)
|
||||
|
||||
C.cableColor(color)
|
||||
|
||||
C.d1 = 11
|
||||
C.d2 = dirn
|
||||
C.add_fingerprint(user)
|
||||
C.updateicon()
|
||||
|
||||
var/datum/powernet/PN = new()
|
||||
PN.add_cable(C)
|
||||
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
|
||||
D.cableColor(color)
|
||||
|
||||
D.d1 = 12
|
||||
D.d2 = 0
|
||||
D.add_fingerprint(user)
|
||||
D.updateicon()
|
||||
|
||||
PN.add_cable(D)
|
||||
D.mergeConnectedNetworksOnTurf()
|
||||
|
||||
// do the normal stuff
|
||||
else
|
||||
///// Z-Level Stuff
|
||||
for(var/obj/structure/cable/LC in F)
|
||||
if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0))
|
||||
user << "There's already a cable at that position."
|
||||
return
|
||||
|
||||
var/obj/structure/cable/C = new(F)
|
||||
|
||||
C.cableColor(color)
|
||||
|
||||
//set up the new cable
|
||||
C.d1 = 0 //it's a O-X node cable
|
||||
C.d2 = dirn
|
||||
C.add_fingerprint(user)
|
||||
C.updateicon()
|
||||
|
||||
//create a new powernet with the cable, if needed it will be merged later
|
||||
var/datum/powernet/PN = new()
|
||||
PN.add_cable(C)
|
||||
|
||||
C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets
|
||||
C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
|
||||
|
||||
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d2)
|
||||
|
||||
|
||||
use(1)
|
||||
if (C.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(C.loc, 1, C.color)
|
||||
del(C) // qdel
|
||||
|
||||
// called when cable_coil is click on an installed obj/cable
|
||||
// or click on a turf that already contains a "node" cable
|
||||
/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user)
|
||||
var/turf/U = user.loc
|
||||
if(!isturf(U))
|
||||
return
|
||||
|
||||
var/turf/T = C.loc
|
||||
|
||||
if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable
|
||||
return
|
||||
|
||||
if(get_dist(C, user) > 1) // make sure it's close enough
|
||||
user << "You can't lay cable at a place that far away."
|
||||
return
|
||||
|
||||
|
||||
if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing
|
||||
turf_place(T,user)
|
||||
return
|
||||
|
||||
var/dirn = get_dir(C, user)
|
||||
|
||||
// one end of the clicked cable is pointing towards us
|
||||
if(C.d1 == dirn || C.d2 == dirn)
|
||||
if(U.intact) // can't place a cable if the floor is complete
|
||||
user << "You can't lay cable there unless the floor tiles are removed."
|
||||
return
|
||||
else
|
||||
// cable is pointing at us, we're standing on an open tile
|
||||
// so create a stub pointing at the clicked cable on our tile
|
||||
|
||||
var/fdirn = turn(dirn, 180) // the opposite direction
|
||||
|
||||
for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already
|
||||
if(LC.d1 == fdirn || LC.d2 == fdirn)
|
||||
user << "There's already a cable at that position."
|
||||
return
|
||||
|
||||
var/obj/structure/cable/NC = new(U)
|
||||
NC.cableColor(color)
|
||||
|
||||
NC.d1 = 0
|
||||
NC.d2 = fdirn
|
||||
NC.add_fingerprint()
|
||||
NC.updateicon()
|
||||
|
||||
//create a new powernet with the cable, if needed it will be merged later
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(NC)
|
||||
|
||||
NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets
|
||||
NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
|
||||
|
||||
if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
NC.mergeDiagonalsNetworks(NC.d2)
|
||||
|
||||
use(1)
|
||||
|
||||
if (NC.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(NC.loc, 1, NC.color)
|
||||
del(NC) // qdel
|
||||
|
||||
return
|
||||
|
||||
// exisiting cable doesn't point at our position, so see if it's a stub
|
||||
else if(C.d1 == 0)
|
||||
// if so, make it a full cable pointing from it's old direction to our dirn
|
||||
var/nd1 = C.d2 // these will be the new directions
|
||||
var/nd2 = dirn
|
||||
|
||||
|
||||
if(nd1 > nd2) // swap directions to match icons/states
|
||||
nd1 = dirn
|
||||
nd2 = C.d2
|
||||
|
||||
|
||||
for(var/obj/structure/cable/LC in T) // check to make sure there's no matching cable
|
||||
if(LC == C) // skip the cable we're interacting with
|
||||
continue
|
||||
if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
|
||||
user << "There's already a cable at that position."
|
||||
return
|
||||
|
||||
|
||||
C.cableColor(color)
|
||||
|
||||
C.d1 = nd1
|
||||
C.d2 = nd2
|
||||
|
||||
C.add_fingerprint()
|
||||
C.updateicon()
|
||||
|
||||
|
||||
C.mergeConnectedNetworks(C.d1) //merge the powernets...
|
||||
C.mergeConnectedNetworks(C.d2) //...in the two new cable directions
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
|
||||
if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d1)
|
||||
|
||||
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d2)
|
||||
|
||||
use(1)
|
||||
|
||||
if (C.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(C.loc, 2, C.color)
|
||||
del(C) // qdel
|
||||
return
|
||||
|
||||
C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets.
|
||||
return
|
||||
|
||||
//////////////////////////////
|
||||
// Misc.
|
||||
/////////////////////////////
|
||||
|
||||
/obj/item/stack/cable_coil/cut
|
||||
item_state = "coil2"
|
||||
|
||||
/obj/item/stack/cable_coil/cut/New(loc)
|
||||
..()
|
||||
src.amount = rand(1,2)
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
update_icon()
|
||||
update_wclass()
|
||||
|
||||
/obj/item/stack/cable_coil/yellow
|
||||
color = COLOR_YELLOW
|
||||
|
||||
/obj/item/stack/cable_coil/blue
|
||||
color = COLOR_BLUE
|
||||
|
||||
/obj/item/stack/cable_coil/green
|
||||
color = COLOR_GREEN
|
||||
|
||||
/obj/item/stack/cable_coil/pink
|
||||
color = COLOR_PINK
|
||||
|
||||
/obj/item/stack/cable_coil/orange
|
||||
color = COLOR_ORANGE
|
||||
|
||||
/obj/item/stack/cable_coil/cyan
|
||||
color = COLOR_CYAN
|
||||
|
||||
/obj/item/stack/cable_coil/white
|
||||
color = COLOR_WHITE
|
||||
|
||||
/obj/item/stack/cable_coil/random/New()
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
..()
|
||||
@@ -3,6 +3,10 @@
|
||||
name = "gun"
|
||||
desc = "Its a gun. It's pretty terrible, though."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
item_icons = list(
|
||||
icon_l_hand = 'icons/mob/items/lefthand_guns.dmi',
|
||||
icon_r_hand = 'icons/mob/items/righthand_guns.dmi',
|
||||
)
|
||||
icon_state = "detective"
|
||||
item_state = "gun"
|
||||
flags = CONDUCT
|
||||
@@ -134,10 +138,7 @@
|
||||
handle_post_fire(user, target, pointblank, reflex)
|
||||
|
||||
update_icon()
|
||||
if(user.hand)
|
||||
user.update_inv_l_hand()
|
||||
else
|
||||
user.update_inv_r_hand()
|
||||
update_held_icon()
|
||||
|
||||
|
||||
//obtains the next projectile to fire
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
/obj/item/weapon/gun/launcher/spikethrower/special_check(user)
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis")
|
||||
if(H.species && H.species.name != "Vox")
|
||||
user << "<span class='warning'>\The [src] does not respond to you!</span>"
|
||||
return 0
|
||||
return ..()
|
||||
@@ -52,56 +52,3 @@
|
||||
if(spikes < 1) return null
|
||||
spikes--
|
||||
return new /obj/item/weapon/spike(src)
|
||||
|
||||
//This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites.
|
||||
/obj/item/weapon/gun/energy/noisecannon
|
||||
name = "alien heavy cannon"
|
||||
desc = "It's some kind of enormous alien weapon, as long as a man is tall."
|
||||
|
||||
icon = 'icons/obj/gun.dmi' //Actual on-sprite is handled by icon_override.
|
||||
icon_state = "noisecannon"
|
||||
item_state = "noisecannon"
|
||||
recoil = 1
|
||||
|
||||
force = 10
|
||||
projectile_type = /obj/item/projectile/energy/sonic
|
||||
cell_type = /obj/item/weapon/cell/super
|
||||
fire_delay = 40
|
||||
fire_sound = 'sound/effects/basscannon.ogg'
|
||||
|
||||
var/mode = 1
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/held.dmi'
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob)
|
||||
if(loc != user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H))
|
||||
if(H.species.name == "Vox Armalis")
|
||||
..()
|
||||
return
|
||||
user << "<span class='warning'>\The [src] is far too large for you to pick up.</span>"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/noisecannon/update_icon()
|
||||
return
|
||||
|
||||
//Projectile.
|
||||
/obj/item/projectile/energy/sonic
|
||||
name = "distortion"
|
||||
icon = 'icons/obj/machines/particle_accelerator2.dmi'
|
||||
icon_state = "particle"
|
||||
damage = 60
|
||||
damage_type = BRUTE
|
||||
check_armour = "bullet"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
|
||||
embed = 0
|
||||
weaken = 5
|
||||
stun = 5
|
||||
|
||||
/obj/item/projectile/energy/sonic/proc/split()
|
||||
//TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf.
|
||||
return
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
power_supply.give(power_supply.maxcharge)
|
||||
if(self_recharge)
|
||||
processing_objects.Add(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/Del()
|
||||
if(self_recharge)
|
||||
@@ -87,3 +88,4 @@
|
||||
icon_state = "[modifystate][ratio]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)][ratio]"
|
||||
|
||||
|
||||
@@ -24,16 +24,18 @@
|
||||
obj/item/weapon/gun/energy/retro
|
||||
name = "retro laser"
|
||||
icon_state = "retro"
|
||||
item_state = "retro"
|
||||
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 3
|
||||
projectile_type = /obj/item/projectile/beam
|
||||
fire_delay = 10
|
||||
fire_delay = 10 //old technology
|
||||
|
||||
/obj/item/weapon/gun/energy/captain
|
||||
name = "antique laser gun"
|
||||
icon_state = "caplaser"
|
||||
item_state = "caplaser"
|
||||
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
|
||||
force = 5
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
@@ -48,7 +50,7 @@ obj/item/weapon/gun/energy/retro
|
||||
name = "laser cannon"
|
||||
desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
|
||||
icon_state = "lasercannon"
|
||||
item_state = "laser"
|
||||
item_state = null
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
origin_tech = "combat=4;materials=3;powerstorage=3"
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
@@ -57,6 +59,7 @@ obj/item/weapon/gun/energy/retro
|
||||
fire_delay = 20
|
||||
|
||||
/obj/item/weapon/gun/energy/lasercannon/mounted
|
||||
name = "mounted laser cannon"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
recharge_time = 10
|
||||
@@ -65,6 +68,7 @@ obj/item/weapon/gun/energy/retro
|
||||
name = "xray laser gun"
|
||||
desc = "A high-power laser gun capable of expelling concentrated xray blasts."
|
||||
icon_state = "xray"
|
||||
item_state = "xray"
|
||||
fire_sound = 'sound/weapons/laser3.ogg'
|
||||
origin_tech = "combat=5;materials=3;magnets=2;syndicate=2"
|
||||
projectile_type = /obj/item/projectile/beam/xray
|
||||
@@ -116,10 +120,12 @@ obj/item/weapon/gun/energy/retro
|
||||
|
||||
/obj/item/weapon/gun/energy/lasertag/blue
|
||||
icon_state = "bluetag"
|
||||
item_state = "bluetag"
|
||||
projectile_type = /obj/item/projectile/beam/lastertag/blue
|
||||
required_vest = /obj/item/clothing/suit/bluetag
|
||||
|
||||
/obj/item/weapon/gun/energy/lasertag/red
|
||||
icon_state = "redtag"
|
||||
item_state = "redtag"
|
||||
projectile_type = /obj/item/projectile/beam/lastertag/red
|
||||
required_vest = /obj/item/clothing/suit/redtag
|
||||
|
||||
@@ -29,12 +29,10 @@
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
modifystate = "energystun"
|
||||
update_icon()
|
||||
if(user.l_hand == src)
|
||||
user.update_inv_l_hand()
|
||||
else
|
||||
user.update_inv_r_hand()
|
||||
update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mounted
|
||||
name = "mounted energy gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
name = "biological demolecularisor"
|
||||
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
|
||||
icon_state = "decloner"
|
||||
item_state = "decloner"
|
||||
fire_sound = 'sound/weapons/pulse3.ogg'
|
||||
origin_tech = "combat=5;materials=4;powerstorage=3"
|
||||
charge_cost = 100
|
||||
@@ -35,7 +36,7 @@
|
||||
name = "floral somatoray"
|
||||
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
|
||||
icon_state = "floramut100"
|
||||
item_state = "obj/item/gun.dmi"
|
||||
item_state = "floramut"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
charge_cost = 100
|
||||
projectile_type = /obj/item/projectile/energy/floramut
|
||||
@@ -59,7 +60,7 @@
|
||||
projectile_type = /obj/item/projectile/energy/floramut
|
||||
modifystate = "floramut"
|
||||
update_icon()
|
||||
return
|
||||
update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag)
|
||||
//allow shooting into adjacent hydrotrays regardless of intent
|
||||
@@ -115,6 +116,7 @@
|
||||
name = "staff of change"
|
||||
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
item_icons = null
|
||||
icon_state = "staffofchange"
|
||||
item_state = "staffofchange"
|
||||
fire_sound = 'sound/weapons/emitter.ogg'
|
||||
@@ -168,6 +170,7 @@ obj/item/weapon/gun/energy/staff/focus
|
||||
desc = "It's a cute rubber duck. With an evil gleam in it's eye."
|
||||
projectile_type = /obj/item/projectile/icarus/pointdefense
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
item_icons = null
|
||||
icon_state = "rubberducky"
|
||||
item_state = "rubberducky"
|
||||
charge_cost = 0
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
cell_type = /obj/item/weapon/cell/crap
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted
|
||||
name = "mounted taser gun"
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
|
||||
/obj/item/weapon/gun/energy/taser/mounted/cyborg
|
||||
name = "taser gun"
|
||||
cell_type = /obj/item/weapon/cell/secborg
|
||||
recharge_time = 10 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
@@ -21,6 +23,7 @@
|
||||
name = "stun revolver"
|
||||
desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger."
|
||||
icon_state = "stunrevolver"
|
||||
item_state = "stunrevolver"
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
origin_tech = "combat=3;materials=3;powerstorage=2"
|
||||
charge_cost = 125
|
||||
|
||||
@@ -105,14 +105,14 @@
|
||||
current_user = user
|
||||
user.visible_message("[user] begins to draw back the string of [src].","<span class='notice'>You begin to draw back the string of [src].</span>")
|
||||
tension = 1
|
||||
|
||||
|
||||
while(bolt && tension && current_user == user)
|
||||
if(!do_after(user, 25)) //crossbow strings don't just magically pull back on their own.
|
||||
user.visible_message("[usr] stops drawing and relaxes the string of [src].","<span class='warning'>You stop drawing back and relax the string of [src].</span>")
|
||||
tension = 0
|
||||
icon_state = "crossbow"
|
||||
return
|
||||
|
||||
|
||||
tension++
|
||||
icon_state = "crossbow-drawn"
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
tension = max_tension
|
||||
usr << "[src] clunks as you draw the string to its maximum tension!"
|
||||
return
|
||||
|
||||
|
||||
user.visible_message("[usr] draws back the string of [src]!","<span class='notice'>You continue drawing back the string of [src]!</span>")
|
||||
|
||||
/obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
for(var/obj/item/O in src.contents)
|
||||
total_stored += O.get_storage_cost()
|
||||
if(total_stored + W.get_storage_cost() <= max_storage_space)
|
||||
user.drop_item(W)
|
||||
user.remove_from_mob(W)
|
||||
W.loc = src
|
||||
user << "You shove [W] into the hopper."
|
||||
else
|
||||
|
||||
@@ -133,4 +133,5 @@
|
||||
name = "syringe gun revolver"
|
||||
desc = "A modification of the syringe gun design, using a rotating cylinder to store up to five syringes. The spring still needs to be drawn between shots."
|
||||
icon_state = "rapidsyringegun"
|
||||
item_state = "rapidsyringegun"
|
||||
max_darts = 5
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
name = "\improper STS-35 automatic rifle"
|
||||
desc = "A durable, rugged looking automatic weapon of a make popular on the frontier worlds. Uses 7.62mm rounds. It is unmarked."
|
||||
icon_state = "arifle"
|
||||
item_state = "l6closednomag" //placeholder
|
||||
item_state = null
|
||||
w_class = 4
|
||||
force = 10
|
||||
caliber = "a762"
|
||||
@@ -63,12 +63,13 @@
|
||||
/obj/item/weapon/gun/projectile/automatic/sts35/update_icon()
|
||||
..()
|
||||
icon_state = (ammo_magazine)? "arifle-0" : "arifle"
|
||||
update_held_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550
|
||||
name = "\improper W-T 550 Saber"
|
||||
desc = "A cheap, mass produced Ward-Takahashi PDW. Uses 9mm rounds."
|
||||
icon_state = "wt550"
|
||||
item_state = "c20r" //placeholder
|
||||
item_state = "wt550"
|
||||
w_class = 3
|
||||
caliber = "9mm"
|
||||
origin_tech = "combat=5;materials=2"
|
||||
@@ -90,7 +91,7 @@
|
||||
name = "\improper Z8 Bulldog"
|
||||
desc = "An older model bullpup carbine, made by the now defunct Zendai Foundries. Uses armor piercing 5.56mm rounds. Makes you feel like a space marine when you hold it."
|
||||
icon_state = "carbine"
|
||||
item_state = "l6closednomag" //placeholder
|
||||
item_state = "z8carbine"
|
||||
w_class = 4
|
||||
force = 10
|
||||
caliber = "a556"
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
name = "dart gun"
|
||||
desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances."
|
||||
icon_state = "dartgun-empty"
|
||||
item_state = null
|
||||
|
||||
caliber = "dart"
|
||||
fire_sound = 'sound/weapons/empty.ogg'
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
name = "desert eagle"
|
||||
desc = "A robust handgun that uses .50 AE ammo"
|
||||
icon_state = "deagle"
|
||||
item_state = "deagle"
|
||||
force = 14.0
|
||||
caliber = ".50"
|
||||
load_method = MAGAZINE
|
||||
@@ -107,6 +108,7 @@
|
||||
name = "\improper Stechtkin pistol"
|
||||
desc = "A small, easily concealable gun. Uses 9mm rounds."
|
||||
icon_state = "pistol"
|
||||
item_state = null
|
||||
w_class = 2
|
||||
caliber = "9mm"
|
||||
silenced = 0
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "revolver"
|
||||
desc = "A classic revolver. Uses .357 ammo"
|
||||
icon_state = "revolver"
|
||||
item_state = "revolver"
|
||||
caliber = "357"
|
||||
origin_tech = "combat=2;materials=2"
|
||||
handle_casings = CYCLE_CASINGS
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
name = "combat shotgun"
|
||||
icon_state = "cshotgun"
|
||||
item_state = "cshotgun"
|
||||
origin_tech = "combat=5;materials=2"
|
||||
max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8.
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
@@ -51,7 +52,7 @@
|
||||
name = "double-barreled shotgun"
|
||||
desc = "A true classic."
|
||||
icon_state = "dshotgun"
|
||||
item_state = "shotgun"
|
||||
item_state = "dshotgun"
|
||||
//SPEEDLOADER because rapid unloading.
|
||||
//In principle someone could make a speedloader for it, so it makes sense.
|
||||
load_method = SINGLE_CASING|SPEEDLOADER
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
var/mob/living/M = loc
|
||||
if(M == T) return
|
||||
if(!istype(M)) return
|
||||
if(src != M.equipped())
|
||||
if(src != M.get_active_hand())
|
||||
stop_aim()
|
||||
return
|
||||
|
||||
|
||||
@@ -655,7 +655,7 @@
|
||||
user << "\The [O] is not suitable for blending."
|
||||
return 1
|
||||
|
||||
user.before_take_item(O)
|
||||
user.remove_from_mob(O)
|
||||
O.loc = src
|
||||
holdingitems += O
|
||||
src.updateUsrDialog()
|
||||
@@ -794,4 +794,4 @@
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
break
|
||||
|
||||
#undef REAGENTS_PER_SHEET
|
||||
#undef REAGENTS_PER_SHEET
|
||||
|
||||
@@ -670,7 +670,7 @@ datum
|
||||
if(prob(50))
|
||||
M.radiation += 50 // curing it that way may kill you instead
|
||||
var/absorbed
|
||||
var/datum/organ/internal/diona/nutrients/rad_organ = locate() in C.internal_organs
|
||||
var/obj/item/organ/diona/nutrients/rad_organ = locate() in C.internal_organs
|
||||
if(rad_organ && !rad_organ.is_broken())
|
||||
absorbed = 1
|
||||
if(!absorbed)
|
||||
@@ -1284,7 +1284,7 @@ datum
|
||||
M.eye_blind = max(M.eye_blind-5 , 0)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
if(E && istype(E))
|
||||
if(E.damage > 0)
|
||||
E.damage = max(E.damage - 1, 0)
|
||||
@@ -1306,7 +1306,7 @@ datum
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
//Peridaxon heals only non-robotic organs
|
||||
for(var/datum/organ/internal/I in H.internal_organs)
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
if((I.damage > 0) && (I.robotic != 2))
|
||||
I.damage = max(I.damage - 0.20, 0)
|
||||
..()
|
||||
@@ -2057,7 +2057,7 @@ datum
|
||||
if(!M.unacidable)
|
||||
if(istype(M, /mob/living/carbon/human) && volume >= 10)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/affecting = H.get_organ("head")
|
||||
var/obj/item/organ/external/affecting = H.get_organ("head")
|
||||
if(affecting)
|
||||
if(affecting.take_damage(4*toxpwr, 2*toxpwr))
|
||||
H.UpdateDamageIcon()
|
||||
@@ -3332,7 +3332,7 @@ datum
|
||||
M:drowsyness = max(M:drowsyness, 30)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/liver/L = H.internal_organs_by_name["liver"]
|
||||
var/obj/item/organ/liver/L = H.internal_organs_by_name["liver"]
|
||||
if (!L)
|
||||
H.adjustToxLoss(5)
|
||||
else if(istype(L))
|
||||
@@ -3654,13 +3654,13 @@ datum
|
||||
if(prob(30)) M.adjustToxLoss(2)
|
||||
if(prob(5)) if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"]
|
||||
var/obj/item/organ/heart/L = H.internal_organs_by_name["heart"]
|
||||
if (L && istype(L))
|
||||
L.take_damage(5, 0)
|
||||
if (300 to INFINITY)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/heart/L = H.internal_organs_by_name["heart"]
|
||||
var/obj/item/organ/heart/L = H.internal_organs_by_name["heart"]
|
||||
if (L && istype(L))
|
||||
L.take_damage(100, 0)
|
||||
holder.remove_reagent(src.id, FOOD_METABOLISM)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
force = 15 //Smashing bottles over someoen's head hurts.
|
||||
|
||||
var/datum/organ/external/affecting = user.zone_sel.selecting //Find what the player is aiming at
|
||||
var/obj/item/organ/external/affecting = user.zone_sel.selecting //Find what the player is aiming at
|
||||
|
||||
var/armor_block = 0 //Get the target's armour values for normal attack damage.
|
||||
var/armor_duration = 0 //The more force the bottle has, the longer the duration.
|
||||
|
||||
@@ -165,9 +165,7 @@
|
||||
return
|
||||
|
||||
user << "\red You slip [W] inside [src]."
|
||||
user.u_equip(W)
|
||||
if ((user.client && user.s_active != src))
|
||||
user.client.screen -= W
|
||||
user.remove_from_mob(W)
|
||||
W.dropped(user)
|
||||
add_fingerprint(user)
|
||||
contents += W
|
||||
@@ -1576,9 +1574,9 @@
|
||||
surprise.transform *= 0.6
|
||||
surprise.add_blood(M)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/E = H.get_organ("chest")
|
||||
var/obj/item/organ/external/E = H.get_organ("chest")
|
||||
E.fracture()
|
||||
for (var/datum/organ/internal/I in E.internal_organs)
|
||||
for (var/obj/item/organ/I in E.internal_organs)
|
||||
I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1))
|
||||
|
||||
if (!E.hidden && prob(60)) //set it snuggly
|
||||
|
||||
@@ -249,8 +249,8 @@
|
||||
reagents.add_reagent("synaptizine", 5)
|
||||
reagents.add_reagent("hyperzine", 5)
|
||||
|
||||
/obj/item/weapon/reagent_containers/pill/spaceacillin
|
||||
name = "Spaceacillin"
|
||||
/obj/item/weapon/reagent_containers/pill/spaceacillin
|
||||
name = "Spaceacillin pill"
|
||||
desc = "Contains antiviral agents."
|
||||
icon_state = "pill19"
|
||||
New()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user