Merge branch 'master' of https://github.com/VOREStation/VOREStation into making-of-shadekin

This commit is contained in:
Heroman3003
2019-10-29 09:33:48 +10:00
1698 changed files with 269984 additions and 473924 deletions

View File

@@ -117,7 +117,7 @@ var/const/CE_STABLE_THRESHOLD = 0.5
src << "<font color='red'>You feel extremely [word]</font>"
else if(blood_volume >= BLOOD_VOLUME_SURVIVE)
adjustOxyLoss(5 * dmg_coef)
adjustToxLoss(3 * dmg_coef)
// adjustToxLoss(3 * dmg_coef)
if(prob(15))
var/word = pick("dizzy","woosey","faint")
src << "<font color='red'>You feel extremely [word]</font>"

View File

@@ -0,0 +1,177 @@
/*
* Augments. This file contains the base, and organic-targeting augments.
*/
/obj/item/organ/internal/augment
name = "augment"
icon_state = "cell_bay"
parent_organ = BP_TORSO
organ_verbs = list(/mob/living/carbon/human/proc/augment_menu) // Verbs added by the organ when present in the body.
target_parent_classes = list() // Is the parent supposed to be organic, robotic, assisted?
forgiving_class = FALSE // Will the organ give its verbs when it isn't a perfect match? I.E., assisted in organic, synthetic in organic.
var/obj/item/integrated_object // Objects held by the organ, used for re-usable, deployable things.
var/integrated_object_type // Object type the organ will spawn.
var/target_slot = null
var/silent_deploy = FALSE
var/image/my_radial_icon = null
var/radial_icon = null // DMI for the augment's radial icon.
var/radial_name = null // The augment's name in the Radial Menu.
var/radial_state = null // Icon state for the augment's radial icon.
var/aug_cooldown = 30 SECONDS
var/last_activate = null
/obj/item/organ/internal/augment/Initialize()
..()
setup_radial_icon()
if(integrated_object_type)
integrated_object = new integrated_object_type(src)
integrated_object.canremove = FALSE
/obj/item/organ/internal/augment/proc/setup_radial_icon()
if(!radial_icon)
radial_icon = icon
if(!radial_name)
radial_name = name
if(!radial_state)
radial_state = icon_state
my_radial_icon = image(icon = radial_icon, icon_state = radial_state)
/obj/item/organ/internal/augment/handle_organ_mod_special(var/removed = FALSE)
if(removed && integrated_object && integrated_object.loc != src)
if(isliving(integrated_object.loc))
var/mob/living/L = integrated_object.loc
L.drop_from_inventory(integrated_object)
integrated_object.forceMove(src)
..(removed)
/obj/item/organ/internal/augment/proc/augment_action()
if(!owner)
return
if(aug_cooldown)
if(last_activate <= world.time + aug_cooldown)
last_activate = world.time
else
return
var/item_to_equip = integrated_object
if(!item_to_equip && integrated_object_type)
item_to_equip = integrated_object_type
if(ispath(item_to_equip))
owner.equip_augment_item(target_slot, item_to_equip, silent_deploy, FALSE)
else if(item_to_equip)
owner.equip_augment_item(target_slot, item_to_equip, silent_deploy, FALSE, src)
/*
* The delicate handling of augment-controlled items.
*/
// Attaches to the end of dropped items' code.
/obj/item
var/destroy_on_drop = FALSE // Used by augments to determine if the item should destroy itself when dropped, or return to its master.
var/obj/item/organ/my_augment = null // Used to reference the object's host organ.
/obj/item/dropped(mob/user)
. = ..()
if(src)
if(destroy_on_drop && !QDELETED(src))
qdel(src)
return
if(my_augment)
forceMove(my_augment)
/*
* Human-specific mob procs.
*/
// The next two procs simply handle the radial menu for augment activation.
/mob/living/carbon/human/proc/augment_menu()
set name = "Open Augment Menu"
set desc = "Toggle your augment menu."
set category = "Augments"
enable_augments(usr)
/mob/living/carbon/human/proc/enable_augments(var/mob/living/user)
var/list/options = list()
var/list/present_augs = list()
for(var/obj/item/organ/internal/augment/Aug in internal_organs)
if(Aug.my_radial_icon && !Aug.is_broken() && Aug.check_verb_compatability())
present_augs[Aug.radial_name] = Aug
for(var/augname in present_augs)
var/obj/item/organ/internal/augment/iconsource = present_augs[augname]
options[augname] = iconsource.my_radial_icon
var/list/choice = list()
if(length(options) == 1)
for(var/key in options)
choice = key
else
choice = show_radial_menu(user, src, options)
if(!isnull(choice) && options[choice])
var/obj/item/organ/internal/augment/A = present_augs[choice]
A.augment_action(user)
/* equip_augment_item
* Used to equip an organ's augment items when possible.
* slot is the target equip slot, if it's not a generic either-hand deployable,
* equipping is either the target object, or a path for the target object,
* destroy_on_drop is the default value for the object to be deleted if it is removed from their person, if equipping is a path, however, this will be set to TRUE,
* cling_to_organ is a reference to the organ object itself, so they can easily return to their organ when removed by any means.
*/
/mob/living/carbon/human/proc/equip_augment_item(var/slot, var/obj/item/equipping = null, var/make_sound = TRUE, var/destroy_on_drop = FALSE, var/obj/item/organ/cling_to_organ = null)
if(!ishuman(src))
return 0
if(!equipping)
return 0
var/mob/living/carbon/human/M = src
if((slot == slot_l_hand && l_hand) || (slot == slot_r_hand && r_hand))
to_chat(M,"<span class='warning'>Your hand is full. Drop something first.</span>")
return 0
var/del_if_failure = destroy_on_drop
if(ispath(equipping))
del_if_failure = TRUE
equipping = new equipping(src)
if(!slot)
put_in_any_hand_if_possible(equipping, del_if_failure)
else
if(slot_is_accessible(slot, equipping, src))
equip_to_slot(equipping, slot, 1, 1)
else if(destroy_on_drop || del_if_failure)
qdel(equipping)
return 0
if(cling_to_organ) // Does the object automatically return to the organ?
equipping.my_augment = cling_to_organ
if(make_sound)
playsound(src, 'sound/items/change_jaws.ogg', 30, 1)
if(equipping.loc != src)
equipping.dropped()
return 1

