mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
Reverts "Removes mutant bodyparts"
This commit is contained in:
@@ -163,10 +163,7 @@
|
||||
///The species is forced to have digitigrade legs in generation.
|
||||
#define DIGITIGRADE_FORCED 2
|
||||
|
||||
// Preferences for leg types
|
||||
/// Legs that are normal
|
||||
#define NORMAL_LEGS "Normal Legs"
|
||||
/// Digitgrade legs that are like bended and uhhh no shoes
|
||||
///Digitigrade's prefs, used in features for legs if you're meant to be a Digitigrade.
|
||||
#define DIGITIGRADE_LEGS "Digitigrade Legs"
|
||||
|
||||
// Health/damage defines
|
||||
|
||||
@@ -15,6 +15,8 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars, list(
|
||||
"contents",
|
||||
"cooldowns",
|
||||
"_datum_components",
|
||||
"external_organs",
|
||||
"external_organs_slot",
|
||||
"group",
|
||||
"hand_bodyparts",
|
||||
"held_items",
|
||||
|
||||
@@ -47,6 +47,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
|
||||
var/list/horns_list
|
||||
var/list/frills_list
|
||||
var/list/spines_list
|
||||
var/list/legs_list
|
||||
var/list/tail_spines_list
|
||||
|
||||
//Mutant Human bits
|
||||
|
||||
@@ -13,24 +13,6 @@
|
||||
///Take on the dna/preference from whoever we're gonna be inserted in
|
||||
var/imprint_on_next_insertion = TRUE
|
||||
|
||||
/datum/bodypart_overlay/mutant/New(obj/item/organ/attached_organ)
|
||||
. = ..()
|
||||
|
||||
RegisterSignal(attached_organ, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_mob_insert))
|
||||
|
||||
/datum/bodypart_overlay/mutant/proc/on_mob_insert(obj/item/organ/parent, mob/living/carbon/receiver)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!should_visual_organ_apply_to(parent.type, receiver))
|
||||
stack_trace("adding a [parent.type] to a [receiver.type] when it shouldn't be!")
|
||||
|
||||
if(imprint_on_next_insertion) //We only want this set *once*
|
||||
var/feature_name = receiver.dna.features[feature_key]
|
||||
if (isnull(feature_name))
|
||||
feature_name = receiver.dna.species.mutant_organs[parent.type]
|
||||
set_appearance_from_name(feature_name)
|
||||
imprint_on_next_insertion = FALSE
|
||||
|
||||
/datum/bodypart_overlay/mutant/get_overlay(layer, obj/item/bodypart/limb)
|
||||
inherit_color(limb) // If draw_color is not set yet, go ahead and do that
|
||||
return ..()
|
||||
@@ -85,6 +67,7 @@
|
||||
return appearance
|
||||
|
||||
/datum/bodypart_overlay/mutant/color_image(image/overlay, layer, obj/item/bodypart/limb)
|
||||
|
||||
overlay.color = sprite_datum.color_src ? draw_color : null
|
||||
|
||||
/datum/bodypart_overlay/mutant/added_to_limb(obj/item/bodypart/limb)
|
||||
|
||||
@@ -755,8 +755,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
|
||||
dna.features["caps"] = SSaccessories.caps_list[deconstruct_block(get_uni_feature_block(features, DNA_MUSHROOM_CAPS_BLOCK), length(SSaccessories.caps_list))]
|
||||
if(dna.features["pod_hair"])
|
||||
dna.features["pod_hair"] = SSaccessories.pod_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_POD_HAIR_BLOCK), length(SSaccessories.pod_hair_list))]
|
||||
for(var/obj/item/organ/organ in organs)
|
||||
organ.mutate_feature(features, src)
|
||||
|
||||
for(var/obj/item/organ/external/external_organ in organs)
|
||||
external_organ.mutate_feature(features, src)
|
||||
|
||||
if(icon_update)
|
||||
update_body(is_creating = mutcolor_update)
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
else if(isorgan(new_part))
|
||||
var/obj/item/organ/new_organ = new_part
|
||||
old_part = human_holder.get_organ_slot(new_organ.slot)
|
||||
new_organ.Insert(human_holder, special = TRUE)
|
||||
if(new_organ.Insert(human_holder, special = TRUE))
|
||||
old_part.moveToNullspace()
|
||||
STOP_PROCESSING(SSobj, old_part)
|
||||
slot_string = new_organ.name
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
* This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none.
|
||||
*/
|
||||
var/color_src = MUTANT_COLOR
|
||||
/// Decides if this sprite has an "inner" part, such as the fleshy parts on ears.
|
||||
var/hasinner = FALSE
|
||||
/// Is this part locked from roundstart selection? Used for parts that apply effects.
|
||||
var/locked = FALSE
|
||||
/// Should we center the sprite?
|
||||
@@ -1891,6 +1893,7 @@
|
||||
/datum/sprite_accessory/ears/cat
|
||||
name = "Cat"
|
||||
icon_state = "cat"
|
||||
hasinner = TRUE
|
||||
color_src = HAIR_COLOR
|
||||
|
||||
/datum/sprite_accessory/ears/cat/miqo
|
||||
@@ -1913,6 +1916,7 @@
|
||||
icon = 'icons/mob/human/fox_features.dmi'
|
||||
name = "Fox"
|
||||
icon_state = "fox"
|
||||
hasinner = TRUE
|
||||
color_src = HAIR_COLOR
|
||||
locked = TRUE
|
||||
|
||||
@@ -2075,6 +2079,10 @@
|
||||
icon = 'icons/mob/human/species/lizard/lizard_spines.dmi'
|
||||
em_block = TRUE
|
||||
|
||||
/datum/sprite_accessory/spines/none
|
||||
name = SPRITE_ACCESSORY_NONE
|
||||
icon_state = "none"
|
||||
|
||||
/datum/sprite_accessory/tail_spines
|
||||
icon = 'icons/mob/human/species/lizard/lizard_spines.dmi'
|
||||
em_block = TRUE
|
||||
@@ -2119,6 +2127,16 @@
|
||||
name = "Aquatic"
|
||||
icon_state = "aqua"
|
||||
|
||||
/datum/sprite_accessory/legs //legs are a special case, they aren't actually sprite_accessories but are updated with them.
|
||||
icon = null //These datums exist for selecting legs on preference, and little else
|
||||
em_block = TRUE
|
||||
|
||||
/datum/sprite_accessory/legs/none
|
||||
name = "Normal Legs"
|
||||
|
||||
/datum/sprite_accessory/legs/digitigrade_lizard
|
||||
name = DIGITIGRADE_LEGS
|
||||
|
||||
/datum/sprite_accessory/caps
|
||||
icon = 'icons/mob/human/species/mush_cap.dmi'
|
||||
color_src = HAIR_COLOR
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
//useless organs we throw in just to fuck with surgeons a bit more. they aren't part of a bonus, just the (absolute) state of flies
|
||||
/obj/item/organ/internal/fly
|
||||
desc = FLY_INFUSED_ORGAN_DESC
|
||||
visual = FALSE
|
||||
|
||||
/obj/item/organ/internal/fly/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
color = ear_owner.hair_color
|
||||
ear_owner.dna.species.mutant_bodyparts -= "ears"
|
||||
ear_owner.update_body()
|
||||
|
||||
sprite_accessory_override = /datum/sprite_accessory/ears/fox
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
@@ -34,7 +34,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
|
||||
AddElement(/datum/element/noticable_organ, "%PRONOUN_They radiate%PRONOUN_s an aura of serenity.")
|
||||
AddElement(/datum/element/update_icon_blocker)
|
||||
|
||||
/obj/item/organ/internal/heart/gondola/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/internal/heart/gondola/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
if(!(FACTION_HOSTILE in receiver.faction))
|
||||
factions_to_remove += FACTION_HOSTILE
|
||||
@@ -42,7 +42,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
|
||||
factions_to_remove += FACTION_MINING
|
||||
receiver.faction |= list(FACTION_HOSTILE, FACTION_MINING)
|
||||
|
||||
/obj/item/organ/internal/heart/gondola/mob_remove(mob/living/carbon/heartless, special, movement_flags)
|
||||
/obj/item/organ/internal/heart/gondola/Remove(mob/living/carbon/heartless, special, movement_flags)
|
||||
. = ..()
|
||||
for(var/faction in factions_to_remove)
|
||||
heartless.faction -= faction
|
||||
@@ -64,11 +64,11 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
|
||||
AddElement(/datum/element/noticable_organ, "%PRONOUN_Their mouth is permanently affixed into a relaxed smile.", BODY_ZONE_PRECISE_MOUTH)
|
||||
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/gondola)
|
||||
|
||||
/obj/item/organ/internal/tongue/gondola/mob_insert(mob/living/carbon/tongue_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/tongue/gondola/Insert(mob/living/carbon/tongue_owner, special, movement_flags)
|
||||
. = ..()
|
||||
tongue_owner.add_mood_event("gondola_zen", /datum/mood_event/gondola_serenity)
|
||||
|
||||
/obj/item/organ/internal/tongue/gondola/mob_remove(mob/living/carbon/tongue_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/tongue/gondola/Remove(mob/living/carbon/tongue_owner, special, movement_flags)
|
||||
tongue_owner.clear_mood_event("gondola_zen")
|
||||
return ..()
|
||||
|
||||
@@ -87,7 +87,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
|
||||
AddElement(/datum/element/noticable_organ, "%PRONOUN_Their left arm has small needles breaching the skin all over it.", BODY_ZONE_L_ARM)
|
||||
AddElement(/datum/element/noticable_organ, "%PRONOUN_Their right arm has small needles breaching the skin all over it.", BODY_ZONE_R_ARM)
|
||||
|
||||
/obj/item/organ/internal/liver/gondola/mob_insert(mob/living/carbon/liver_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/liver/gondola/Insert(mob/living/carbon/liver_owner, special, movement_flags)
|
||||
. = ..()
|
||||
var/has_left = liver_owner.has_left_hand(check_disabled = FALSE)
|
||||
var/has_right = liver_owner.has_right_hand(check_disabled = FALSE)
|
||||
@@ -102,7 +102,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
|
||||
RegisterSignal(liver_owner, COMSIG_LIVING_TRY_PULL, PROC_REF(on_owner_try_pull))
|
||||
RegisterSignal(liver_owner, COMSIG_CARBON_HELPED, PROC_REF(on_hug))
|
||||
|
||||
/obj/item/organ/internal/liver/gondola/mob_remove(mob/living/carbon/liver_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/liver/gondola/Remove(mob/living/carbon/liver_owner, special, movement_flags)
|
||||
. = ..()
|
||||
UnregisterSignal(liver_owner, list(COMSIG_HUMAN_EQUIPPING_ITEM, COMSIG_LIVING_TRY_PULL, COMSIG_CARBON_HELPED))
|
||||
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
if(iscarbon(loc))
|
||||
Insert(loc)
|
||||
|
||||
/obj/item/organ/internal/body_egg/mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
/obj/item/organ/internal/body_egg/Insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
egg_owner.add_traits(list(TRAIT_XENO_HOST, TRAIT_XENO_IMMUNE), ORGAN_TRAIT)
|
||||
egg_owner.med_hud_set_status()
|
||||
INVOKE_ASYNC(src, PROC_REF(AddInfectionImages), egg_owner)
|
||||
|
||||
/obj/item/organ/internal/body_egg/mob_remove(mob/living/carbon/egg_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/body_egg/Remove(mob/living/carbon/egg_owner, special, movement_flags)
|
||||
. = ..()
|
||||
egg_owner.remove_traits(list(TRAIT_XENO_HOST, TRAIT_XENO_IMMUNE), ORGAN_TRAIT)
|
||||
egg_owner.med_hud_set_status()
|
||||
|
||||
@@ -18,7 +18,10 @@ ADMIN_VERB(manipulate_organs, R_DEBUG, "Manipulate Organs", "Manipulate the orga
|
||||
return
|
||||
organ_to_grant = organs[organ_to_grant]
|
||||
organ_to_grant = new organ_to_grant
|
||||
organ_to_grant.Insert(carbon_victim)
|
||||
if(!organ_to_grant.Insert(carbon_victim))
|
||||
to_chat(user, span_notice("[carbon_victim] is unable to carry this organ!"))
|
||||
qdel(organ_to_grant)
|
||||
return
|
||||
log_admin("[key_name(user)] has added organ [organ_to_grant.type] to [key_name(carbon_victim)]")
|
||||
message_admins("[key_name_admin(user)] has added organ [organ_to_grant.type] to [ADMIN_LOOKUPFLW(carbon_victim)]")
|
||||
|
||||
|
||||
@@ -526,7 +526,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w
|
||||
var/forename = names.len > 1 ? names[2] : names[1]
|
||||
var/newname = "[forename]-[pick(honorifics["[H.gender]"])]"
|
||||
H.fully_replace_character_name(H.real_name,newname)
|
||||
H.update_body_parts()
|
||||
H.update_mutant_bodyparts()
|
||||
if(animetype == "Yes")
|
||||
var/seifuku = pick(typesof(/obj/item/clothing/under/costume/schoolgirl))
|
||||
var/obj/item/clothing/under/costume/schoolgirl/I = new seifuku
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
active_mind_control = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/internal/heart/gland/mob_remove(mob/living/carbon/gland_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/heart/gland/Remove(mob/living/carbon/gland_owner, special, movement_flags)
|
||||
. = ..()
|
||||
active = FALSE
|
||||
if(initial(uses) == 1)
|
||||
@@ -93,8 +93,10 @@
|
||||
hud.remove_atom_from_hud(gland_owner)
|
||||
clear_mind_control()
|
||||
|
||||
/obj/item/organ/internal/heart/gland/mob_insert(mob/living/carbon/gland_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
/obj/item/organ/internal/heart/gland/Insert(mob/living/carbon/gland_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(special != 2 && uses) // Special 2 means abductor surgery
|
||||
Start()
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
/// When this egg last got removed from a body. If -1, the egg hasn't been removed from a body.
|
||||
var/removal_time = -1
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/Insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
. = ..()
|
||||
hatch_time = world.time + (removal_time == -1 ? EGG_INCUBATION_TIME : (hatch_time - removal_time))
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/mob_remove(mob/living/carbon/egg_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/Remove(mob/living/carbon/egg_owner, special, movement_flags)
|
||||
. = ..()
|
||||
removal_time = world.time
|
||||
|
||||
|
||||
@@ -418,13 +418,20 @@
|
||||
usable_organs -= /obj/item/organ/internal/lungs/corrupt // Their lungs are already more cursed than anything I could give them
|
||||
|
||||
var/total_implant = rand(2, 4)
|
||||
var/gave_any = FALSE
|
||||
|
||||
for (var/i in 1 to total_implant)
|
||||
if (!length(usable_organs))
|
||||
return
|
||||
break
|
||||
var/organ_path = pick_n_take(usable_organs)
|
||||
var/obj/item/organ/internal/to_give = new organ_path
|
||||
to_give.Insert(sac_target)
|
||||
if (!to_give.Insert(sac_target))
|
||||
qdel(to_give)
|
||||
else
|
||||
gave_any = TRUE
|
||||
|
||||
if (!gave_any)
|
||||
return
|
||||
|
||||
new /obj/effect/gibspawner/human/bodypartless(get_turf(sac_target))
|
||||
sac_target.visible_message(span_boldwarning("Several organs force themselves out of [sac_target]!"))
|
||||
|
||||
@@ -65,10 +65,9 @@
|
||||
/obj/item/organ/internal/heart/nightmare
|
||||
name = "heart of darkness"
|
||||
desc = "An alien organ that twists and writhes when exposed to light."
|
||||
visual = TRUE
|
||||
icon_state = "demon_heart-on"
|
||||
base_icon_state = "demon_heart"
|
||||
|
||||
visual = TRUE
|
||||
color = COLOR_CRAYON_BLACK
|
||||
decay_factor = 0
|
||||
// No love is to be found in a heart so twisted.
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
if(affected_mob)
|
||||
affected_mob.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#1d2953")
|
||||
if(affected_mob.dna && affected_mob.dna.species)
|
||||
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob)
|
||||
affected_mob.set_haircolor(null, override = TRUE)
|
||||
to_chat(affected_mob, span_notice("You feel better."))
|
||||
..()
|
||||
@@ -65,6 +66,7 @@
|
||||
affected_mob.adjustStaminaLoss(22.5 * seconds_per_tick, updating_stamina = FALSE)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(affected_mob.dna && affected_mob.dna.species)
|
||||
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
|
||||
affected_mob.set_haircolor("#1d2953", override = TRUE)
|
||||
affected_mob.visible_message(span_warning("[affected_mob] looks terrifyingly gaunt..."), span_revennotice("You suddenly feel like your skin is <i>wrong</i>..."))
|
||||
affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY)
|
||||
|
||||
@@ -111,6 +111,10 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
||||
/// DOES have random body on, will this already be randomized?
|
||||
var/randomize_by_default = TRUE
|
||||
|
||||
/// If the selected species has this in its /datum/species/mutant_bodyparts,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_mutant_bodypart = null
|
||||
|
||||
/// If the selected species has this in its /datum/species/body_markings,
|
||||
/// will show the feature as selectable.
|
||||
var/relevant_body_markings = null
|
||||
@@ -332,7 +336,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
if ( \
|
||||
!isnull(relevant_inherent_trait) \
|
||||
!isnull(relevant_mutant_bodypart) \
|
||||
|| !isnull(relevant_inherent_trait) \
|
||||
|| !isnull(relevant_external_organ) \
|
||||
|| !isnull(relevant_head_flag) \
|
||||
|| !isnull(relevant_body_markings) \
|
||||
|
||||
@@ -94,51 +94,13 @@
|
||||
savefile_key = "feature_lizard_legs"
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
relevant_mutant_bodypart = "legs"
|
||||
|
||||
/datum/preference/choiced/lizard_legs/init_possible_values()
|
||||
return list(NORMAL_LEGS, DIGITIGRADE_LEGS)
|
||||
return assoc_to_keys_features(SSaccessories.legs_list)
|
||||
|
||||
/datum/preference/choiced/lizard_legs/apply_to_human(mob/living/carbon/human/target, value)
|
||||
target.dna.features["legs"] = value
|
||||
// Hack to update the dummy in the preference menu
|
||||
// (Because digi legs are ONLY handled on species change)
|
||||
if(!isdummy(target) || target.dna.species.digitigrade_customization == DIGITIGRADE_NEVER)
|
||||
return
|
||||
|
||||
var/list/correct_legs = target.dna.species.bodypart_overrides.Copy() & list(BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
|
||||
|
||||
if(value == DIGITIGRADE_LEGS)
|
||||
correct_legs[BODY_ZONE_R_LEG] = /obj/item/bodypart/leg/right/digitigrade
|
||||
correct_legs[BODY_ZONE_L_LEG] = /obj/item/bodypart/leg/left/digitigrade
|
||||
|
||||
for(var/obj/item/bodypart/old_part as anything in target.bodyparts)
|
||||
if(old_part.change_exempt_flags & BP_BLOCK_CHANGE_SPECIES)
|
||||
continue
|
||||
|
||||
var/path = correct_legs[old_part.body_zone]
|
||||
if(!path)
|
||||
continue
|
||||
var/obj/item/bodypart/new_part = new path()
|
||||
new_part.replace_limb(target, TRUE)
|
||||
new_part.update_limb(is_creating = TRUE)
|
||||
qdel(old_part)
|
||||
|
||||
/datum/preference/choiced/lizard_legs/is_accessible(datum/preferences/preferences)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/datum/species/species_type = preferences.read_preference(/datum/preference/choiced/species)
|
||||
return initial(species_type.digitigrade_customization) == DIGITIGRADE_OPTIONAL
|
||||
|
||||
|
||||
/datum/preference/choiced/lizard_legs/is_accessible(datum/preferences/preferences)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
|
||||
var/datum/species/species_type = preferences.read_preference(/datum/preference/choiced/species)
|
||||
|
||||
return initial(species_type.digitigrade_customization) & DIGITIGRADE_OPTIONAL
|
||||
|
||||
/datum/preference/choiced/lizard_snout
|
||||
savefile_key = "feature_lizard_snout"
|
||||
@@ -160,7 +122,7 @@
|
||||
savefile_key = "feature_lizard_spines"
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
relevant_external_organ = /obj/item/organ/external/spines
|
||||
relevant_mutant_bodypart = "spines"
|
||||
|
||||
/datum/preference/choiced/lizard_spines/init_possible_values()
|
||||
return assoc_to_keys_features(SSaccessories.spines_list)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
savefile_key = "feature_mushperson_cap"
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||
relevant_external_organ = /obj/item/organ/external/mushroom_cap
|
||||
relevant_mutant_bodypart = "cap"
|
||||
|
||||
/datum/preference/choiced/mushroom_cap/init_possible_values()
|
||||
return assoc_to_keys_features(SSaccessories.caps_list)
|
||||
|
||||
@@ -387,7 +387,7 @@
|
||||
if (organ.type == target_species.get_mutant_organ_type_for_slot(organ.slot))
|
||||
continue
|
||||
else
|
||||
if ((organ.type in target_species.mutant_organs))
|
||||
if ((organ.type in target_species.mutant_organs) || (organ.type in target_species.external_organs))
|
||||
continue
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -10,7 +10,7 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and
|
||||
desc = "This shard seems to be directly linked to some sinister entity. It might be your god! It also gives you a really horrible rash when you hold onto it for too long."
|
||||
items_to_create = list(/obj/item/vorpalscythe)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/shard/scythe/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/internal/cyberimp/arm/shard/scythe/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
if(receiver.mind)
|
||||
ADD_TRAIT(receiver.mind, TRAIT_MORBID, ORGAN_TRAIT)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
icon = 'icons/obj/medical/organs/mining_organs.dmi'
|
||||
icon_state = "hivelord_core"
|
||||
actions_types = list(/datum/action/cooldown/monster_core_action)
|
||||
visual = FALSE
|
||||
item_flags = NOBLUDGEON
|
||||
slot = ORGAN_SLOT_MONSTER_CORE
|
||||
organ_flags = ORGAN_ORGANIC
|
||||
@@ -65,9 +66,10 @@
|
||||
deltimer(decay_timer)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/internal/monster_core/mob_insert(mob/living/carbon/target_carbon, special = FALSE, movement_flags)
|
||||
/obj/item/organ/internal/monster_core/Insert(mob/living/carbon/target_carbon, special = FALSE, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
if (inert)
|
||||
to_chat(target_carbon, span_notice("[src] breaks down as you try to insert it."))
|
||||
qdel(src)
|
||||
@@ -78,7 +80,7 @@
|
||||
target_carbon.visible_message(span_notice("[src] stabilizes as it's inserted."))
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/internal/monster_core/mob_remove(mob/living/carbon/target_carbon, special, movement_flags)
|
||||
/obj/item/organ/internal/monster_core/Remove(mob/living/carbon/target_carbon, special, movement_flags)
|
||||
if (!inert && !special)
|
||||
owner.visible_message(span_notice("[src] rapidly decays as it's removed."))
|
||||
go_inert()
|
||||
|
||||
@@ -557,6 +557,7 @@
|
||||
var/obj/item/organ/external/wings/functional/wings = get_wing_choice(exposed_human, chest)
|
||||
wings = new wings()
|
||||
wings.Insert(exposed_human)
|
||||
exposed_human.dna.species.handle_mutant_bodyparts(exposed_human)
|
||||
playsound(exposed_human.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1)
|
||||
exposed_human.apply_damage(20, def_zone = BODY_ZONE_CHEST, forced = TRUE, wound_bonus = CANT_WOUND)
|
||||
exposed_human.emote("scream")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/item/organ/internal/alien
|
||||
icon_state = "acid"
|
||||
visual = FALSE
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/toxin/acid = 10)
|
||||
|
||||
/obj/item/organ/internal/alien/plasmavessel
|
||||
@@ -221,11 +222,11 @@
|
||||
stomach_contents -= source
|
||||
UnregisterSignal(source, list(COMSIG_MOVABLE_MOVED, COMSIG_LIVING_DEATH, COMSIG_QDELETING))
|
||||
|
||||
/obj/item/organ/internal/stomach/alien/mob_insert(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/stomach/alien/Insert(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
RegisterSignal(stomach_owner, COMSIG_ATOM_RELAYMOVE, PROC_REF(something_moved))
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/internal/stomach/alien/mob_remove(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/stomach/alien/Remove(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
UnregisterSignal(stomach_owner, COMSIG_ATOM_RELAYMOVE)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -53,8 +53,13 @@
|
||||
overlays_standing[cache_index] = null
|
||||
SEND_SIGNAL(src, COMSIG_CARBON_REMOVE_OVERLAY, cache_index, I)
|
||||
|
||||
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
|
||||
/mob/living/carbon/human/proc/update_mutant_bodyparts()
|
||||
dna?.species.handle_mutant_bodyparts(src)
|
||||
update_body_parts()
|
||||
|
||||
/mob/living/carbon/update_body(is_creating = FALSE)
|
||||
dna?.species.handle_body(src)
|
||||
dna?.species.handle_body(src) //This calls `handle_mutant_bodyparts` which calls `update_mutant_bodyparts()`. Don't double call!
|
||||
update_body_parts(is_creating)
|
||||
|
||||
/mob/living/carbon/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
|
||||
|
||||
@@ -80,8 +80,10 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right,
|
||||
BODY_ZONE_CHEST = /obj/item/bodypart/chest,
|
||||
)
|
||||
///Internal organs that are unique to this race, like a tail or other cosmetic organs. list(typepath of organ 1, typepath of organ 2 = "Round").
|
||||
///Internal organs that are unique to this race, like a tail. list(typepath of organ 1, typepath of organ 2)
|
||||
var/list/mutant_organs = list()
|
||||
///List of external organs to generate like horns, frills, wings, etc. list(typepath of organ = "Round Beautiful BDSM Snout"). Still WIP
|
||||
var/list/external_organs = list()
|
||||
///Replaces default brain with a different organ
|
||||
var/obj/item/organ/internal/brain/mutantbrain = /obj/item/organ/internal/brain
|
||||
///Replaces default heart with a different organ
|
||||
@@ -282,10 +284,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
if(ORGAN_SLOT_STOMACH)
|
||||
return mutantstomach
|
||||
else
|
||||
// Non-standard organs we might have
|
||||
for(var/obj/item/organ/extra_organ as anything in mutant_organs)
|
||||
if(initial(extra_organ.slot) == slot)
|
||||
return extra_organ
|
||||
CRASH("Invalid organ slot [slot]")
|
||||
|
||||
/**
|
||||
* Corrects organs in a carbon, removing ones it doesn't need and adding ones it does.
|
||||
@@ -301,33 +300,46 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
* * visual_only - boolean, only load organs that change how the species looks. Do not use for normal gameplay stuff
|
||||
*/
|
||||
/datum/species/proc/regenerate_organs(mob/living/carbon/organ_holder, datum/species/old_species, replace_current = TRUE, list/excluded_zones, visual_only = FALSE)
|
||||
for(var/slot in get_all_slots())
|
||||
//what should be put in if there is no mutantorgan (brains handled separately)
|
||||
var/list/organ_slots = list(
|
||||
ORGAN_SLOT_BRAIN,
|
||||
ORGAN_SLOT_HEART,
|
||||
ORGAN_SLOT_LUNGS,
|
||||
ORGAN_SLOT_APPENDIX,
|
||||
ORGAN_SLOT_EYES,
|
||||
ORGAN_SLOT_EARS,
|
||||
ORGAN_SLOT_TONGUE,
|
||||
ORGAN_SLOT_LIVER,
|
||||
ORGAN_SLOT_STOMACH,
|
||||
)
|
||||
|
||||
for(var/slot in organ_slots)
|
||||
var/obj/item/organ/existing_organ = organ_holder.get_organ_slot(slot)
|
||||
var/obj/item/organ/new_organ = get_mutant_organ_type_for_slot(slot)
|
||||
var/old_organ_type = old_species?.get_mutant_organ_type_for_slot(slot)
|
||||
|
||||
// if we have an extra organ that before changing that the species didnt have, remove it
|
||||
if(!new_organ)
|
||||
if(existing_organ && (old_organ_type == existing_organ.type || replace_current))
|
||||
existing_organ.Remove(organ_holder)
|
||||
if(isnull(new_organ)) // if they aren't suppose to have an organ here, remove it
|
||||
if(existing_organ)
|
||||
existing_organ.Remove(organ_holder, special = TRUE)
|
||||
qdel(existing_organ)
|
||||
continue
|
||||
|
||||
if(existing_organ)
|
||||
// we dont want to remove organs that were not from the old species (such as from freak surgery or prosthetics)
|
||||
if(existing_organ.type != old_organ_type && !replace_current && !remove_features) // SKYRAT EDIT - Fixes certain species lacking a tongue (Looks at abductor)
|
||||
// we don't want to remove organs that are not the default for this species
|
||||
if(!isnull(existing_organ) && !remove_features) // SKYRAT EDIT - Fixes certain species lacking a tongue (Looks at abductor)
|
||||
if(!isnull(old_species) && existing_organ.type != old_species.get_mutant_organ_type_for_slot(slot))
|
||||
continue
|
||||
else if(!replace_current && existing_organ.type != get_mutant_organ_type_for_slot(slot))
|
||||
continue
|
||||
|
||||
// we don't want to remove organs that are the same as the new one
|
||||
if(existing_organ.type == new_organ)
|
||||
continue
|
||||
// at this point we already know new_organ is not null
|
||||
if(existing_organ?.type == new_organ)
|
||||
continue // we don't want to remove organs that are the same as the new one
|
||||
|
||||
if(visual_only && (!initial(new_organ.bodypart_overlay) && !initial(new_organ.visual)))
|
||||
if(visual_only && !initial(new_organ.visual))
|
||||
continue
|
||||
|
||||
var/used_neworgan = FALSE
|
||||
new_organ = SSwardrobe.provide_type(new_organ)
|
||||
var/should_have = new_organ.get_availability(src, organ_holder) && should_visual_organ_apply_to(new_organ, organ_holder)
|
||||
var/should_have = new_organ.get_availability(src, organ_holder)
|
||||
|
||||
// Check for an existing organ, and if there is one check to see if we should remove it
|
||||
var/health_pct = 1
|
||||
@@ -351,6 +363,46 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
if(!used_neworgan)
|
||||
QDEL_NULL(new_organ)
|
||||
|
||||
if(!isnull(old_species))
|
||||
for(var/mutant_organ in old_species.mutant_organs)
|
||||
if(mutant_organ in mutant_organs)
|
||||
continue // need this mutant organ, but we already have it!
|
||||
|
||||
var/obj/item/organ/current_organ = organ_holder.get_organ_by_type(mutant_organ)
|
||||
if(current_organ)
|
||||
current_organ.Remove(organ_holder)
|
||||
QDEL_NULL(current_organ)
|
||||
|
||||
for(var/obj/item/organ/external/external_organ in organ_holder.organs)
|
||||
// External organ checking. We need to check the external organs owned by the carbon itself,
|
||||
// because we want to also remove ones not shared by its species.
|
||||
// This should be done even if species was not changed.
|
||||
if(external_organ in external_organs)
|
||||
continue // Don't remove external organs this species is supposed to have.
|
||||
|
||||
external_organ.Remove(organ_holder)
|
||||
QDEL_NULL(external_organ)
|
||||
|
||||
var/list/species_organs = mutant_organs + external_organs
|
||||
for(var/organ_path in species_organs)
|
||||
var/obj/item/organ/current_organ = organ_holder.get_organ_by_type(organ_path)
|
||||
if(ispath(organ_path, /obj/item/organ/external) && !should_external_organ_apply_to(organ_path, organ_holder))
|
||||
if(!isnull(current_organ) && replace_current)
|
||||
// if we have an organ here and we're replacing organs, remove it
|
||||
current_organ.Remove(organ_holder)
|
||||
QDEL_NULL(current_organ)
|
||||
continue
|
||||
|
||||
if(!current_organ || replace_current)
|
||||
var/obj/item/organ/replacement = SSwardrobe.provide_type(organ_path)
|
||||
// If there's an existing mutant organ, we're technically replacing it.
|
||||
// Let's abuse the snowflake proc that skillchips added. Basically retains
|
||||
// feature parity with every other organ too.
|
||||
if(current_organ)
|
||||
current_organ.before_organ_replacement(replacement)
|
||||
// organ.Insert will qdel any current organs in that slot, so we don't need to.
|
||||
replacement.Insert(organ_holder, special=TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
|
||||
/datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer)
|
||||
for(var/obj/item/equipped_item in wearer.get_equipped_items(INCLUDE_POCKETS))
|
||||
var/equipped_item_slot = wearer.get_slot_by_item(equipped_item)
|
||||
@@ -392,7 +444,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
if(old_species.type != type)
|
||||
replace_body(human_who_gained_species, src)
|
||||
|
||||
regenerate_organs(human_who_gained_species, old_species, replace_current = FALSE, visual_only = human_who_gained_species.visual_only_organs)
|
||||
regenerate_organs(human_who_gained_species, old_species, visual_only = human_who_gained_species.visual_only_organs)
|
||||
|
||||
// Drop the items the new species can't wear
|
||||
INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), human_who_gained_species, TRUE)
|
||||
@@ -408,6 +460,16 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
//Resets blood if it is excessively high so they don't gib
|
||||
normalize_blood(human_who_gained_species)
|
||||
|
||||
if(ishuman(human_who_gained_species))
|
||||
var/mob/living/carbon/human/human = human_who_gained_species
|
||||
for(var/obj/item/organ/external/organ_path as anything in external_organs)
|
||||
if(!should_external_organ_apply_to(organ_path, human))
|
||||
continue
|
||||
|
||||
//Load a persons preferences from DNA
|
||||
var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path)
|
||||
new_organ.Insert(human, special=TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
|
||||
//add_body_markings(human_who_gained_species) // SKYRAT EDIT REMOVAL - We do this differently
|
||||
|
||||
if(length(inherent_traits))
|
||||
@@ -448,6 +510,10 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
for(var/X in inherent_traits)
|
||||
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
|
||||
|
||||
for(var/obj/item/organ/external/organ in C.organs)
|
||||
organ.Remove(C)
|
||||
qdel(organ)
|
||||
|
||||
//If their inert mutation is not the same, swap it out
|
||||
if((inert_mutation != new_species.inert_mutation) && LAZYLEN(C.dna.mutation_index) && (inert_mutation in C.dna.mutation_index))
|
||||
C.dna.remove_mutation(inert_mutation)
|
||||
@@ -481,6 +547,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
* Handles the body of a human
|
||||
*
|
||||
* Handles lipstick, having no eyes, eye color, undergarnments like underwear, undershirts, and socks, and body layers.
|
||||
* Calls [handle_mutant_bodyparts][/datum/species/proc/handle_mutant_bodyparts]
|
||||
* Arguments:
|
||||
* * species_human - Human, whoever we're handling the body for
|
||||
*/
|
||||
@@ -489,7 +556,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
/datum/species/proc/handle_body(mob/living/carbon/human/species_human)
|
||||
species_human.remove_overlay(BODY_LAYER)
|
||||
if(HAS_TRAIT(species_human, TRAIT_INVISIBLE_MAN))
|
||||
return
|
||||
return handle_mutant_bodyparts(species_human)
|
||||
var/list/standing = list()
|
||||
|
||||
if(!HAS_TRAIT(species_human, TRAIT_HUSK))
|
||||
@@ -534,7 +601,105 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
species_human.overlays_standing[BODY_LAYER] = standing
|
||||
|
||||
species_human.apply_overlay(BODY_LAYER)
|
||||
update_body_markings(species_human)
|
||||
handle_mutant_bodyparts(species_human)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handles the mutant bodyparts of a human
|
||||
*
|
||||
* Handles the adding and displaying of, layers, colors, and overlays of mutant bodyparts and accessories.
|
||||
* Handles digitigrade leg displaying and squishing.
|
||||
* Arguments:
|
||||
* * H - Human, whoever we're handling the body for
|
||||
* * forced_colour - The forced color of an accessory. Leave null to use mutant color.
|
||||
*/
|
||||
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/source, forced_colour)
|
||||
var/list/bodyparts_to_add = mutant_bodyparts.Copy()
|
||||
var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
var/list/standing = list()
|
||||
|
||||
source.remove_overlay(BODY_BEHIND_LAYER)
|
||||
source.remove_overlay(BODY_ADJ_LAYER)
|
||||
source.remove_overlay(BODY_FRONT_LAYER)
|
||||
|
||||
if(!mutant_bodyparts || HAS_TRAIT(source, TRAIT_INVISIBLE_MAN))
|
||||
return
|
||||
|
||||
var/obj/item/bodypart/head/noggin = source.get_bodypart(BODY_ZONE_HEAD)
|
||||
|
||||
|
||||
if(mutant_bodyparts["ears"])
|
||||
if(!source.dna.features["ears"] || source.dna.features["ears"] == "None" || source.head && (source.head.flags_inv & HIDEHAIR) || (source.wear_mask && (source.wear_mask.flags_inv & HIDEHAIR)) || !noggin || IS_ROBOTIC_LIMB(noggin))
|
||||
bodyparts_to_add -= "ears"
|
||||
|
||||
if(!bodyparts_to_add)
|
||||
return
|
||||
|
||||
var/g = (source.physique == FEMALE) ? "f" : "m"
|
||||
|
||||
for(var/layer in relevent_layers)
|
||||
var/layertext = mutant_bodyparts_layertext(layer)
|
||||
|
||||
for(var/bodypart in bodyparts_to_add)
|
||||
var/datum/sprite_accessory/accessory
|
||||
switch(bodypart)
|
||||
if("ears")
|
||||
accessory = SSaccessories.ears_list[source.dna.features["ears"]]
|
||||
if("legs")
|
||||
accessory = SSaccessories.legs_list[source.dna.features["legs"]]
|
||||
|
||||
if(!accessory || accessory.icon_state == "none")
|
||||
continue
|
||||
|
||||
var/mutable_appearance/accessory_overlay = mutable_appearance(accessory.icon, layer = -layer)
|
||||
|
||||
if(accessory.gender_specific)
|
||||
accessory_overlay.icon_state = "[g]_[bodypart]_[accessory.icon_state]_[layertext]"
|
||||
else
|
||||
accessory_overlay.icon_state = "m_[bodypart]_[accessory.icon_state]_[layertext]"
|
||||
|
||||
if(accessory.em_block)
|
||||
accessory_overlay.overlays += emissive_blocker(accessory_overlay.icon, accessory_overlay.icon_state, source, accessory_overlay.alpha)
|
||||
|
||||
if(accessory.center)
|
||||
accessory_overlay = center_image(accessory_overlay, accessory.dimension_x, accessory.dimension_y)
|
||||
|
||||
if(!(HAS_TRAIT(source, TRAIT_HUSK)))
|
||||
if(!forced_colour)
|
||||
switch(accessory.color_src)
|
||||
if(MUTANT_COLOR)
|
||||
accessory_overlay.color = fixed_mut_color || source.dna.features["mcolor"]
|
||||
if(HAIR_COLOR)
|
||||
accessory_overlay.color = get_fixed_hair_color(source) || source.hair_color
|
||||
if(FACIAL_HAIR_COLOR)
|
||||
accessory_overlay.color = get_fixed_hair_color(source) || source.facial_hair_color
|
||||
if(EYE_COLOR)
|
||||
accessory_overlay.color = source.eye_color_left
|
||||
else
|
||||
accessory_overlay.color = forced_colour
|
||||
standing += accessory_overlay
|
||||
|
||||
if(accessory.hasinner)
|
||||
var/mutable_appearance/inner_accessory_overlay = mutable_appearance(accessory.icon, layer = -layer)
|
||||
if(accessory.gender_specific)
|
||||
inner_accessory_overlay.icon_state = "[g]_[bodypart]inner_[accessory.icon_state]_[layertext]"
|
||||
else
|
||||
inner_accessory_overlay.icon_state = "m_[bodypart]inner_[accessory.icon_state]_[layertext]"
|
||||
|
||||
if(accessory.center)
|
||||
inner_accessory_overlay = center_image(inner_accessory_overlay, accessory.dimension_x, accessory.dimension_y)
|
||||
|
||||
standing += inner_accessory_overlay
|
||||
|
||||
source.overlays_standing[layer] = standing.Copy()
|
||||
standing = list()
|
||||
|
||||
source.apply_overlay(BODY_BEHIND_LAYER)
|
||||
source.apply_overlay(BODY_ADJ_LAYER)
|
||||
source.apply_overlay(BODY_FRONT_LAYER)
|
||||
|
||||
update_body_markings(source)
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
@@ -586,9 +751,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
|
||||
var/list/new_features = list()
|
||||
var/static/list/organs_to_randomize = list()
|
||||
for(var/obj/item/organ/organ_path as anything in mutant_organs)
|
||||
if(!organ_path.bodypart_overlay)
|
||||
continue
|
||||
for(var/obj/item/organ/external/organ_path as anything in external_organs)
|
||||
var/overlay_path = initial(organ_path.bodypart_overlay)
|
||||
var/datum/bodypart_overlay/mutant/sample_overlay = organs_to_randomize[overlay_path]
|
||||
if(isnull(sample_overlay))
|
||||
@@ -1443,14 +1606,15 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
var/datum/preference/preference = GLOB.preference_entries[preference_type]
|
||||
|
||||
if ( \
|
||||
(preference.relevant_inherent_trait in inherent_traits) \
|
||||
|| (preference.relevant_external_organ in mutant_organs) \
|
||||
(preference.relevant_mutant_bodypart in mutant_bodyparts) \
|
||||
|| (preference.relevant_inherent_trait in inherent_traits) \
|
||||
|| (preference.relevant_external_organ in external_organs) \
|
||||
|| (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \
|
||||
|| (preference.relevant_body_markings in body_markings) \
|
||||
)
|
||||
features += preference.savefile_key
|
||||
|
||||
for (var/obj/item/organ/organ_type as anything in mutant_organs)
|
||||
for (var/obj/item/organ/external/organ_type as anything in external_organs)
|
||||
var/preference = initial(organ_type.preference)
|
||||
if (!isnull(preference))
|
||||
features += preference
|
||||
@@ -1496,7 +1660,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
/datum/species/proc/get_types_to_preload()
|
||||
var/list/to_store = list()
|
||||
to_store += mutant_organs
|
||||
for(var/obj/item/organ/horny as anything in mutant_organs)
|
||||
for(var/obj/item/organ/external/horny as anything in external_organs)
|
||||
to_store += horny //Haha get it?
|
||||
|
||||
//Don't preload brains, cause reuse becomes a horrible headache
|
||||
@@ -2108,10 +2272,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
|
||||
/// Update the overlays if necessary
|
||||
/datum/species/proc/update_body_markings(mob/living/carbon/human/hooman)
|
||||
if(HAS_TRAIT(hooman, TRAIT_INVISIBLE_MAN))
|
||||
remove_body_markings(hooman)
|
||||
return
|
||||
|
||||
var/needs_update = FALSE
|
||||
for(var/datum/bodypart_overlay/simple/body_marking/marking as anything in body_markings)
|
||||
if(initial(marking.dna_feature_key) == body_markings[marking]) // dna is same as our species (sort of mini-cache), so no update needed
|
||||
|
||||
@@ -161,8 +161,7 @@ There are several things that need to be remembered:
|
||||
overlays_standing[UNIFORM_LAYER] = uniform_overlay
|
||||
apply_overlay(UNIFORM_LAYER)
|
||||
|
||||
update_body_parts()
|
||||
apply_overlay(UNIFORM_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/mob/living/carbon/human/update_worn_id(update_obscured = TRUE)
|
||||
remove_overlay(ID_LAYER)
|
||||
@@ -591,8 +590,11 @@ There are several things that need to be remembered:
|
||||
// SKYRAT EDIT END
|
||||
overlays_standing[SUIT_LAYER] = suit_overlay
|
||||
update_body_parts()
|
||||
update_mutant_bodyparts()
|
||||
|
||||
apply_overlay(SUIT_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_pockets()
|
||||
if(client && hud_used)
|
||||
var/atom/movable/screen/inventory/inv
|
||||
@@ -660,7 +662,7 @@ There are several things that need to be remembered:
|
||||
overlays_standing[FACEMASK_LAYER] = mask_overlay
|
||||
|
||||
apply_overlay(FACEMASK_LAYER)
|
||||
update_body_parts() //e.g. upgate needed because mask now hides lizard snout
|
||||
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
|
||||
|
||||
/mob/living/carbon/human/update_worn_back(update_obscured = TRUE)
|
||||
remove_overlay(BACK_LAYER)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
BODY_ZONE_CHEST = /obj/item/bodypart/chest,
|
||||
)
|
||||
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
|
||||
mutant_bodyparts = list("wings" = "None")
|
||||
mutantbrain = /obj/item/organ/internal/brain/dullahan
|
||||
mutanteyes = /obj/item/organ/internal/eyes/dullahan
|
||||
mutanttongue = /obj/item/organ/internal/tongue/dullahan
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
// stored_feature_id is only set once (the first time an organ is inserted), so this should be safe.
|
||||
var/obj/item/organ/internal/ears/cat/kitty_ears = new
|
||||
kitty_ears.Insert(soon_to_be_felinid, special = TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
if(should_visual_organ_apply_to(/obj/item/organ/external/tail/cat, soon_to_be_felinid)) //only give them a tail if they actually have sprites for it / are a compatible subspecies.
|
||||
if(should_external_organ_apply_to(/obj/item/organ/external/tail/cat, soon_to_be_felinid)) //only give them a tail if they actually have sprites for it / are a compatible subspecies.
|
||||
var/obj/item/organ/external/tail/cat/kitty_tail = new
|
||||
kitty_tail.Insert(soon_to_be_felinid, special = TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
|
||||
@@ -184,8 +184,8 @@
|
||||
old_tail.Remove(purrbated_human, special = TRUE)
|
||||
qdel(old_tail)
|
||||
// Locate does not work on assoc lists, so we do it by hand
|
||||
for(var/external_organ in target_species.mutant_organs)
|
||||
if(!should_visual_organ_apply_to(external_organ, purrbated_human))
|
||||
for(var/external_organ in target_species.external_organs)
|
||||
if(!should_external_organ_apply_to(external_organ, purrbated_human))
|
||||
continue
|
||||
if(ispath(external_organ, /obj/item/organ/external/tail))
|
||||
var/obj/item/organ/external/tail/new_tail = new external_organ()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/datum/species/monkey
|
||||
name = "\improper Monkey"
|
||||
id = SPECIES_MONKEY
|
||||
mutant_organs = list(
|
||||
external_organs = list(
|
||||
/obj/item/organ/external/tail/monkey = "Monkey",
|
||||
)
|
||||
mutanttongue = /obj/item/organ/internal/tongue/monkey
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/moth,
|
||||
)
|
||||
|
||||
/datum/species/moth/regenerate_organs(mob/living/carbon/C, datum/species/old_species, replace_current= TRUE, list/excluded_zones, visual_only)
|
||||
. = ..()
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
handle_mutant_bodyparts(H)
|
||||
|
||||
/datum/species/moth/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load)
|
||||
. = ..()
|
||||
RegisterSignal(human_who_gained_species, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
fixed_mut_color = "#DBBF92"
|
||||
|
||||
mutant_organs = list(/obj/item/organ/external/mushroom_cap = "Round")
|
||||
external_organs = list(/obj/item/organ/external/mushroom_cap = "Round")
|
||||
|
||||
inherent_traits = list(
|
||||
TRAIT_MUTANT_COLORS,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
TRAIT_NO_MIRROR_REFLECTION,
|
||||
)
|
||||
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
|
||||
mutant_bodyparts = list("wings" = "None")
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN
|
||||
exotic_bloodtype = "U"
|
||||
blood_deficiency_drain_rate = BLOOD_DEFICIENCY_MODIFIER // vampires already passively lose blood, so this just makes them lose it slightly more quickly when they have blood deficiency.
|
||||
|
||||
@@ -225,7 +225,8 @@
|
||||
organ_evacced.Remove(target, special = TRUE)
|
||||
organ_evacced.forceMove(get_turf(target))
|
||||
|
||||
organ.Insert(target)
|
||||
if (!organ.Insert(target))
|
||||
organ.forceMove(drop_location())
|
||||
organ = null
|
||||
|
||||
///Patrient Transport - Generates hardlight bags you can put people in.
|
||||
|
||||
@@ -991,7 +991,7 @@
|
||||
aux_zone_markings = LAZYCOPY(owner_species.body_markings[aux_zone])
|
||||
markings_alpha = owner_species.markings_alpha
|
||||
// SKYRAT EDIT END
|
||||
recolor_bodypart_overlays()
|
||||
recolor_external_organs()
|
||||
return TRUE
|
||||
|
||||
//to update the bodypart's icon when not attached to a mob
|
||||
@@ -1369,7 +1369,7 @@
|
||||
QDEL_NULL(current_gauze)
|
||||
|
||||
///Loops through all of the bodypart's external organs and update's their color.
|
||||
/obj/item/bodypart/proc/recolor_bodypart_overlays()
|
||||
/obj/item/bodypart/proc/recolor_external_organs()
|
||||
for(var/datum/bodypart_overlay/mutant/overlay in bodypart_overlays)
|
||||
overlay.inherit_color(src, force = TRUE)
|
||||
|
||||
|
||||
@@ -406,12 +406,12 @@
|
||||
qdel(phantom_loss)
|
||||
|
||||
//Copied from /datum/species/proc/on_species_gain()
|
||||
for(var/obj/item/organ/organ_path as anything in dna.species.mutant_organs)
|
||||
for(var/obj/item/organ/external/organ_path as anything in dna.species.external_organs)
|
||||
//Load a persons preferences from DNA
|
||||
var/zone = initial(organ_path.zone)
|
||||
if(zone != limb_zone)
|
||||
continue
|
||||
var/obj/item/organ/new_organ = SSwardrobe.provide_type(organ_path)
|
||||
var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path)
|
||||
new_organ.Insert(src)
|
||||
|
||||
update_body_parts()
|
||||
|
||||
@@ -182,8 +182,8 @@
|
||||
/mob/living/carbon/proc/synchronize_bodytypes()
|
||||
var/all_limb_flags = NONE
|
||||
for(var/obj/item/bodypart/limb as anything in bodyparts)
|
||||
for(var/obj/item/organ/organ in limb)
|
||||
all_limb_flags |= organ.external_bodytypes
|
||||
for(var/obj/item/organ/external/ext_organ in limb)
|
||||
all_limb_flags |= ext_organ.external_bodytypes
|
||||
all_limb_flags |= limb.bodytype
|
||||
|
||||
bodytype = all_limb_flags
|
||||
@@ -192,8 +192,8 @@
|
||||
/mob/living/carbon/proc/synchronize_bodyshapes()
|
||||
var/all_limb_flags = NONE
|
||||
for(var/obj/item/bodypart/limb as anything in bodyparts)
|
||||
for(var/obj/item/organ/organ in limb)
|
||||
all_limb_flags |= organ.external_bodyshapes
|
||||
for(var/obj/item/organ/external/ext_organ in limb)
|
||||
all_limb_flags |= ext_organ.external_bodyshapes
|
||||
all_limb_flags |= limb.bodyshape
|
||||
|
||||
bodyshape = all_limb_flags
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
tool = tool.contents[1]
|
||||
target_organ = tool
|
||||
user.temporarilyRemoveItemFromInventory(target_organ, TRUE)
|
||||
target_organ.Insert(target)
|
||||
if(target_organ.Insert(target))
|
||||
if(apparatus)
|
||||
apparatus.icon_state = initial(apparatus.icon_state)
|
||||
apparatus.desc = initial(apparatus.desc)
|
||||
@@ -253,6 +253,8 @@
|
||||
)
|
||||
display_pain(target, "Your [target.parse_zone_with_bodypart(target_zone)] throbs with pain as your new [tool.name] comes to life!")
|
||||
target_organ.on_surgical_insertion(user, target, target_zone, tool)
|
||||
else
|
||||
target_organ.forceMove(target.loc)
|
||||
|
||||
else if(current_type == "extract")
|
||||
if(target_organ && target_organ.owner == target)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/obj/item/organ
|
||||
name = "organ"
|
||||
icon = 'icons/obj/medical/organs/organs.dmi'
|
||||
@@ -78,9 +79,6 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
|
||||
volume = reagent_vol,\
|
||||
after_eat = CALLBACK(src, PROC_REF(OnEatFrom)))
|
||||
|
||||
if(bodypart_overlay)
|
||||
setup_bodypart_overlay()
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
if(bodypart_owner && !owner && !QDELETED(bodypart_owner))
|
||||
bodypart_remove(bodypart_owner)
|
||||
@@ -142,7 +140,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
|
||||
return
|
||||
|
||||
/obj/item/organ/proc/on_life(seconds_per_tick, times_fired)
|
||||
return
|
||||
CRASH("Oh god oh fuck something is calling parent organ life")
|
||||
|
||||
/obj/item/organ/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -344,16 +342,3 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
|
||||
/// Tries to replace the existing organ on the passed mob with this one, with special handling for replacing a brain without ghosting target
|
||||
/obj/item/organ/proc/replace_into(mob/living/carbon/new_owner)
|
||||
return Insert(new_owner, special = TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
|
||||
|
||||
/// Get all possible organ slots by checking every organ, and then store it and give it whenever needed
|
||||
/proc/get_all_slots()
|
||||
var/static/list/all_organ_slots = list()
|
||||
|
||||
if(!all_organ_slots.len)
|
||||
for(var/obj/item/organ/an_organ as anything in subtypesof(/obj/item/organ))
|
||||
if(!initial(an_organ.slot))
|
||||
continue
|
||||
all_organ_slots |= initial(an_organ.slot)
|
||||
|
||||
return all_organ_slots
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
System for drawing organs with overlays. These overlays are drawn directly on the bodypart, attached to a person or not
|
||||
Works in tandem with the /datum/sprite_accessory datum to generate sprites
|
||||
Unlike normal organs, we're actually inside a persons limbs at all times
|
||||
*/
|
||||
/obj/item/organ
|
||||
///The overlay datum that actually draws stuff on the limb
|
||||
var/datum/bodypart_overlay/mutant/bodypart_overlay
|
||||
|
||||
/// The savefile_key of the preference this relates to. Used for the preferences UI.
|
||||
var/preference
|
||||
///With what DNA block do we mutate in mutate_feature() ? For genetics
|
||||
var/dna_block
|
||||
|
||||
///Set to EXTERNAL_BEHIND, EXTERNAL_FRONT or EXTERNAL_ADJACENT if you want to draw one of those layers as the object sprite. FALSE to use your own
|
||||
///This will not work if it doesn't have a limb to generate its icon with
|
||||
var/use_mob_sprite_as_obj_sprite = FALSE
|
||||
|
||||
///Does this organ have any bodytypes to pass to its bodypart_owner?
|
||||
var/external_bodytypes = NONE
|
||||
///Does this organ have any bodyshapes to pass to its bodypart_owner?
|
||||
var/external_bodyshapes = NONE
|
||||
|
||||
///Which flags does a 'modification tool' need to have to restyle us, if it all possible (located in code/_DEFINES/mobs)
|
||||
var/restyle_flags = NONE
|
||||
|
||||
///If not null, overrides the appearance with this sprite accessory datum
|
||||
var/sprite_accessory_override
|
||||
|
||||
/**accessory_type 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
|
||||
*/
|
||||
/obj/item/organ/proc/setup_bodypart_overlay(accessory_type)
|
||||
bodypart_overlay = new bodypart_overlay(src)
|
||||
|
||||
accessory_type = accessory_type ? accessory_type : sprite_accessory_override
|
||||
var/update_overlays = TRUE
|
||||
if(accessory_type)
|
||||
bodypart_overlay.set_appearance(accessory_type)
|
||||
bodypart_overlay.imprint_on_next_insertion = FALSE
|
||||
else if(loc) //we've been spawned into the world, and not in nullspace to be added to a limb (yes its fucking scuffed)
|
||||
bodypart_overlay.randomize_appearance()
|
||||
else
|
||||
update_overlays = FALSE
|
||||
|
||||
if(use_mob_sprite_as_obj_sprite && update_overlays)
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
if(restyle_flags)
|
||||
RegisterSignal(src, COMSIG_ATOM_RESTYLE, PROC_REF(on_attempt_feature_restyle))
|
||||
|
||||
/// Some sanity checks, but mostly to check if the person has their preference/dna set to load
|
||||
/proc/should_visual_organ_apply_to(obj/item/organ/organpath, mob/living/carbon/target)
|
||||
if(!initial(organpath.bodypart_overlay))
|
||||
return TRUE
|
||||
|
||||
if(isnull(organpath) || isnull(target))
|
||||
stack_trace("passed a null path or mob to 'should_visual_organ_apply_to'")
|
||||
return FALSE
|
||||
|
||||
var/datum/bodypart_overlay/mutant/bodypart_overlay = initial(organpath.bodypart_overlay)
|
||||
var/feature_key = !isnull(bodypart_overlay) && initial(bodypart_overlay.feature_key)
|
||||
if(isnull(feature_key))
|
||||
return TRUE
|
||||
|
||||
if(target.dna.features[feature_key] != SPRITE_ACCESSORY_NONE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
///Update our features after something changed our appearance
|
||||
/obj/item/organ/proc/mutate_feature(features, mob/living/carbon/human/human)
|
||||
if(!dna_block)
|
||||
return
|
||||
|
||||
var/list/feature_list = bodypart_overlay.get_global_feature_list()
|
||||
|
||||
bodypart_overlay.set_appearance_from_name(feature_list[deconstruct_block(get_uni_feature_block(features, dna_block), feature_list.len)])
|
||||
|
||||
///If you need to change an external_organ for simple one-offs, use this. Pass the accessory type : /datum/accessory/something
|
||||
/obj/item/organ/proc/simple_change_sprite(accessory_type)
|
||||
var/datum/sprite_accessory/typed_accessory = accessory_type //we only take types for maintainability
|
||||
|
||||
bodypart_overlay.set_appearance(typed_accessory)
|
||||
|
||||
if(owner) //are we in a person?
|
||||
owner.update_body_parts()
|
||||
else if(bodypart_owner) //are we in a limb?
|
||||
bodypart_owner.update_icon_dropped()
|
||||
//else if(use_mob_sprite_as_obj_sprite) //are we out in the world, unprotected by flesh?
|
||||
|
||||
/obj/item/organ/update_overlays()
|
||||
. = ..()
|
||||
|
||||
if(!use_mob_sprite_as_obj_sprite)
|
||||
return
|
||||
|
||||
//Build the mob sprite and use it as our overlay
|
||||
for(var/external_layer in bodypart_overlay.all_layers)
|
||||
if(bodypart_overlay.layers & external_layer)
|
||||
. += bodypart_overlay.get_overlay(external_layer, bodypart_owner)
|
||||
|
||||
///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
|
||||
|
||||
preference = "feature_lizard_horns"
|
||||
dna_block = DNA_HORNS_BLOCK
|
||||
restyle_flags = EXTERNAL_RESTYLE_ENAMEL
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/horns
|
||||
|
||||
/datum/bodypart_overlay/mutant/horns
|
||||
layers = EXTERNAL_ADJACENT
|
||||
feature_key = "horns"
|
||||
|
||||
/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(mob/living/carbon/human/human)
|
||||
if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/bodypart_overlay/mutant/horns/get_global_feature_list()
|
||||
return SSaccessories.horns_list
|
||||
|
||||
///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
|
||||
|
||||
preference = "feature_lizard_frills"
|
||||
dna_block = DNA_FRILLS_BLOCK
|
||||
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/frills
|
||||
|
||||
/datum/bodypart_overlay/mutant/frills
|
||||
layers = EXTERNAL_ADJACENT
|
||||
feature_key = "frills"
|
||||
|
||||
/datum/bodypart_overlay/mutant/frills/can_draw_on_bodypart(mob/living/carbon/human/human)
|
||||
if(!(human.head?.flags_inv & HIDEEARS))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/bodypart_overlay/mutant/frills/get_global_feature_list()
|
||||
return SSaccessories.frills_list
|
||||
|
||||
///Guess what part of the lizard this is?
|
||||
/obj/item/organ/external/snout
|
||||
name = "lizard snout"
|
||||
desc = "Take a closer look at that snout!"
|
||||
icon_state = "snout"
|
||||
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_EXTERNAL_SNOUT
|
||||
|
||||
preference = "feature_lizard_snout"
|
||||
external_bodyshapes = BODYSHAPE_SNOUTED
|
||||
|
||||
dna_block = DNA_SNOUT_BLOCK
|
||||
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/snout
|
||||
|
||||
/datum/bodypart_overlay/mutant/snout
|
||||
layers = EXTERNAL_ADJACENT
|
||||
feature_key = "snout"
|
||||
|
||||
/datum/bodypart_overlay/mutant/snout/can_draw_on_bodypart(mob/living/carbon/human/human)
|
||||
if(!(human.wear_mask?.flags_inv & HIDESNOUT) && !(human.head?.flags_inv & HIDESNOUT))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/bodypart_overlay/mutant/snout/get_global_feature_list()
|
||||
return SSaccessories.snouts_list
|
||||
|
||||
///A moth's antennae
|
||||
/obj/item/organ/external/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
|
||||
|
||||
preference = "feature_moth_antennae"
|
||||
dna_block = DNA_MOTH_ANTENNAE_BLOCK
|
||||
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/antennae
|
||||
|
||||
///Are we burned?
|
||||
var/burnt = FALSE
|
||||
///Store our old datum here for if our antennae are healed
|
||||
var/original_sprite_datum
|
||||
|
||||
/obj/item/organ/external/antennae/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
|
||||
RegisterSignal(receiver, COMSIG_HUMAN_BURNING, PROC_REF(try_burn_antennae))
|
||||
RegisterSignal(receiver, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(heal_antennae))
|
||||
|
||||
/obj/item/organ/external/antennae/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
|
||||
UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL))
|
||||
|
||||
///check if our antennae can burn off ;_;
|
||||
/obj/item/organ/external/antennae/proc/try_burn_antennae(mob/living/carbon/human/human)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!burnt && human.bodytemperature >= 800 && human.fire_stacks > 0) //do not go into the extremely hot light. you will not survive
|
||||
to_chat(human, span_danger("Your precious antennae burn to a crisp!"))
|
||||
|
||||
burn_antennae()
|
||||
human.update_body_parts()
|
||||
|
||||
///Burn our antennae off ;_;
|
||||
/obj/item/organ/external/antennae/proc/burn_antennae()
|
||||
var/datum/bodypart_overlay/mutant/antennae/antennae = bodypart_overlay
|
||||
antennae.burnt = TRUE
|
||||
burnt = TRUE
|
||||
|
||||
///heal our antennae back up!!
|
||||
/obj/item/organ/external/antennae/proc/heal_antennae(datum/source, heal_flags)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!burnt)
|
||||
return
|
||||
|
||||
if(heal_flags & (HEAL_LIMBS|HEAL_ORGANS))
|
||||
var/datum/bodypart_overlay/mutant/antennae/antennae = bodypart_overlay
|
||||
antennae.burnt = FALSE
|
||||
burnt = FALSE
|
||||
|
||||
///Moth antennae datum, with full burning functionality
|
||||
/datum/bodypart_overlay/mutant/antennae
|
||||
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
|
||||
feature_key = "moth_antennae"
|
||||
///Accessory datum of the burn sprite
|
||||
var/datum/sprite_accessory/burn_datum = /datum/sprite_accessory/moth_antennae/burnt_off
|
||||
///Are we burned? If so we draw differently
|
||||
var/burnt = FALSE
|
||||
|
||||
/datum/bodypart_overlay/mutant/antennae/New()
|
||||
. = ..()
|
||||
|
||||
burn_datum = fetch_sprite_datum(burn_datum) //turn the path into the singleton instance
|
||||
|
||||
/datum/bodypart_overlay/mutant/antennae/get_global_feature_list()
|
||||
return SSaccessories.moth_antennae_list
|
||||
|
||||
/datum/bodypart_overlay/mutant/antennae/get_base_icon_state()
|
||||
return burnt ? burn_datum.icon_state : sprite_datum.icon_state
|
||||
|
||||
///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
|
||||
|
||||
preference = "feature_pod_hair"
|
||||
use_mob_sprite_as_obj_sprite = TRUE
|
||||
|
||||
dna_block = DNA_POD_HAIR_BLOCK
|
||||
restyle_flags = EXTERNAL_RESTYLE_PLANT
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/pod_hair
|
||||
|
||||
///Podperson bodypart overlay, with special coloring functionality to render the flowers in the inverse color
|
||||
/datum/bodypart_overlay/mutant/pod_hair
|
||||
layers = EXTERNAL_FRONT|EXTERNAL_ADJACENT
|
||||
feature_key = "pod_hair"
|
||||
|
||||
///This layer will be colored differently than the rest of the organ. So we can get differently colored flowers or something
|
||||
var/color_swapped_layer = EXTERNAL_FRONT
|
||||
///The individual rgb colors are subtracted from this to get the color shifted layer
|
||||
var/color_inverse_base = 255
|
||||
|
||||
/datum/bodypart_overlay/mutant/pod_hair/get_global_feature_list()
|
||||
return SSaccessories.pod_hair_list
|
||||
|
||||
/datum/bodypart_overlay/mutant/pod_hair/color_image(image/overlay, draw_layer, obj/item/bodypart/limb)
|
||||
if(draw_layer != bitflag_to_layer(color_swapped_layer))
|
||||
return ..()
|
||||
|
||||
if(draw_color) // can someone explain to me why draw_color is allowed to EVER BE AN EMPTY STRING
|
||||
var/list/rgb_list = rgb2num(draw_color)
|
||||
overlay.color = rgb(color_inverse_base - rgb_list[1], color_inverse_base - rgb_list[2], color_inverse_base - rgb_list[3]) //inversa da color
|
||||
else
|
||||
overlay.color = null
|
||||
|
||||
/datum/bodypart_overlay/mutant/pod_hair/can_draw_on_bodypart(mob/living/carbon/human/human)
|
||||
if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
@@ -1,7 +1,7 @@
|
||||
//Contains a bunch of procs for different types, but in the end it just lets you restyle the bodypart overlay so thats why its here
|
||||
//Contains a bunch of procs for different types, but in the end it just lets you restyle external_organs so thats why its here
|
||||
|
||||
///Helper proc to fetch a list of styles a player might want to restyle their features into during the round : returns list("Cabbage" = /datum/sprite_accessory/cabbage)
|
||||
/obj/item/organ/proc/get_valid_restyles()
|
||||
/obj/item/organ/external/proc/get_valid_restyles()
|
||||
var/list/valid_restyles
|
||||
|
||||
valid_restyles = list()
|
||||
@@ -31,18 +31,18 @@
|
||||
///Asks the external organs inside the limb if they can restyle
|
||||
/obj/item/bodypart/proc/attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
var/list/valid_features = list()
|
||||
for(var/obj/item/organ/feature in contents)
|
||||
for(var/obj/item/organ/external/feature in contents)
|
||||
if(feature.restyle_flags & restyle_type)
|
||||
valid_features.Add(feature)
|
||||
|
||||
var/obj/item/organ/target_organ
|
||||
var/obj/item/organ/external/target_organ
|
||||
switch(LAZYLEN(valid_features))
|
||||
if(1)
|
||||
target_organ = valid_features[1]
|
||||
if(2 to INFINITY)
|
||||
var/choose_options = list()
|
||||
var/name_to_organ = list() //literally so I dont have to loop again after someones made their choice
|
||||
for(var/obj/item/organ/organ_choice as anything in valid_features)
|
||||
for(var/obj/item/organ/external/organ_choice as anything in valid_features)
|
||||
choose_options[organ_choice.name] = image(organ_choice)
|
||||
name_to_organ[organ_choice.name] = organ_choice
|
||||
var/picked_option = show_radial_menu(trimmer, original_target, choose_options, radius = 38, require_near = TRUE)
|
||||
@@ -57,7 +57,7 @@
|
||||
target_organ.attempt_feature_restyle(source, trimmer, original_target, body_zone, restyle_type, style_speed)
|
||||
|
||||
///Invoke async so we dont break signals
|
||||
/obj/item/organ/proc/on_attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
/obj/item/organ/external/proc/on_attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(restyle_flags & restyle_type)
|
||||
@@ -66,7 +66,7 @@
|
||||
to_chat(trimmer, span_warning("This tool is incompatible with the [src.name]!"))
|
||||
|
||||
///Restyles the external organ from a list of valid options
|
||||
/obj/item/organ/proc/attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
/obj/item/organ/external/proc/attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
var/list/restyles = get_valid_restyles()
|
||||
var/new_style = tgui_input_list(trimmer, "Select a new style", "Grooming", restyles)
|
||||
|
||||
@@ -80,4 +80,5 @@
|
||||
span_notice("You successfully change [original_target == trimmer ? "your" : original_target.name + "'s"] [name].")
|
||||
)
|
||||
|
||||
|
||||
simple_change_sprite(restyles[new_style]) //turn name to type and pass it on
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/spines
|
||||
|
||||
/obj/item/organ/external/spines/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/spines/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
// If we have a tail, attempt to add a tail spines overlay
|
||||
var/obj/item/organ/external/tail/our_tail = receiver.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
|
||||
our_tail?.try_insert_tail_spines(our_tail.bodypart_owner)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/spines/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/external/spines/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
// If we have a tail, remove any tail spines overlay
|
||||
var/obj/item/organ/external/tail/our_tail = organ_owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
|
||||
our_tail?.remove_tail_spines(our_tail.bodypart_owner)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
///The overlay for tail spines, if any
|
||||
var/datum/bodypart_overlay/mutant/tail_spines/tail_spines_overlay
|
||||
|
||||
/obj/item/organ/external/tail/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/tail/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
receiver.clear_mood_event("tail_lost")
|
||||
@@ -34,7 +34,7 @@
|
||||
// If it's not your tail AND of different species, we are horrified
|
||||
if(IS_WEAKREF_OF(receiver, original_owner))
|
||||
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_right)
|
||||
else if(type in receiver.dna.species.mutant_organs)
|
||||
else if(type in receiver.dna.species.external_organs)
|
||||
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_species)
|
||||
else
|
||||
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_wrong)
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
organ_owner.clear_mood_event("tail_regained")
|
||||
|
||||
if(type in organ_owner.dna.species.mutant_organs)
|
||||
if(type in organ_owner.dna.species.external_organs)
|
||||
organ_owner.add_mood_event("tail_lost", /datum/mood_event/tail_lost)
|
||||
organ_owner.add_mood_event("tail_balance_lost", /datum/mood_event/tail_balance_lost)
|
||||
|
||||
|
||||
@@ -35,14 +35,15 @@
|
||||
QDEL_NULL(fly)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/wings/functional/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/wings/functional/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
if(QDELETED(fly))
|
||||
fly = new
|
||||
fly.Grant(receiver)
|
||||
|
||||
/obj/item/organ/external/wings/functional/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/external/wings/functional/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
fly?.Remove(organ_owner)
|
||||
if(wings_open)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
name = "appendix"
|
||||
icon_state = "appendix"
|
||||
base_icon_state = "appendix"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_APPENDIX
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/toxin/bad_food = 5)
|
||||
|
||||
@@ -27,13 +27,14 @@
|
||||
eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT)
|
||||
balloon_alert(eye_owner, "hud enabled")
|
||||
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/mob_insert(mob/living/carbon/eye_owner, special = FALSE, movement_flags)
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/Insert(mob/living/carbon/eye_owner, special = FALSE, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
eye_owner.add_traits(HUD_traits, ORGAN_TRAIT)
|
||||
toggled_on = TRUE
|
||||
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/mob_remove(mob/living/carbon/eye_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/Remove(mob/living/carbon/eye_owner, special, movement_flags)
|
||||
. = ..()
|
||||
eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT)
|
||||
toggled_on = FALSE
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/obj/item/organ/internal/cyberimp
|
||||
name = "cybernetic implant"
|
||||
desc = "A state-of-the-art implant that improves a baseline's functionality."
|
||||
visual = FALSE
|
||||
organ_flags = ORGAN_ROBOTIC
|
||||
failing_desc = "seems to be broken."
|
||||
var/implant_color = COLOR_WHITE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
desc = "There are three parts to the ear. Inner, middle and outer. Only one of these parts should be normally visible."
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_EARS
|
||||
visual = FALSE
|
||||
gender = PLURAL
|
||||
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
@@ -135,34 +136,32 @@
|
||||
icon_state = "kitty"
|
||||
visual = TRUE
|
||||
damage_multiplier = 2
|
||||
// Keeps track of which cat ears sprite is associated with this.
|
||||
var/variant = "Cat"
|
||||
|
||||
preference = "feature_human_ears"
|
||||
/obj/item/organ/internal/ears/cat/Initialize(mapload, variant_pref)
|
||||
. = ..()
|
||||
if(variant_pref)
|
||||
variant = variant_pref
|
||||
|
||||
dna_block = DNA_EARS_BLOCK
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION
|
||||
/*
|
||||
/obj/item/organ/internal/ears/cat/on_mob_insert(mob/living/carbon/human/ear_owner)
|
||||
. = ..()
|
||||
if(istype(ear_owner) && ear_owner.dna)
|
||||
color = ear_owner.hair_color
|
||||
ear_owner.dna.features["ears"] = ear_owner.dna.species.mutant_bodyparts["ears"] = variant
|
||||
ear_owner.dna.update_uf_block(DNA_EARS_BLOCK)
|
||||
ear_owner.update_body()
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears
|
||||
|
||||
/// Bodypart overlay for the horrible cat ears
|
||||
/datum/bodypart_overlay/mutant/cat_ears
|
||||
layers = EXTERNAL_FRONT | EXTERNAL_ADJACENT
|
||||
color_source = ORGAN_COLOR_HAIR
|
||||
feature_key = "ears"
|
||||
|
||||
/// We dont color the inner part, which is the front layer
|
||||
var/colorless_layer = EXTERNAL_FRONT
|
||||
|
||||
/datum/bodypart_overlay/mutant/cat_ears/get_global_feature_list()
|
||||
return SSaccessories.ears_list
|
||||
|
||||
/datum/bodypart_overlay/mutant/cat_ears/can_draw_on_bodypart(mob/living/carbon/human/human)
|
||||
if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/bodypart_overlay/mutant/cat_ears/color_image(image/overlay, draw_layer, obj/item/bodypart/limb)
|
||||
if(draw_layer != bitflag_to_layer(colorless_layer))
|
||||
return ..()
|
||||
return overlay
|
||||
/obj/item/organ/internal/ears/cat/on_mob_remove(mob/living/carbon/human/ear_owner)
|
||||
. = ..()
|
||||
if(istype(ear_owner) && ear_owner.dna)
|
||||
color = ear_owner.hair_color
|
||||
ear_owner.dna.species.mutant_bodyparts -= "ears"
|
||||
ear_owner.update_body()
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
/obj/item/organ/internal/ears/penguin
|
||||
name = "penguin ears"
|
||||
|
||||
@@ -53,18 +53,21 @@
|
||||
var/native_fov = FOV_180_DEGREES //SKYRAT EDIT CHANGE - Original FOV_90_DEGREES
|
||||
|
||||
|
||||
/obj/item/organ/internal/eyes/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/internal/eyes/Insert(mob/living/carbon/eye_recipient, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
// If we don't do this before everything else, heterochromia will be reset leading to eye_color_right no longer being accurate
|
||||
if(ishuman(receiver))
|
||||
var/mob/living/carbon/human/human_recipient = receiver
|
||||
if(ishuman(eye_recipient))
|
||||
var/mob/living/carbon/human/human_recipient = eye_recipient
|
||||
old_eye_color_left = human_recipient.eye_color_left
|
||||
old_eye_color_right = human_recipient.eye_color_right
|
||||
|
||||
. = ..()
|
||||
|
||||
receiver.cure_blind(NO_EYES)
|
||||
if(!.)
|
||||
return
|
||||
|
||||
eye_recipient.cure_blind(NO_EYES)
|
||||
apply_damaged_eye_effects()
|
||||
refresh(receiver, call_update = TRUE)
|
||||
refresh(eye_recipient, call_update = TRUE)
|
||||
|
||||
/// Refreshes the visuals of the eyes
|
||||
/// If call_update is TRUE, we also will call update_body
|
||||
@@ -97,32 +100,31 @@
|
||||
if(call_update)
|
||||
affected_human.update_body()
|
||||
|
||||
/obj/item/organ/internal/eyes/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/eyes/Remove(mob/living/carbon/eye_owner, special, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(ishuman(organ_owner))
|
||||
var/mob/living/carbon/human/human_owner = organ_owner
|
||||
if(ishuman(eye_owner))
|
||||
var/mob/living/carbon/human/human_owner = eye_owner
|
||||
if(initial(eye_color_left))
|
||||
human_owner.eye_color_left = old_eye_color_left
|
||||
if(initial(eye_color_right))
|
||||
human_owner.eye_color_right = old_eye_color_right
|
||||
if(native_fov)
|
||||
organ_owner.remove_fov_trait(type)
|
||||
eye_owner.remove_fov_trait(type)
|
||||
if(!special)
|
||||
human_owner.update_body()
|
||||
|
||||
// Cure blindness from eye damage
|
||||
organ_owner.cure_blind(EYE_DAMAGE)
|
||||
organ_owner.cure_nearsighted(EYE_DAMAGE)
|
||||
eye_owner.cure_blind(EYE_DAMAGE)
|
||||
eye_owner.cure_nearsighted(EYE_DAMAGE)
|
||||
// Eye blind and temp blind go to, even if this is a bit of cheesy way to clear blindness
|
||||
organ_owner.remove_status_effect(/datum/status_effect/eye_blur)
|
||||
organ_owner.remove_status_effect(/datum/status_effect/temporary_blindness)
|
||||
eye_owner.remove_status_effect(/datum/status_effect/eye_blur)
|
||||
eye_owner.remove_status_effect(/datum/status_effect/temporary_blindness)
|
||||
// Then become blind anyways (if not special)
|
||||
if(!special)
|
||||
organ_owner.become_blind(NO_EYES)
|
||||
eye_owner.become_blind(NO_EYES)
|
||||
|
||||
organ_owner.update_tint()
|
||||
organ_owner.update_sight()
|
||||
eye_owner.update_tint()
|
||||
eye_owner.update_sight()
|
||||
is_emissive = FALSE // SKYRAT EDIT ADDITION
|
||||
|
||||
#define OFFSET_X 1
|
||||
@@ -449,7 +451,7 @@
|
||||
deactivate(close_ui = TRUE)
|
||||
|
||||
/// Set the initial color of the eyes on insert to be the mob's previous eye color.
|
||||
/obj/item/organ/internal/eyes/robotic/glow/mob_insert(mob/living/carbon/eye_recipient, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
/obj/item/organ/internal/eyes/robotic/glow/Insert(mob/living/carbon/eye_recipient, special = FALSE, movement_flags = DELETE_IF_REPLACED)
|
||||
. = ..()
|
||||
left_eye_color_string = old_eye_color_left
|
||||
right_eye_color_string = old_eye_color_right
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "I feel bad for the heartless bastard who lost this."
|
||||
icon_state = "heart-on"
|
||||
base_icon_state = "heart"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_HEART
|
||||
item_flags = NO_BLOOD_ON_ITEM
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
add_atom_colour(ethereal_color, FIXED_COLOUR_PRIORITY)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/organ/internal/heart/ethereal/mob_insert(mob/living/carbon/heart_owner, special = FALSE, movement_flags)
|
||||
/obj/item/organ/internal/heart/ethereal/Insert(mob/living/carbon/heart_owner, special = FALSE, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
RegisterSignal(heart_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change))
|
||||
RegisterSignal(heart_owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(on_owner_fully_heal))
|
||||
RegisterSignal(heart_owner, COMSIG_QDELETING, PROC_REF(owner_deleted))
|
||||
|
||||
/obj/item/organ/internal/heart/ethereal/mob_remove(mob/living/carbon/heart_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/heart/ethereal/Remove(mob/living/carbon/heart_owner, special, movement_flags)
|
||||
UnregisterSignal(heart_owner, list(COMSIG_MOB_STATCHANGE, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_QDELETING))
|
||||
REMOVE_TRAIT(heart_owner, TRAIT_CORPSELOCKED, SPECIES_TRAIT)
|
||||
stop_crystalization_process(heart_owner)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
name = "liver"
|
||||
desc = "Pairing suggestion: chianti and fava beans."
|
||||
icon_state = "liver"
|
||||
visual = FALSE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_LIVER
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/organ/internal/lungs
|
||||
name = "lungs"
|
||||
icon_state = "lungs"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_LUNGS
|
||||
gender = PLURAL
|
||||
@@ -153,16 +154,17 @@
|
||||
add_gas_reaction(/datum/gas/zauker, while_present = PROC_REF(too_much_zauker))
|
||||
|
||||
///Simply exists so that you don't keep any alerts from your previous lack of lungs.
|
||||
/obj/item/organ/internal/lungs/mob_insert(mob/living/carbon/receiver, special = FALSE, movement_flags)
|
||||
/obj/item/organ/internal/lungs/Insert(mob/living/carbon/receiver, special = FALSE, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return .
|
||||
receiver.clear_alert(ALERT_NOT_ENOUGH_OXYGEN)
|
||||
receiver.clear_alert(ALERT_NOT_ENOUGH_CO2)
|
||||
receiver.clear_alert(ALERT_NOT_ENOUGH_NITRO)
|
||||
receiver.clear_alert(ALERT_NOT_ENOUGH_PLASMA)
|
||||
receiver.clear_alert(ALERT_NOT_ENOUGH_N2O)
|
||||
|
||||
/obj/item/organ/internal/lungs/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/lungs/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
// This is very "manual" I realize, but it's useful to ensure cleanup for gases we're removing happens
|
||||
// Avoids stuck alerts and such
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
name = "stomach"
|
||||
desc = "Onaka ga suite imasu."
|
||||
icon_state = "stomach"
|
||||
visual = FALSE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
zone = BODY_ZONE_CHEST
|
||||
slot = ORGAN_SLOT_STOMACH
|
||||
@@ -246,11 +247,11 @@
|
||||
disgusted.throw_alert(ALERT_DISGUST, /atom/movable/screen/alert/disgusted)
|
||||
disgusted.add_mood_event("disgust", /datum/mood_event/disgusted)
|
||||
|
||||
/obj/item/organ/internal/stomach/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/internal/stomach/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
receiver.hud_used?.hunger?.update_appearance()
|
||||
|
||||
/obj/item/organ/internal/stomach/mob_remove(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/stomach/Remove(mob/living/carbon/stomach_owner, special, movement_flags)
|
||||
if(ishuman(stomach_owner))
|
||||
var/mob/living/carbon/human/human_owner = owner
|
||||
human_owner.clear_alert(ALERT_DISGUST)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "tongue"
|
||||
desc = "A fleshy muscle mostly used for lying."
|
||||
icon_state = "tongue"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_PRECISE_MOUTH
|
||||
slot = ORGAN_SLOT_TONGUE
|
||||
attack_verb_continuous = list("licks", "slobbers", "slaps", "frenches", "tongues")
|
||||
@@ -123,30 +124,30 @@
|
||||
food_taste_reaction = FOOD_LIKED
|
||||
return food_taste_reaction
|
||||
|
||||
/obj/item/organ/internal/tongue/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/internal/tongue/Insert(mob/living/carbon/tongue_owner, special = FALSE, movement_flags)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
if(modifies_speech)
|
||||
RegisterSignal(receiver, COMSIG_MOB_SAY, PROC_REF(handle_speech))
|
||||
receiver.voice_filter = voice_filter
|
||||
RegisterSignal(tongue_owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
|
||||
tongue_owner.voice_filter = voice_filter
|
||||
/* This could be slightly simpler, by making the removal of the
|
||||
* NO_TONGUE_TRAIT conditional on the tongue's `sense_of_taste`, but
|
||||
* then you can distinguish between ageusia from no tongue, and
|
||||
* ageusia from having a non-tasting tongue.
|
||||
*/
|
||||
REMOVE_TRAIT(receiver, TRAIT_AGEUSIA, NO_TONGUE_TRAIT)
|
||||
REMOVE_TRAIT(tongue_owner, TRAIT_AGEUSIA, NO_TONGUE_TRAIT)
|
||||
apply_tongue_effects()
|
||||
|
||||
/obj/item/organ/internal/tongue/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/internal/tongue/Remove(mob/living/carbon/tongue_owner, special, movement_flags)
|
||||
. = ..()
|
||||
|
||||
temp_say_mod = ""
|
||||
UnregisterSignal(organ_owner, COMSIG_MOB_SAY)
|
||||
REMOVE_TRAIT(organ_owner, TRAIT_SPEAKS_CLEARLY, SPEAKING_FROM_TONGUE)
|
||||
REMOVE_TRAIT(organ_owner, TRAIT_AGEUSIA, ORGAN_TRAIT)
|
||||
UnregisterSignal(tongue_owner, COMSIG_MOB_SAY)
|
||||
REMOVE_TRAIT(tongue_owner, TRAIT_SPEAKS_CLEARLY, SPEAKING_FROM_TONGUE)
|
||||
REMOVE_TRAIT(tongue_owner, TRAIT_AGEUSIA, ORGAN_TRAIT)
|
||||
// Carbons by default start with NO_TONGUE_TRAIT caused TRAIT_AGEUSIA
|
||||
ADD_TRAIT(organ_owner, TRAIT_AGEUSIA, NO_TONGUE_TRAIT)
|
||||
organ_owner.voice_filter = initial(organ_owner.voice_filter)
|
||||
ADD_TRAIT(tongue_owner, TRAIT_AGEUSIA, NO_TONGUE_TRAIT)
|
||||
tongue_owner.voice_filter = initial(tongue_owner.voice_filter)
|
||||
|
||||
/obj/item/organ/internal/tongue/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag)
|
||||
. = ..()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/organ/internal/vocal_cords //organs that are activated through speech with the :x/MODE_KEY_VOCALCORDS channel
|
||||
name = "vocal cords"
|
||||
icon_state = "appendix"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_PRECISE_MOUTH
|
||||
slot = ORGAN_SLOT_VOICE
|
||||
gender = PLURAL
|
||||
@@ -86,6 +87,7 @@
|
||||
next_command = world.time + (cooldown * cooldown_mod)
|
||||
|
||||
/obj/item/organ/internal/adamantine_resonator
|
||||
visual = FALSE
|
||||
name = "adamantine resonator"
|
||||
desc = "Fragments of adamantine exist in all golems, stemming from their origins as purely magical constructs. These are used to \"hear\" messages from their leaders."
|
||||
zone = BODY_ZONE_HEAD
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
mob_insert(receiver, special, movement_flags)
|
||||
bodypart_insert(limb_owner = receiver, movement_flags = movement_flags)
|
||||
|
||||
if(!special)
|
||||
receiver.update_body_parts()
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Remove the organ from the select mob.
|
||||
@@ -33,9 +32,6 @@
|
||||
mob_remove(organ_owner, special, movement_flags)
|
||||
bodypart_remove(limb_owner = organ_owner, movement_flags = movement_flags)
|
||||
|
||||
if(!special)
|
||||
organ_owner.update_body_parts()
|
||||
|
||||
/*
|
||||
* Insert the organ into the select mob.
|
||||
*
|
||||
@@ -69,11 +65,6 @@
|
||||
wash(CLEAN_TYPE_BLOOD)
|
||||
organ_flags &= ~ORGAN_VIRGIN
|
||||
|
||||
if(external_bodytypes)
|
||||
receiver.synchronize_bodytypes()
|
||||
if(external_bodyshapes)
|
||||
receiver.synchronize_bodyshapes()
|
||||
|
||||
receiver.organs |= src
|
||||
receiver.organs_slot[slot] = src
|
||||
owner = receiver
|
||||
@@ -129,9 +120,6 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT)
|
||||
interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
|
||||
if(bodypart_overlay)
|
||||
limb.add_bodypart_overlay(bodypart_overlay)
|
||||
|
||||
/*
|
||||
* Remove the organ from the select mob.
|
||||
*
|
||||
@@ -175,9 +163,6 @@
|
||||
SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special)
|
||||
ADD_TRAIT(src, TRAIT_USED_ORGAN, ORGAN_TRAIT)
|
||||
|
||||
organ_owner.synchronize_bodytypes()
|
||||
organ_owner.synchronize_bodyshapes()
|
||||
|
||||
var/list/diseases = organ_owner.get_static_viruses()
|
||||
if(!LAZYLEN(diseases))
|
||||
return
|
||||
@@ -226,16 +211,6 @@
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT)
|
||||
interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
|
||||
if(!bodypart_overlay)
|
||||
return
|
||||
|
||||
limb.remove_bodypart_overlay(bodypart_overlay)
|
||||
|
||||
if(use_mob_sprite_as_obj_sprite)
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
color = bodypart_overlay.draw_color // so a pink felinid doesn't drop a gray tail
|
||||
|
||||
/// In space station videogame, nothing is sacred. If somehow an organ is removed unexpectedly, handle it properly
|
||||
/obj/item/organ/proc/forced_removal()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/datum/unit_test/organ_bodypart_shuffle
|
||||
|
||||
/datum/unit_test/organ_bodypart_shuffle/Run()
|
||||
var/mob/living/carbon/human/hollow_boy = allocate(/mob/living/carbon/human/consistent) //freshly filled with wet insides
|
||||
var/mob/living/carbon/human/hollow_boy = allocate(/mob/living/carbon/human/consistent)
|
||||
|
||||
// Test if organs are all properly updating when forcefully removed
|
||||
var/list/removed_organs = list()
|
||||
@@ -30,3 +30,5 @@
|
||||
continue
|
||||
TEST_ASSERT(organ in hollow_boy.organs, "Organ '[organ.name] was put in an empty bodypart that replaced a humans, but the organ did not come with.")
|
||||
|
||||
// Test if bodyparts are all properly updating when forcefully removed
|
||||
hollow_boy = allocate(/mob/living/carbon/human/consistent) //freshly filled with wet insides
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
// Attempt to insert entire list of mutant organs for the given infusion_entry.
|
||||
for(var/obj/item/organ/organ as anything in output_organs)
|
||||
organ = new organ()
|
||||
organ.Insert(lab_rat, special = TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
TEST_ASSERT(organ.Insert(lab_rat, special = TRUE, movement_flags = DELETE_IF_REPLACED), "The organ `[organ.type]` for `[infuser_entry.type]` was not inserted in the mob when expected, Insert() returned falsy when TRUE was expected.")
|
||||
inserted_organs += organ
|
||||
|
||||
// Search for added Status Effect.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "An implant that can be placed in a user's head to control circuits using their brain."
|
||||
icon = 'icons/obj/science/circuits.dmi'
|
||||
icon_state = "bci"
|
||||
visual = FALSE
|
||||
zone = BODY_ZONE_HEAD
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
|
||||
@@ -6130,7 +6130,7 @@
|
||||
#include "code\modules\surgery\organs\autosurgeon.dm"
|
||||
#include "code\modules\surgery\organs\helpers.dm"
|
||||
#include "code\modules\surgery\organs\organ_movement.dm"
|
||||
#include "code\modules\surgery\organs\external\_visual_organs.dm"
|
||||
#include "code\modules\surgery\organs\external\_external_organ.dm"
|
||||
#include "code\modules\surgery\organs\external\restyling.dm"
|
||||
#include "code\modules\surgery\organs\external\spines.dm"
|
||||
#include "code\modules\surgery\organs\external\tails.dm"
|
||||
@@ -7677,6 +7677,7 @@
|
||||
#include "modular_skyrat\modules\gladiator\code\modules\mob\living\simple_animal\hostile\megafauna\markedone.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\cellphone.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\department_guards.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\hud.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\sec_clothing_overrides.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\sol_fed.dm"
|
||||
#include "modular_skyrat\modules\goofsec\code\solfed_clothing.dm"
|
||||
|
||||
Reference in New Issue
Block a user