[MIRROR] The Great Species Dedatumming 2: Makes external organs operable [MDB IGNORE] (#15530)

* The Great Species Dedatumming 2: Makes external organs operable

* Fixes merge conflicts

* Partly fixes taur bodies (makes them external and use the mob sprite as their icon)

Co-authored-by: Time-Green <timkoster1@hotmail.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
SkyratBot
2022-08-13 02:01:39 +02:00
committed by GitHub
parent b4ca929e54
commit f6f9b6f2f3
19 changed files with 140 additions and 63 deletions
-22
View File
@@ -72,28 +72,6 @@
/// Allows for masks to use tanks on adjacentadjecent tiles.
#define MASK_EXTEND_RANGE (1<<21)
//SKYRAT DEFINE END
/// Flags for the organ_flags var on /obj/item/organ
#define ORGAN_SYNTHETIC (1<<0) //Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
#define ORGAN_FROZEN (1<<1) //Frozen organs, don't deteriorate
#define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed
#define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change.
#define ORGAN_VITAL (1<<4) //Currently only the brain
#define ORGAN_EDIBLE (1<<5) //is a snack? :D
#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time.
#define ORGAN_UNREMOVABLE (1<<7) //Can't be removed using surgery
DEFINE_BITFIELD(organ_flags, list(
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
"ORGAN_FROZEN" = ORGAN_FROZEN,
"ORGAN_FAILING" = ORGAN_FAILING,
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
"ORGAN_VITAL" = ORGAN_VITAL,
"ORGAN_EDIBLE" = ORGAN_EDIBLE,
"ORGAN_SYNTHETIC_EMP" = ORGAN_SYNTHETIC_EMP,
"ORGAN_UNREMOVABLE" = ORGAN_UNREMOVABLE,
))
/// Integrity defines for clothing (not flags but close enough)
#define CLOTHING_PRISTINE 0 // We have no damage on the clothing
+30
View File
@@ -0,0 +1,30 @@
// Flags for the organ_flags var on /obj/item/organ
///Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
#define ORGAN_SYNTHETIC (1<<0)
///Frozen organs, don't deteriorate
#define ORGAN_FROZEN (1<<1)
///Failing organs perform damaging effects until replaced or fixed
#define ORGAN_FAILING (1<<2)
///Is this organ external? defines how to manipulate the organ, should generally be reserved to cosmetic organs like tails, horns and wings
#define ORGAN_EXTERNAL (1<<3)
///Currently only the brain
#define ORGAN_VITAL (1<<4)
///is a snack? :D
#define ORGAN_EDIBLE (1<<5)
///Synthetic organ affected by an EMP. Deteriorates over time.
#define ORGAN_SYNTHETIC_EMP (1<<6)
// //Can't be removed using surgery
#define ORGAN_UNREMOVABLE (1<<7)
DEFINE_BITFIELD(organ_flags, list(
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
"ORGAN_FROZEN" = ORGAN_FROZEN,
"ORGAN_FAILING" = ORGAN_FAILING,
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
"ORGAN_VITAL" = ORGAN_VITAL,
"ORGAN_EDIBLE" = ORGAN_EDIBLE,
"ORGAN_SYNTHETIC_EMP" = ORGAN_SYNTHETIC_EMP,
"ORGAN_UNREMOVABLE" = ORGAN_UNREMOVABLE,
))
/// When the surgery step fails :(
#define SURGERY_STEP_FAIL -1
@@ -69,7 +69,7 @@
/obj/item/organ/internal/body_egg/alien_embryo/egg_process()
if(stage == 6 && prob(50))
for(var/datum/surgery/S in owner.surgeries)
if(S.location == BODY_ZONE_CHEST && istype(S.get_surgery_step(), /datum/surgery_step/manipulate_organs))
if(S.location == BODY_ZONE_CHEST && istype(S.get_surgery_step(), /datum/surgery_step/manipulate_organs/internal))
AttemptGrow(0)
return
AttemptGrow()
@@ -157,7 +157,7 @@
/obj/item/organ/internal/brain/dullahan
decoy_override = TRUE
organ_flags = 0
organ_flags = NONE
/obj/item/organ/internal/tongue/dullahan
zone = "abstract"
@@ -44,7 +44,7 @@
/datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
objective = tgui_input_text(user, "Choose the objective to imprint on your victim's brain", "Brainwashing")
if(!objective)
return -1
return SURGERY_STEP_FAIL
display_results(user, target, span_notice("You begin to brainwash [target]..."),
span_notice("[user] begins to fix [target]'s brain."),
span_notice("[user] begins to perform surgery on [target]'s brain."))
+3 -3
View File
@@ -16,16 +16,16 @@
/datum/surgery_step/replace_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(NOAUGMENTS in target.dna.species.species_traits)
to_chat(user, span_warning("[target] cannot be augmented!"))
return -1
return SURGERY_STEP_FAIL
if(istype(tool, /obj/item/borg/apparatus/organ_storage) && istype(tool.contents[1], /obj/item/bodypart))
tool = tool.contents[1]
var/obj/item/bodypart/aug = tool
if(IS_ORGANIC_LIMB(aug))
to_chat(user, span_warning("That's not an augment, silly!"))
return -1
return SURGERY_STEP_FAIL
if(aug.body_zone != target_zone)
to_chat(user, span_warning("[tool] isn't the right type for [parse_zone(target_zone)]."))
return -1
return SURGERY_STEP_FAIL
target_limb = surgery.operated_bodypart
if(target_limb)
display_results(user, target, span_notice("You begin to augment [target]'s [parse_zone(user.zone_selected)]..."),
+56 -17
View File
@@ -9,7 +9,7 @@
/datum/surgery_step/saw,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/incise,
/datum/surgery_step/manipulate_organs, //there should be bone fixing
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/close)
/datum/surgery/organ_manipulation/soft
@@ -19,7 +19,7 @@
/datum/surgery_step/retract_skin,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/incise,
/datum/surgery_step/manipulate_organs,
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/close)
/datum/surgery/organ_manipulation/alien
@@ -31,7 +31,7 @@
/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/saw,
/datum/surgery_step/manipulate_organs,
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/close)
/datum/surgery/organ_manipulation/mechanic
@@ -45,7 +45,7 @@
/datum/surgery_step/open_hatch,
/datum/surgery_step/mechanic_unwrench,
/datum/surgery_step/prepare_electronics,
/datum/surgery_step/manipulate_organs,
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/mechanic_wrench,
/datum/surgery_step/mechanic_close)
@@ -55,11 +55,20 @@
/datum/surgery_step/mechanic_open,
/datum/surgery_step/open_hatch,
/datum/surgery_step/prepare_electronics,
/datum/surgery_step/manipulate_organs,
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/mechanic_close)
/datum/surgery/organ_manipulation/external
name = "Feature manipulation"
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
steps = list(
/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/manipulate_organs/external,
/datum/surgery_step/close)
///Organ manipulation base class. Do not use, it wont work. Use it's subtypes
/datum/surgery_step/manipulate_organs
time = 64
name = "manipulate organs"
repeatable = TRUE
implements = list(
@@ -67,6 +76,7 @@
/obj/item/borg/apparatus/organ_storage = 100)
preop_sound = 'sound/surgery/organ2.ogg'
success_sound = 'sound/surgery/organ1.ogg'
var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55, /obj/item/kitchen/fork = 35)
var/current_type
var/obj/item/organ/target_organ
@@ -82,13 +92,13 @@
success_sound = initial(success_sound)
if(!length(tool.contents))
to_chat(user, span_warning("There is nothing inside [tool]!"))
return -1
return SURGERY_STEP_FAIL
target_organ = tool.contents[1]
if(!isorgan(target_organ))
if (target_zone == BODY_ZONE_PRECISE_EYES)
target_zone = check_zone(target_zone)
to_chat(user, span_warning("You cannot put [target_organ] into [target]'s [parse_zone(target_zone)]!"))
return -1
return SURGERY_STEP_FAIL
tool = target_organ
if(isorgan(tool))
current_type = "insert"
@@ -97,11 +107,15 @@
target_organ = tool
if(target_zone != target_organ.zone || target.getorganslot(target_organ.slot))
to_chat(user, span_warning("There is no room for [target_organ] in [target]'s [parse_zone(target_zone)]!"))
return -1
return SURGERY_STEP_FAIL
var/obj/item/organ/meatslab = tool
if(!meatslab.useable)
to_chat(user, span_warning("[target_organ] seems to have been chewed on, you can't use this!"))
return -1
return SURGERY_STEP_FAIL
if(!can_use_organ(user, meatslab))
return SURGERY_STEP_FAIL
if (target_zone == BODY_ZONE_PRECISE_EYES)
target_zone = check_zone(target_zone)
display_results(user, target, span_notice("You begin to insert [tool] into [target]'s [parse_zone(target_zone)]..."),
@@ -112,12 +126,16 @@
else if(implement_type in implements_extract)
current_type = "extract"
var/list/organs = target.getorganszone(target_zone)
var/list/unfiltered_organs = target.getorganszone(target_zone)
var/list/organs = list()
for(var/organ in unfiltered_organs)
if(can_use_organ(user, organ))
organs.Add(organ)
if (target_zone == BODY_ZONE_PRECISE_EYES)
target_zone = check_zone(target_zone)
if(!length(organs))
to_chat(user, span_warning("There are no removable organs in [target]'s [parse_zone(target_zone)]!"))
return -1
return SURGERY_STEP_FAIL
else
for(var/obj/item/organ/organ in organs)
organ.on_find(user)
@@ -126,22 +144,21 @@
var/chosen_organ = tgui_input_list(user, "Remove which organ?", "Surgery", sort_list(organs))
if(isnull(chosen_organ))
return -1
return SURGERY_STEP_FAIL
target_organ = chosen_organ
if(user && target && user.Adjacent(target) && user.get_active_held_item() == tool)
target_organ = organs[target_organ]
if(!target_organ)
return -1
return SURGERY_STEP_FAIL
if(target_organ.organ_flags & ORGAN_UNREMOVABLE)
to_chat(user, span_warning("[target_organ] is too well connected to take out!"))
return -1
return SURGERY_STEP_FAIL
display_results(user, target, span_notice("You begin to extract [target_organ] from [target]'s [parse_zone(target_zone)]..."),
span_notice("[user] begins to extract [target_organ] from [target]'s [parse_zone(target_zone)]."),
span_notice("[user] begins to extract something from [target]'s [parse_zone(target_zone)]."))
display_pain(target, "You can feel your [target_organ] being removed from your [parse_zone(target_zone)]!")
else
return -1
return SURGERY_STEP_FAIL
/datum/surgery_step/manipulate_organs/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
if (target_zone == BODY_ZONE_PRECISE_EYES)
@@ -176,3 +193,25 @@
span_notice("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!"),
span_notice("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!"))
return FALSE
///You can never use this MUHAHAHAHAHAHAH (because its the byond version of abstract)
/datum/surgery_step/manipulate_organs/proc/can_use_organ(mob/user, obj/item/organ/organ)
return FALSE
///Surgery step for internal organs, like hearts and brains
/datum/surgery_step/manipulate_organs/internal
time = 6.4 SECONDS
name = "manipulate organs"
///only operate on not external organs (so internal organs)
/datum/surgery_step/manipulate_organs/internal/can_use_organ(mob/user, obj/item/organ/organ)
return !(organ.organ_flags & ORGAN_EXTERNAL)
///Surgery step for external organs/features, like tails, frills, wings etc
/datum/surgery_step/manipulate_organs/external
time = 3.2 SECONDS
name = "manipulate features"
///Only operate on external organs
/datum/surgery_step/manipulate_organs/external/can_use_organ(mob/user, obj/item/organ/organ)
return organ.organ_flags & ORGAN_EXTERNAL
@@ -18,8 +18,6 @@
add_overlay(overlay)
return ..()
//[[[[BRAIN]]]]
/obj/item/organ/internal/cyberimp/brain
+25 -7
View File
@@ -7,8 +7,7 @@
name = "external organ"
desc = "An external organ that is too external."
///Unremovable is until the features are completely finished
organ_flags = ORGAN_UNREMOVABLE | ORGAN_EDIBLE
organ_flags = ORGAN_EXTERNAL | ORGAN_EDIBLE
visual = TRUE
///Sometimes we need multiple layers, for like the back, middle and front of the person
@@ -29,6 +28,8 @@
var/datum/sprite_accessory/sprite_datum
///Key of the icon states of all the sprite_datums for easy caching
var/cache_key = ""
///Set to TRUE to use the mob sprite as item sprite
var/use_mob_sprite_as_obj_sprite = FALSE
///With what DNA block do we mutate in mutate_feature() ? For genetics
var/dna_block
@@ -45,7 +46,6 @@
///Does this organ have any bodytypes to pass to it's ownerlimb?
var/external_bodytypes = NONE
/**mob_sprite is optional if you havent set sprite_datums for the object, and is used mostly to generate sprite_datums from a persons DNA
* For _mob_sprite we make a distinction between "Round Snout" and "round". Round Snout is the name of the sprite datum, while "round" would be part of the sprite
* I'm sorry
@@ -152,6 +152,10 @@
var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, finished_icon_state, layer = -image_layer)
appearance.dir = image_dir
///Also give the icon to the obj
if(use_mob_sprite_as_obj_sprite)
icon = icon(sprite_datum.icon, finished_icon_state, SOUTH)
if(sprite_datum.color_src) //There are multiple flags, but only one is ever used so meh :/ | This comment isn't true.
appearance.color = draw_color
@@ -242,10 +246,12 @@
/obj/item/organ/external/proc/override_color(rgb_value)
CRASH("External organ color set to override with no override proc.")
///The horns of a lizard!
/obj/item/organ/external/horns
name = "horns"
desc = "Why do lizards even have horns? Well, this one obviously doesn't."
icon_state = "horns"
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_EXTERNAL_HORNS
layers = EXTERNAL_ADJACENT
@@ -262,6 +268,9 @@
///The frills of a lizard (like weird fin ears)
/obj/item/organ/external/frills
name = "frills"
desc = "Ear-like external organs often seen on aquatic reptillians."
icon_state = "frills"
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_EXTERNAL_FRILLS
layers = EXTERNAL_ADJACENT
@@ -280,7 +289,10 @@
///Guess what part of the lizard this is?
/obj/item/organ/external/snout
name = "snout"
name = "snout" // SKYRAT EDIT - ORIGINAL: name = "lizard snout"
desc = "Take a closer look at that snout!"
icon_state = "snout"
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_EXTERNAL_SNOUT
layers = EXTERNAL_ADJACENT
@@ -299,7 +311,10 @@
///A moth's antennae
/obj/item/organ/external/antennae
name = "antennae"
name = "moth antennae"
desc = "A moths antennae. What is it telling them? What are they sensing?"
icon_state = "antennae"
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_EXTERNAL_ANTENNAE
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
@@ -354,8 +369,11 @@
burnt = FALSE
set_sprite(original_sprite)
//podperson hair
///The leafy hair of a podperson
/obj/item/organ/external/pod_hair
name = "podperson hair"
desc = "Base for many-o-salads."
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_EXTERNAL_POD_HAIR
layers = EXTERNAL_FRONT|EXTERNAL_ADJACENT
+4
View File
@@ -1,4 +1,8 @@
/obj/item/organ/external/spines
name = "lizard spines"
desc = "Not an actual spine, obviously."
icon_state = "spines"
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_EXTERNAL_SPINES
layers = EXTERNAL_ADJACENT|EXTERNAL_BEHIND
+1 -1
View File
@@ -6,7 +6,7 @@
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_EXTERNAL_TAIL
layers = EXTERNAL_FRONT|EXTERNAL_BEHIND
organ_flags = ORGAN_EDIBLE
organ_flags = ORGAN_EDIBLE | ORGAN_EXTERNAL
feature_key = "tail"
render_key = "tail"
// dna_block = DNA_TAIL_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
+7
View File
@@ -1,9 +1,13 @@
///Wing base type. doesn't really do anything
/obj/item/organ/external/wings
name = "wings"
desc = "Spread your wings and FLLLLLLLLYYYYY!"
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_EXTERNAL_WINGS
layers = ALL_EXTERNAL_OVERLAYS
use_mob_sprite_as_obj_sprite = TRUE
feature_key = "wings"
/obj/item/organ/external/wings/can_draw_on_bodypart(mob/living/carbon/human/human)
@@ -164,6 +168,9 @@
///Moth wings! They can flutter in low-grav and burn off in heat
/obj/item/organ/external/wings/moth
name = "moth wings"
desc = "Spread your wings and FLOOOOAAAAAT!"
feature_key = "moth_wings"
preference = "feature_moth_wings"
layers = EXTERNAL_BEHIND | EXTERNAL_FRONT
+1 -1
View File
@@ -242,7 +242,7 @@
/obj/item/organ/internal/heart/freedom
name = "heart of freedom"
desc = "This heart pumps with the passion to give... something freedom."
organ_flags = ORGAN_SYNTHETIC //the power of freedom prevents heart attacks
organ_flags = ORGAN_SYNTHETIC //the power of freedom prevents heart attacks
/// The cooldown until the next time this heart can give the host an adrenaline boost.
COOLDOWN_DECLARE(adrenaline_cooldown)
+1 -1
View File
@@ -30,7 +30,7 @@
return (locate(typepath) in internal_organs + external_organs)
/mob/living/carbon/getorganszone(zone, subzones = 0)
/mob/living/carbon/getorganszone(zone, subzones = 0, external = FALSE)
var/list/returnorg = list()
if(subzones)
// Include subzones - groin for chest, eyes and mouth for head
@@ -34,11 +34,11 @@
if(istype(tool, /obj/item/borg/apparatus/organ_storage))
if(!tool.contents.len)
to_chat(user, span_warning("There is nothing inside [tool]!"))
return -1
return SURGERY_STEP_FAIL
var/obj/item/organ_storage_contents = tool.contents[1]
if(!isbodypart(organ_storage_contents))
to_chat(user, span_warning("[organ_storage_contents] cannot be attached!"))
return -1
return SURGERY_STEP_FAIL
tool = organ_storage_contents
if(istype(tool, /obj/item/bodypart))
var/obj/item/bodypart/bodypart_to_attach = tool
@@ -49,7 +49,7 @@
var/obj/item/bodypart/chest/target_chest = human_target.get_bodypart(BODY_ZONE_CHEST)
if(!(bodypart_to_attach.bodytype & target_chest.acceptable_bodytype))
to_chat(user, span_warning("[bodypart_to_attach] doesn't match the patient's morphology."))
return -1
return SURGERY_STEP_FAIL
if(human_target.dna.species.id != bodypart_to_attach.limb_id)
organ_rejection_dam = 30
@@ -59,14 +59,14 @@
span_notice("[user] begins to replace [target]'s [parse_zone(target_zone)]."))
else
to_chat(user, span_warning("[tool] isn't the right type for [parse_zone(target_zone)]."))
return -1
return SURGERY_STEP_FAIL
else if(target_zone == BODY_ZONE_L_ARM || target_zone == BODY_ZONE_R_ARM)
display_results(user, target, span_notice("You begin to attach [tool] onto [target]..."),
span_notice("[user] begins to attach [tool] onto [target]'s [parse_zone(target_zone)]."),
span_notice("[user] begins to attach something onto [target]'s [parse_zone(target_zone)]."))
else
to_chat(user, span_warning("[tool] must be installed onto an arm."))
return -1
return SURGERY_STEP_FAIL
/datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
. = ..()
+1 -1
View File
@@ -75,7 +75,7 @@
var/fail_prob = 0//100 - fail_prob = success_prob
var/advance = FALSE
if(preop(user, target, target_zone, tool, surgery) == -1)
if(preop(user, target, target_zone, tool, surgery) == SURGERY_STEP_FAIL)
surgery.step_in_progress = FALSE
return FALSE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

@@ -30,8 +30,10 @@
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_EXTERNAL_TAUR
layers = ALL_EXTERNAL_OVERLAYS
organ_flags = ORGAN_EXTERNAL
external_bodytypes = BODYTYPE_TAUR
color_source = ORGAN_COLOR_OVERRIDE
use_mob_sprite_as_obj_sprite = TRUE
feature_key = "taur"
preference = "feature_taur"
+1
View File
@@ -177,6 +177,7 @@
#include "code\__DEFINES\strippable.dm"
#include "code\__DEFINES\subsystems.dm"
#include "code\__DEFINES\supermatter.dm"
#include "code\__DEFINES\surgery.dm"
#include "code\__DEFINES\tcg.dm"
#include "code\__DEFINES\text.dm"
#include "code\__DEFINES\tgs.config.dm"