View File

@@ -0,0 +1,262 @@
/*
* Arm mounted augments.
*/
/obj/item/organ/internal/augment/armmounted
name = "laser rifle implant"
desc = "A large implant that fits into a subject's arm. It deploys a laser-emitting array by some painful means."
icon_state = "augment_laser"
w_class = ITEMSIZE_LARGE
organ_tag = O_AUG_L_FOREARM
parent_organ = BP_L_ARM
target_slot = slot_l_hand
target_parent_classes = list(ORGAN_FLESH, ORGAN_ASSISTED)
integrated_object_type = /obj/item/weapon/gun/energy/laser/mounted/augment
/obj/item/organ/internal/augment/armmounted/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_screwdriver())
switch(organ_tag)
if(O_AUG_L_FOREARM)
organ_tag = O_AUG_R_FOREARM
parent_organ = BP_R_ARM
target_slot = slot_r_hand
if(O_AUG_R_FOREARM)
organ_tag = O_AUG_L_FOREARM
parent_organ = BP_L_ARM
target_slot = slot_l_hand
to_chat(user, "<span class='notice'>You swap \the [src]'s servos to install neatly into \the lower [parent_organ] mount.</span>")
return
. = ..()
/obj/item/organ/internal/augment/armmounted/taser
name = "taser implant"
desc = "A large implant that fits into a subject's arm. It deploys a taser-emitting array by some painful means."
icon_state = "augment_taser"
integrated_object_type = /obj/item/weapon/gun/energy/taser/mounted/augment
/obj/item/organ/internal/augment/armmounted/dartbow
name = "crossbow implant"
desc = "A small implant that fits into a subject's arm. It deploys a dart launching mechanism through the flesh through unknown means."
icon_state = "augment_dart"
w_class = ITEMSIZE_SMALL
integrated_object_type = /obj/item/weapon/gun/energy/crossbow
// Wrist-or-hand-mounted implant
/obj/item/organ/internal/augment/armmounted/hand
name = "resonant analyzer implant"
desc = "An augment that fits neatly into the hand, useful for determining the usefulness of an object for research."
icon_state = "augment_box"
w_class = ITEMSIZE_SMALL
integrated_object_type = /obj/item/weapon/portable_scanner
/obj/item/organ/internal/augment/armmounted/hand/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_screwdriver())
switch(organ_tag)
if(O_AUG_L_HAND)
organ_tag = O_AUG_R_HAND
parent_organ = BP_R_HAND
target_slot = slot_r_hand
if(O_AUG_R_HAND)
organ_tag = O_AUG_L_HAND
parent_organ = BP_L_HAND
target_slot = slot_l_hand
to_chat(user, "<span class='notice'>You swap \the [src]'s servos to install neatly into \the upper [parent_organ] mount.</span>")
return
. = ..()
/obj/item/organ/internal/augment/armmounted/hand/sword
name = "energy blade implant"
integrated_object_type = /obj/item/weapon/melee/energy/sword
/*
* Shoulder augment.
*/
/obj/item/organ/internal/augment/armmounted/shoulder
name = "shoulder augment"
desc = "A large implant that fits into a subject's arm. It looks kind of like a skeleton."
icon_state = "augment_armframe"
organ_tag = O_AUG_R_UPPERARM
w_class = ITEMSIZE_HUGE
integrated_object_type = null
/obj/item/organ/internal/augment/armmounted/shoulder/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_screwdriver())
switch(organ_tag)
if(O_AUG_L_UPPERARM)
organ_tag = O_AUG_R_UPPERARM
parent_organ = BP_R_ARM
target_slot = slot_r_hand
if(O_AUG_R_UPPERARM)
organ_tag = O_AUG_L_UPPERARM
parent_organ = BP_L_ARM
target_slot = slot_l_hand
to_chat(user, "<span class='notice'>You swap \the [src]'s servos to install neatly into \the upper [parent_organ] mount.</span>")
return
. = ..()
/obj/item/organ/internal/augment/armmounted/shoulder/surge
name = "muscle overclocker"
aug_cooldown = 1.5 MINUTES
/obj/item/organ/internal/augment/armmounted/shoulder/surge/augment_action()
if(!owner)
return
if(aug_cooldown)
if(last_activate <= world.time + aug_cooldown)
last_activate = world.time
else
return
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.add_modifier(/datum/modifier/melee_surge, 0.75 MINUTES)
// The toolkit / multi-tool implant.
/obj/item/organ/internal/augment/armmounted/shoulder/multiple
name = "rotary toolkit"
desc = "A large implant that fits into a subject's arm. It deploys an array of tools by some painful means."
icon_state = "augment_toolkit"
organ_tag = O_AUG_R_UPPERARM
w_class = ITEMSIZE_HUGE
integrated_object_type = null
toolspeed = 0.8
var/list/integrated_tools = list(
/obj/item/weapon/tool/screwdriver = null,
/obj/item/weapon/tool/wrench = null,
/obj/item/weapon/tool/crowbar = null,
/obj/item/weapon/tool/wirecutters = null,
/obj/item/device/multitool = null,
/obj/item/stack/cable_coil/gray = null,
/obj/item/weapon/tape_roll = null
)
var/list/integrated_tools_by_name
var/list/integrated_tool_images
var/list/synths
var/list/synth_types = list(
/datum/matter_synth/wire
)
/obj/item/organ/internal/augment/armmounted/shoulder/multiple/Initialize()
..()
if(integrated_object)
integrated_tools[integrated_object_type] = integrated_object
if(integrated_tools && integrated_tools.len)
integrated_tools_by_name = list()
integrated_tool_images = list()
if(synth_types)
synths = list()
for(var/datumpath in synth_types)
var/datum/matter_synth/MS = new datumpath
synths += MS
for(var/path in integrated_tools)
if(!integrated_tools[path])
integrated_tools[path] = new path(src)
var/obj/item/I = integrated_tools[path]
I.canremove = FALSE
I.toolspeed = toolspeed
I.my_augment = src
I.name = "integrated [I.name]"
for(var/tool in integrated_tools)
var/obj/item/Tool = integrated_tools[tool]
if(istype(Tool, /obj/item/stack))
var/obj/item/stack/S = Tool
S.synths = synths
S.uses_charge = synths.len
integrated_tools_by_name[Tool.name] = Tool
integrated_tool_images[Tool.name] = image(icon = Tool.icon, icon_state = Tool.icon_state)
/obj/item/organ/internal/augment/armmounted/shoulder/multiple/handle_organ_proc_special()
..()
if(!owner || is_bruised() || !synths)
return
if(prob(20))
for(var/datum/matter_synth/MS in synths)
MS.add_charge(MS.recharge_rate)
/obj/item/organ/internal/augment/armmounted/shoulder/multiple/augment_action()
if(!owner)
return
var/list/options = list()
for(var/Iname in integrated_tools_by_name)
options[Iname] = integrated_tool_images[Iname]
var/list/choice = list()
if(length(options) == 1)
for(var/key in options)
choice = key
else
choice = show_radial_menu(owner, owner, options)
integrated_object = integrated_tools_by_name[choice]
..()
/obj/item/organ/internal/augment/armmounted/shoulder/multiple/medical
name = "rotary medical kit"
icon_state = "augment_medkit"
integrated_object_type = null
integrated_tools = list(
/obj/item/weapon/surgical/hemostat = null,
/obj/item/weapon/surgical/retractor = null,
/obj/item/weapon/surgical/cautery = null,
/obj/item/weapon/surgical/surgicaldrill = null,
/obj/item/weapon/surgical/scalpel = null,
/obj/item/weapon/surgical/circular_saw = null,
/obj/item/weapon/surgical/bonegel = null,
/obj/item/weapon/surgical/FixOVein = null,
/obj/item/weapon/surgical/bonesetter = null,
/obj/item/stack/medical/crude_pack = null
)
synth_types = list(
/datum/matter_synth/bandage
)

