Merge remote-tracking branch 'upstream/dev' into CultVisualNetwork

Conflicts:
	code/setup.dm
This commit is contained in:
PsiOmega
2015-04-01 12:47:31 +02:00
213 changed files with 7050 additions and 4292 deletions
+1
View File
@@ -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)
+6 -28
View File
@@ -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)
+2 -2
View File
@@ -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()
+26 -26
View File
@@ -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)
+1 -1
View File
@@ -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)
+33 -8
View File
@@ -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
+7 -20
View File
@@ -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()
+4 -4
View File
@@ -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
+2 -2
View File
@@ -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()
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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]."
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+2
View File
@@ -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"
+1 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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"
+13 -19
View File
@@ -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
+9 -14
View File
@@ -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)
+32 -21
View File
@@ -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.
+78 -25
View File
@@ -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)
+6 -6
View File
@@ -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
+1 -3
View File
@@ -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)
+4 -4
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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)
+13 -4
View File
@@ -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)
+4 -4
View File
@@ -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)
+5
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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
+191 -76
View File
@@ -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
+111
View File
@@ -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
+160 -265
View File
@@ -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"
-275
View File
@@ -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)
+24
View File
@@ -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)
+6 -8
View File
@@ -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
+37
View File
@@ -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'
+6 -5
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -3
View File
@@ -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].", \
+3 -3
View File
@@ -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!"
+934
View File
@@ -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)
..()
+5 -4
View File
@@ -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
+1 -54
View File
@@ -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
+2
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+7 -7
View File
@@ -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