mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Death of mutant bodyparts AND external organs (#85137)
## About The Pull Request Removes mutant bodyparts and external organs from the game completely Digitgrade behaviour was mutant bodypart for no reason Cat ears now work with the bodyparts overlay system, same as all the other external organs (since all their behaviour is now just on /organ It doesn't remove all the /external types, but moves all behaviour to /organ. I'll follow up with a PR wiping all the /external organ types, but it's just conflict heaven so not this PR I've also streamlined a lot of duplicate/weird species regeneration code Melbert did the same PR as well but due to a lack of time (?) I have absorbed his PR to double nuke mutant bodyparts ## Why It's Good For The Game Frees us from the chain of unmodular code, and kills my greatest nemesis (after the shuttle meteor murder bug) ## Changelog 🆑 Time-Green and MrMelbert Refactor: External organ behaviour has been moved to /organ, ears now use the same system as the other organs Refactor: Mutant bodyparts are dead! This likely does not mean much to the average person but it's very dear to me code: Improves digitgrade handling in preference code /🆑 I have absorbed #85126, using Melberts code to improve and add some missing changes. Mainly improving the functioning of preferences and digitgrade legs. I didn't take over the hairstyle improvements. --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
+26
-83
@@ -1,19 +1,11 @@
|
||||
/**
|
||||
* 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
|
||||
/*
|
||||
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/external
|
||||
name = "external organ"
|
||||
desc = "An external organ that is too external."
|
||||
|
||||
organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE
|
||||
visual = TRUE
|
||||
|
||||
/obj/item/organ
|
||||
///The overlay datum that actually draws stuff on the limb
|
||||
var/datum/bodypart_overlay/mutant/bodypart_overlay
|
||||
///If not null, overrides the appearance with this sprite accessory datum
|
||||
var/sprite_accessory_override
|
||||
|
||||
/// The savefile_key of the preference this relates to. Used for the preferences UI.
|
||||
var/preference
|
||||
@@ -23,21 +15,24 @@
|
||||
///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
|
||||
|
||||
/**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
|
||||
///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/external/Initialize(mapload, accessory_type)
|
||||
. = ..()
|
||||
|
||||
bodypart_overlay = new bodypart_overlay()
|
||||
/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
|
||||
@@ -55,61 +50,13 @@
|
||||
if(restyle_flags)
|
||||
RegisterSignal(src, COMSIG_ATOM_RESTYLE, PROC_REF(on_attempt_feature_restyle))
|
||||
|
||||
/obj/item/organ/external/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
receiver.update_body_parts()
|
||||
/// 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
|
||||
|
||||
/obj/item/organ/external/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
if(!special)
|
||||
organ_owner.update_body_parts()
|
||||
|
||||
/obj/item/organ/external/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
if(!should_external_organ_apply_to(type, receiver))
|
||||
stack_trace("adding a [type] to a [receiver.type] when it shouldn't be!")
|
||||
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(bodypart_overlay.imprint_on_next_insertion) //We only want this set *once*
|
||||
var/feature_name = receiver.dna.features[bodypart_overlay.feature_key]
|
||||
if (isnull(feature_name))
|
||||
feature_name = receiver.dna.species.external_organs[type]
|
||||
bodypart_overlay.set_appearance_from_name(feature_name)
|
||||
bodypart_overlay.imprint_on_next_insertion = FALSE
|
||||
|
||||
if(external_bodytypes)
|
||||
receiver.synchronize_bodytypes()
|
||||
if(external_bodyshapes)
|
||||
receiver.synchronize_bodyshapes()
|
||||
|
||||
receiver.update_body_parts()
|
||||
|
||||
/obj/item/organ/external/mob_remove(mob/living/carbon/organ_owner, special, moving)
|
||||
if(!special)
|
||||
organ_owner.synchronize_bodytypes()
|
||||
organ_owner.synchronize_bodyshapes()
|
||||
organ_owner.update_body_parts()
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/on_bodypart_insert(obj/item/bodypart/bodypart)
|
||||
bodypart.add_bodypart_overlay(bodypart_overlay)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/on_bodypart_remove(obj/item/bodypart/bodypart)
|
||||
bodypart.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
|
||||
return ..()
|
||||
|
||||
/proc/should_external_organ_apply_to(obj/item/organ/external/organpath, mob/living/carbon/target)
|
||||
if(isnull(organpath) || isnull(target))
|
||||
stack_trace("passed a null path or mob to 'should_external_organ_apply_to'")
|
||||
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)
|
||||
@@ -122,7 +69,7 @@
|
||||
return FALSE
|
||||
|
||||
///Update our features after something changed our appearance
|
||||
/obj/item/organ/external/proc/mutate_feature(features, mob/living/carbon/human/human)
|
||||
/obj/item/organ/proc/mutate_feature(features, mob/living/carbon/human/human)
|
||||
if(!dna_block)
|
||||
return
|
||||
|
||||
@@ -131,7 +78,7 @@
|
||||
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/external/proc/simple_change_sprite(accessory_type)
|
||||
/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)
|
||||
@@ -142,10 +89,7 @@
|
||||
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/external/on_life(seconds_per_tick, times_fired)
|
||||
return
|
||||
|
||||
/obj/item/organ/external/update_overlays()
|
||||
/obj/item/organ/update_overlays()
|
||||
. = ..()
|
||||
|
||||
if(!use_mob_sprite_as_obj_sprite)
|
||||
@@ -260,17 +204,16 @@
|
||||
///Store our old datum here for if our antennae are healed
|
||||
var/original_sprite_datum
|
||||
|
||||
/obj/item/organ/external/antennae/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/antennae/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
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/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/external/antennae/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
if(organ_owner)
|
||||
UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL))
|
||||
|
||||
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)
|
||||
+7
-8
@@ -1,7 +1,7 @@
|
||||
//Contains a bunch of procs for different types, but in the end it just lets you restyle external_organs so thats why its here
|
||||
//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
|
||||
|
||||
///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/external/proc/get_valid_restyles()
|
||||
/obj/item/organ/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/external/feature in contents)
|
||||
for(var/obj/item/organ/feature in contents)
|
||||
if(feature.restyle_flags & restyle_type)
|
||||
valid_features.Add(feature)
|
||||
|
||||
var/obj/item/organ/external/target_organ
|
||||
var/obj/item/organ/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/external/organ_choice as anything in valid_features)
|
||||
for(var/obj/item/organ/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/external/proc/on_attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
/obj/item/organ/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/external/proc/attempt_feature_restyle(atom/source, mob/living/trimmer, atom/movable/original_target, body_zone, restyle_type, style_speed)
|
||||
/obj/item/organ/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,5 +80,4 @@
|
||||
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
|
||||
|
||||
+2
-2
@@ -14,13 +14,13 @@
|
||||
|
||||
bodypart_overlay = /datum/bodypart_overlay/mutant/spines
|
||||
|
||||
/obj/item/organ/external/spines/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/spines/mob_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/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/external/spines/mob_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)
|
||||
|
||||
+3
-3
@@ -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/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/tail/mob_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.external_organs)
|
||||
else if(type in receiver.dna.species.mutant_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)
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
organ_owner.clear_mood_event("tail_regained")
|
||||
|
||||
if(type in organ_owner.dna.species.external_organs)
|
||||
if(type in organ_owner.dna.species.mutant_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,15 +35,14 @@
|
||||
QDEL_NULL(fly)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/external/wings/functional/Insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
/obj/item/organ/external/wings/functional/mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(QDELETED(fly))
|
||||
fly = new
|
||||
fly.Grant(receiver)
|
||||
|
||||
/obj/item/organ/external/wings/functional/Remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
/obj/item/organ/external/wings/functional/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
||||
. = ..()
|
||||
fly?.Remove(organ_owner)
|
||||
if(wings_open)
|
||||
|
||||
Reference in New Issue
Block a user