View File

@@ -0,0 +1,104 @@
// The base organic-targeting augment.
/obj/item/organ/internal/augment/bioaugment
name = "bioaugmenting implant"
icon_state = "augment_hybrid"
dead_icon = "augment_hybrid_dead"
robotic = ORGAN_ASSISTED
target_parent_classes = list(ORGAN_FLESH)
/* Jensen Shades. Your vision can be augmented.
* This, technically, no longer needs its unique organ verb, however I have chosen to leave it for posterity
* in the event it needs to be referenced, while still remaining perfectly functional with either system.
*/
/obj/item/organ/internal/augment/bioaugment/thermalshades
name = "integrated thermolensing implant"
desc = "A miniscule implant that houses a pair of thermolensed sunglasses. Don't ask how they deploy, you don't want to know."
icon_state = "augment_shades"
dead_icon = "augment_shades_dead"
w_class = ITEMSIZE_TINY
organ_tag = O_AUG_EYES
robotic = ORGAN_ROBOT
parent_organ = BP_HEAD
organ_verbs = list(
/mob/living/carbon/human/proc/augment_menu,
/mob/living/carbon/human/proc/toggle_shades)
integrated_object_type = /obj/item/clothing/glasses/hud/security/jensenshades
/obj/item/organ/internal/augment/bioaugment/thermalshades/augment_action()
if(!owner)
return
owner.toggle_shades()
// Here for posterity and example.
/mob/living/carbon/human/proc/toggle_shades()
set name = "Toggle Integrated Thermoshades"
set desc = "Toggle your flash-proof, thermal-integrated sunglasses."
set category = "Augments"
var/obj/item/organ/internal/augment/aug = internal_organs_by_name[O_AUG_EYES]
if(glasses)
if(aug && aug.integrated_object == glasses)
drop_from_inventory(glasses)
aug.integrated_object.forceMove(aug)
if(!glasses)
to_chat(src, "<span class='alien'>Your [aug.integrated_object] retract into your skull.</span>")
else if(!istype(glasses, /obj/item/clothing/glasses/hud/security/jensenshades))
to_chat(src, "<span class='notice'>\The [glasses] block your shades from deploying.</span>")
else if(istype(glasses, /obj/item/clothing/glasses/hud/security/jensenshades))
var/obj/item/G = glasses
if(G.canremove)
to_chat(src, "<span class='notice'>\The [G] are not your integrated shades.</span>")
else
drop_from_inventory(G)
to_chat(src, "<span class='notice'>\The [G] retract into your skull.</span>")
qdel(G)
else
if(aug && aug.integrated_object)
to_chat(src, "<span class='alien'>Your [aug.integrated_object] deploy.</span>")
equip_to_slot(aug.integrated_object, slot_glasses, 0, 1)
if(!glasses || glasses != aug.integrated_object)
aug.integrated_object.forceMove(aug)
else
var/obj/item/clothing/glasses/hud/security/jensenshades/J = new(get_turf(src))
equip_to_slot(J, slot_glasses, 1, 1)
to_chat(src, "<span class='notice'>Your [aug.integrated_object] deploy.</span>")
/obj/item/organ/internal/augment/bioaugment/sprint_enhance
name = "locomotive optimization implant"
desc = "A chunk of meat and metal that can manage an individual's leg musculature."
organ_tag = O_AUG_PELVIC
parent_organ = BP_GROIN
target_parent_classes = list(ORGAN_FLESH, ORGAN_ASSISTED)
aug_cooldown = 2 MINUTES
/obj/item/organ/internal/augment/bioaugment/sprint_enhance/augment_action()
if(!owner)
return
if(aug_cooldown)
if(last_activate <= world.time + aug_cooldown)
last_activate = world.time
else
return
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.add_modifier(/datum/modifier/sprinting, 1 MINUTES)

View File

@@ -130,6 +130,11 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
target.key = brainmob.key
..()
/obj/item/organ/internal/brain/proc/get_control_efficiency()
. = max(0, 1 - (round(damage / max_damage * 10) / 10))
return .
/obj/item/organ/internal/brain/pariah_brain
name = "brain remnants"
desc = "Did someone tread on this? It looks useless for cloning or cyborgification."

View File

@@ -9,7 +9,6 @@
var/standard_pulse_level = PULSE_NORM // We run on a normal clock. This is NOT CONNECTED to species heart-rate modifier.
/obj/item/organ/internal/heart/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
if(!.) return
@@ -23,6 +22,10 @@
owner.custom_pain("A stabbing pain rolls through your chest!",1)
owner.apply_damage(damage = 25, damagetype = HALLOSS, def_zone = parent_organ)
/obj/item/organ/internal/heart/robotize()
..()
standard_pulse_level = PULSE_NONE
/obj/item/organ/internal/heart/grey
icon_state = "heart_grey-on"
dead_icon = "heart_grey-off"

View File

@@ -0,0 +1,23 @@
/obj/item/organ/internal/intestine
name = "intestine"
icon_state = "intestine"
organ_tag = O_INTESTINE
parent_organ = BP_GROIN
/obj/item/organ/internal/intestine/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
if(!.) return
//Viral Gastroenteritis
if (. >= 1)
if(prob(1))
owner.custom_pain("There's a twisting pain in your abdomen!",1)
owner.vomit()
if (. >= 2)
if(prob(1))
owner.custom_pain("Your abdomen feels like it's tearing itself apart!",1)
owner.m_intent = "walk"
owner.hud_used.move_intent.icon_state = "walking"
/obj/item/organ/internal/intestine/xeno
color = "#555555"

View File

@@ -22,6 +22,13 @@
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
/obj/item/organ/internal/kidneys/handle_organ_proc_special()
. = ..()
if(owner && owner.getToxLoss() <= owner.getMaxHealth() * 0.1) // If you have less than 10 tox damage (for a human), your kidneys can help purge it.
if(prob(owner.getToxLoss()))
owner.adjustToxLoss(rand(-1,-3))
/obj/item/organ/internal/kidneys/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
if(!.) return

View File

@@ -21,6 +21,13 @@
spawn owner.emote("me", 1, "gasps for air!")
owner.AdjustLosebreath(15)
if(owner.internal_organs_by_name[O_BRAIN]) // As the brain starts having Trouble, the lungs start malfunctioning.
var/obj/item/organ/internal/brain/Brain = owner.internal_organs_by_name[O_BRAIN]
if(Brain.get_control_efficiency() <= 0.8)
if(prob(4 / max(0.1,Brain.get_control_efficiency())))
spawn owner.emote("me", 1, "gasps for air!")
owner.AdjustLosebreath(round(3 / max(0.1,Brain.get_control_efficiency())))
/obj/item/organ/internal/lungs/proc/rupture()
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
if(istype(parent))

View File

@@ -0,0 +1,87 @@
/obj/item/organ/internal/spleen
name = "spleen"
icon_state = "spleen"
organ_tag = O_SPLEEN
parent_organ = BP_TORSO
w_class = ITEMSIZE_TINY
var/spleen_tick = 20 // The number of ticks between Spleen cycles.
var/spleen_efficiency = 1 // A multiplier for how efficient this spleen is.
/obj/item/organ/internal/spleen/process()
..()
if(!owner) return
if(owner.life_tick % spleen_tick == 0)
//High toxins levels are dangerous
if(owner.getToxLoss() >= 30 && !owner.reagents.has_reagent("anti_toxin"))
//Healthy liver suffers on its own
if (src.damage < min_broken_damage)
src.damage += 0.2 * spleen_tick
//Damaged one shares the fun
else
var/obj/item/organ/internal/O = pick(owner.internal_organs)
if(O)
O.damage += 0.2 * spleen_tick
else if(!src.is_broken()) // If the spleen isn't severely damaged, it can help fight infections. Key word, can.
var/obj/item/organ/external/OEx = pick(owner.organs)
OEx.adjust_germ_level(round(rand(0 * spleen_efficiency,-10 * spleen_efficiency)))
if(!src.is_bruised() && owner.internal_organs_by_name[O_BRAIN]) // If it isn't bruised, it helps with brain infections.
var/obj/item/organ/internal/brain/B = owner.internal_organs_by_name[O_BRAIN]
B.adjust_germ_level(round(rand(-3 * spleen_efficiency, -10 * spleen_efficiency)))
//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 * spleen_tick * spleen_efficiency
if(src.damage < 0)
src.damage = 0
/obj/item/organ/internal/spleen/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
if(!.) return
// Low levels can cause pain and haemophilia, high levels can cause brain infections.
if (. >= 1)
if(prob(1))
owner.custom_pain("There's a sharp pain in your [owner.get_organ(parent_organ)]!",1)
owner.add_modifier(/datum/modifier/trait/haemophilia, 2 MINUTES * spleen_efficiency)
if (. >= 2)
if(prob(1))
if(owner.getToxLoss() < owner.getMaxHealth() * 0.2 * spleen_efficiency)
owner.adjustToxLoss(2 * spleen_efficiency)
else if(owner.internal_organs_by_name[O_BRAIN])
var/obj/item/organ/internal/brain/Brain = owner.internal_organs_by_name[O_BRAIN]
Brain.adjust_germ_level(round(rand(5 * spleen_efficiency,20 * spleen_efficiency)))
/obj/item/organ/internal/spleen/die()
..()
if(owner)
owner.add_modifier(/datum/modifier/trait/haemophilia, round(15 MINUTES * spleen_efficiency))
var/obj/item/organ/external/Target = owner.get_organ(parent_organ)
var/datum/wound/W = new /datum/wound/internal_bleeding(round(20 * spleen_efficiency))
owner.adjustToxLoss(15 * spleen_efficiency)
Target.wounds += W
/obj/item/organ/internal/spleen/skrell
name = "lymphatic hub"
icon_state = "spleen"
parent_organ = BP_HEAD
spleen_efficiency = 0.5
/obj/item/organ/internal/spleen/skrell/Initialize()
..()
adjust_scale(0.8,0.7)
/obj/item/organ/internal/spleen/minor
name = "vestigial spleen"
parent_organ = BP_GROIN
spleen_efficiency = 0.3
spleen_tick = 15
/obj/item/organ/internal/spleen/minor/Initialize()
..()
adjust_scale(0.7)

View File

@@ -0,0 +1,50 @@
/obj/item/organ/internal/stomach
name = "stomach"
icon_state = "stomach"
organ_tag = O_STOMACH
parent_organ = BP_GROIN
unacidable = TRUE // Don't melt when holding your acid, dangit.
var/acidtype = "stomacid" // Incase you want some stomach organ with, say, polyacid instead, or sulphuric.
var/max_acid_volume = 30
var/deadly_hold = TRUE // Does the stomach do damage to mobs eaten by its owner? Xenos should probably have this FALSE.
/obj/item/organ/internal/stomach/Initialize()
..()
if(reagents)
reagents.maximum_volume = 30
else
create_reagents(30)
/obj/item/organ/internal/stomach/handle_organ_proc_special()
if(owner && istype(owner, /mob/living/carbon/human))
if(reagents)
if(reagents.total_volume + 2 < max_acid_volume && prob(20))
reagents.add_reagent(acidtype, rand(1,2))
for(var/mob/living/L in owner.stomach_contents) // Splashes mobs inside with acid. Twice as effective as being splashed with the same acid outside the body.
reagents.trans_to(L, 2, 2, 0)
if(is_broken() && prob(1))
owner.custom_pain("There's a twisting pain in your abdomen!",1)
owner.vomit(FALSE, TRUE)
/obj/item/organ/internal/stomach/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
if(!.) return
//Bacterial Gastroenteritis
if (. >= 1)
if(prob(1))
owner.custom_pain("There's a twisting pain in your abdomen!",1)
owner.apply_effect(2, AGONY, 0)
if (. >= 2)
if(prob(1) && owner.getToxLoss() < owner.getMaxHealth()*0.2)
owner.adjustToxLoss(3)
owner.vomit(FALSE, TRUE)
/obj/item/organ/internal/stomach/xeno
color = "#555555"

View File

@@ -1,7 +1,7 @@
/*
* Voicebox/Vocal Synthesizers
* TL;DR: Assists with speaking languages that a species doesn't normally have,
* such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters.
* such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters. - - Can now actually cause muting, if destroyed / removed.
*/
/obj/item/organ/internal/voicebox
@@ -10,6 +10,7 @@
parent_organ = BP_TORSO // We don't have a neck area
organ_tag = O_VOICE
will_assist_languages = list(LANGUAGE_GALCOM)
var/mute = FALSE
/obj/item/organ/internal/voicebox/New()
..()

View File

@@ -36,7 +36,10 @@ var/list/organ_cache = list()
var/list/will_assist_languages = list()
var/list/datum/language/assists_languages = list()
var/list/organ_verbs // Verbs added by the organ when present in the body.
// Organ verb vars.
var/list/organ_verbs // Verbs added by the organ when present in the body.
var/list/target_parent_classes = list() // Is the parent supposed to be organic, robotic, assisted?
var/forgiving_class = TRUE // Will the organ give its verbs when it isn't a perfect match? I.E., assisted in organic, synthetic in organic.
/obj/item/organ/Destroy()
@@ -75,6 +78,7 @@ var/list/organ_cache = list()
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs |= src
H.internal_organs_by_name[organ_tag] = src
if(dna)
if(!blood_DNA)
blood_DNA = list()
@@ -289,7 +293,7 @@ var/list/organ_cache = list()
W.time_inflicted = world.time
//Note: external organs have their own version of this proc
/obj/item/organ/proc/take_damage(amount, var/silent=0)
/obj/item/organ/take_damage(amount, var/silent=0)
if(src.robotic >= ORGAN_ROBOT)
src.damage = between(0, src.damage + (amount * 0.8), max_damage)
else
@@ -441,12 +445,12 @@ var/list/organ_cache = list()
all_organs |= owner.internal_organs
for(var/obj/item/organ/O in all_organs)
if(!(O.status & ORGAN_DEAD) && O.organ_verbs)
if(!(O.status & ORGAN_DEAD) && O.organ_verbs && O.check_verb_compatability())
for(var/verb_type in O.organ_verbs)
if(verb_type in organ_verbs)
save_verbs |= verb_type
if(!removed && organ_verbs)
if(!removed && organ_verbs && check_verb_compatability())
for(var/verb_path in organ_verbs)
owner.verbs |= verb_path
else if(organ_verbs)
@@ -457,3 +461,32 @@ var/list/organ_cache = list()
/obj/item/organ/proc/handle_organ_proc_special() // Called when processed.
return
/obj/item/organ/proc/check_verb_compatability() // Used for determining if an organ should give or remove its verbs. I.E., FBP part in a human, no verbs. If true, keep or add.
if(owner)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
var/obj/item/organ/O = H.get_organ(parent_organ)
if(forgiving_class)
if(O.robotic <= ORGAN_ASSISTED && robotic <= ORGAN_LIFELIKE) // Parent is organic or assisted, we are at most synthetic.
return TRUE
if(O.robotic >= ORGAN_ROBOT && robotic >= ORGAN_ASSISTED) // Parent is synthetic, and we are biosynthetic at least.
return TRUE
if(!target_parent_classes || !target_parent_classes.len) // Default checks, if we're not looking for a Specific type.
if(O.robotic == robotic) // Same thing, we're fine.
return TRUE
if(O.robotic < ORGAN_ROBOT && robotic < ORGAN_ROBOT)
return TRUE
if(O.robotic > ORGAN_ASSISTED && robotic > ORGAN_ASSISTED)
return TRUE
else
if(O.robotic in target_parent_classes)
return TRUE
return FALSE

View File

@@ -952,6 +952,13 @@ Note that amputating the affected organ does in fact remove the infection from t
qdel(src)
if(victim.l_hand)
if(istype(victim.l_hand,/obj/item/weapon/material/twohanded)) //if they're holding a two-handed weapon, drop it now they've lost a hand
victim.l_hand.update_held_icon()
if(victim.r_hand)
if(istype(victim.r_hand,/obj/item/weapon/material/twohanded))
victim.r_hand.update_held_icon()
/****************************************************
HELPERS
****************************************************/

View File

@@ -13,3 +13,7 @@
min_broken_damage = o_min_broken_damage
else
return ..()
/obj/item/organ/external/proc/is_hidden_by_tail()
if(owner && owner.tail_style && owner.tail_style.hide_body_parts && (organ_tag in owner.tail_style.hide_body_parts))
return 1

View File

@@ -129,7 +129,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
icon = 'icons/mob/human_races/cyberlimbs/grayson/grayson_main.dmi'
unavailable_to_build = 1
monitor_styles = "blank=grayson_off;\
red=grayson_red;\
green=grayson_green;\
blue=grayson_blue;\
rgb=grayson_rgb"
/datum/robolimb/grayson_alt1
@@ -177,7 +179,8 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
desc = "This rather thick limb has a militaristic green plating."
icon = 'icons/mob/human_races/cyberlimbs/hephaestus/hephaestus_alt2.dmi'
unavailable_to_build = 1
monitor_styles = "red=athena_red;\
blank=athena_off"
/datum/robolimb/hephaestus_monitor
company = "Hephaestus Monitor"
@@ -266,7 +269,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt2.dmi'
unavailable_to_build = 1
monitor_styles = "blank=xion_off;\
red=xion_red;\
green=xion_green;\
blue=xion_blue;\
rgb=xion_rgb"
/datum/robolimb/xion_alt3

View File

@@ -56,3 +56,89 @@
max_damage = 30
encased = 0
spread_dam = 1
/*
* Internal Slime organs.
*/
/obj/item/organ/internal/heart/grey/colormatch/slime
name = "pneumatic network"
desc = "A disgusting sac of goo."
icon_state = "sac_slime"
dead_icon = null
standard_pulse_level = PULSE_NONE
/obj/item/organ/internal/heart/grey/colormatch/slime/process()
..()
if(!(QDELETED(src)) && src.loc != owner)
visible_message("<span class='notice'>\The [src] splatters!</span>")
var/turf/T = get_turf(src)
var/obj/effect/decal/cleanable/blood/B = new (T)
B.basecolor = src.color
B.update_icon()
qdel(src)
/obj/item/organ/internal/regennetwork
name = "pneumoregenesis network"
parent_organ = BP_TORSO
organ_tag = O_REGBRUTE
icon_state = "sac_slime"
var/strain = 0 // The amount of stress this organ is under. Capped at min_broken_damage, usually half its max damage.
var/last_strain_increase = 0 // World time of the last increase in strain.
var/strain_regen_cooldown = 5 MINUTES
/obj/item/organ/internal/regennetwork/Initialize()
..()
var/mob/living/carbon/human/H = null
spawn(15)
if(ishuman(owner))
H = owner
color = H.species.get_blood_colour(H)
/obj/item/organ/internal/regennetwork/proc/get_strain_percent(var/cost)
adjust_strain(cost)
if((status & ORGAN_CUT_AWAY) || (status & ORGAN_BROKEN) || (status & ORGAN_DEAD))
return 1
return round((strain / min_broken_damage) * 10) / 10
/obj/item/organ/internal/regennetwork/proc/adjust_strain(var/amount)
if(amount < 0 && world.time < (last_strain_increase + strain_regen_cooldown))
return
else if(amount > 0)
last_strain_increase = world.time
strain = CLAMP(strain + amount, 0, min_broken_damage)
/obj/item/organ/internal/regennetwork/process()
..()
if(!(QDELETED(src)) && src.loc != owner)
visible_message("<span class='notice'>\The [src] splatters!</span>")
var/turf/T = get_turf(src)
var/obj/effect/decal/cleanable/blood/B = new (T)
B.basecolor = src.color
B.update_icon()
qdel(src)
if(src && !is_bruised())
adjust_strain(-0.25 * max(0, (min_broken_damage - damage) / min_broken_damage)) // Decrease the current strain with respect to the current strain level.
/obj/item/organ/internal/regennetwork/burn
name = "thermoregenesis network"
organ_tag = O_REGBURN
/obj/item/organ/internal/regennetwork/oxy
name = "respiroregenesis network"
organ_tag = O_REGOXY
/obj/item/organ/internal/regennetwork/tox
name = "toxoregenesis network"
organ_tag = O_REGTOX

View File

@@ -1,14 +1,77 @@
/obj/item/organ/external/head/blankeyes
eye_icon_location = 'icons/mob/human_face_vr.dmi'
eye_icon = "blank_eyes"
//For custom heads with custom parts since the base code is restricted to a single icon file.
/obj/item/organ/external/head/vr/get_icon()
..()
overlays.Cut()
if(!owner || !owner.species)
return
for(var/M in markings)
var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"]
var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]")
mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode)
overlays |= mark_s //So when it's not on your body, it has icons
mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons
icon_cache_key += "[M][markings[M]["color"]]"
if(owner.should_have_organ(O_EYES))//Moved on top of markings.
var/obj/item/organ/internal/eyes/eyes = owner.internal_organs_by_name[O_EYES]
if(eye_icon)
var/icon/eyes_icon = new/icon(eye_icons_vr, eye_icon_vr)
if(eyes)
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
else
eyes_icon.Blend(rgb(128,0,0), ICON_ADD)
mob_icon.Blend(eyes_icon, ICON_OVERLAY)
overlays |= eyes_icon
if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS)))
var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s")
overlays |= lip_icon
mob_icon.Blend(lip_icon, ICON_OVERLAY)
if(owner.f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype(owner) in facial_hair_style.species_allowed))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
overlays |= image(facial_s, "pixel_y" = head_offset)
if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3)
hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_MULTIPLY)
overlays |= image(hair_s, "pixel_y" = head_offset)
/obj/item/organ/external/head/sergal
eye_icon_location = 'icons/mob/human_face_vr.dmi'
eye_icon = "eyes_sergal"
/obj/item/organ/external/head/vr
var/eye_icons_vr = 'icons/mob/human_face_vr.dmi'
var/eye_icon_vr = "blank_eyes"
var/head_offset = 0
eye_icon = "blank_eyes"
/obj/item/organ/external/head/vr/sergal
eye_icon_vr = "eyes_sergal"
/obj/item/organ/external/head/vr/werebeast
eye_icons_vr = 'icons/mob/werebeast_face_vr.dmi'
eye_icon_vr = "werebeast_eyes"
head_offset = 6
/obj/item/organ/external/head/blankeyes
eye_icon_location = 'icons/mob/human_face_vr.dmi'
eye_icon = "blank_eyes"
/obj/item/organ/external/head/shadekin
cannot_gib = 1
cannot_amputate = 1
eye_icon_location = 'icons/mob/human_face_vr.dmi'
eye_icon = "eyes_shadekin_blue"
eye_icon = "eyes_shadekin_blue"

View File

@@ -47,4 +47,11 @@
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
/obj/item/organ/internal/brain/unathi
color = "#b3cbc3"
color = "#b3cbc3"
/obj/item/organ/internal/stomach/unathi
color = "#b3cbc3"
max_acid_volume = 40
/obj/item/organ/internal/intestine/unathi
color = "#b3cbc3"