The death or internal/external organ pathing (ft. fixed fox ears and recoloring bodypart overlays with dye sprays) (#87434)

## About The Pull Request
This PR kills the abstract internal and external typepaths for organs,
now replaced by an EXTERNAL_ORGAN flag to distinguish the two kinds.

This PR also fixes fox ears (from #87162, no tail is added) and
mushpeople's caps (they should be red, the screenshot is a tad
outdated).

And yes, you can now use a hair dye spray to recolor body parts like
most tails, podpeople hair, mushpeople caps and cat ears. The process
can be reversed by using the spray again.

## Why It's Good For The Game
Time-Green put some effort during the last few months to untie functions
and mechanics from external/internal organ pathing. Now, all that this
pathing is good for are a few typechecks, easily replaceable with
bitflags.

Also podpeople and mushpeople need a way to recolor their "hair". This
kind of applies to fish tails from the fish infusion, which colors can't
be selected right now. The rest is just there if you ever want to
recolor your lizard tail for some reason.

Proof of testing btw (screenshot taken before mushpeople cap fix, right
side has dyed body parts, moth can't be dyed, they're already fabolous):

![immagine](https://github.com/user-attachments/assets/2bb625c9-9233-42eb-b9b8-e0bd6909ce89)

## Changelog

🆑
code: Removed internal/external pathing from organs in favor of a bit
flag. Hopefully this shouldn't break anything about organs.
fix: Fixed invisible fox ears.
fix: Fixed mushpeople caps not being colored red by default.
add: You can now dye most tails, podpeople hair, mushpeople caps etc.
with a hair dye spray.
/🆑
This commit is contained in:
Ghom
2024-10-30 08:03:02 +01:00
committed by GitHub
parent 0ec91798a7
commit 778ed9f1ab
473 changed files with 2564 additions and 2445 deletions
+26 -12
View File
@@ -100,7 +100,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
. += bodypart_overlay.get_overlay(external_layer, bodypart_owner)
///The horns of a lizard!
/obj/item/organ/external/horns
/obj/item/organ/horns
name = "horns"
desc = "Why do lizards even have horns? Well, this one obviously doesn't."
icon_state = "horns"
@@ -114,9 +114,12 @@ Unlike normal organs, we're actually inside a persons limbs at all times
bodypart_overlay = /datum/bodypart_overlay/mutant/horns
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
/datum/bodypart_overlay/mutant/horns
layers = EXTERNAL_ADJACENT
feature_key = "horns"
dyable = TRUE
/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))
@@ -128,7 +131,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
return SSaccessories.horns_list
///The frills of a lizard (like weird fin ears)
/obj/item/organ/external/frills
/obj/item/organ/frills
name = "frills"
desc = "Ear-like external organs often seen on aquatic reptillians."
icon_state = "frills"
@@ -142,6 +145,8 @@ Unlike normal organs, we're actually inside a persons limbs at all times
bodypart_overlay = /datum/bodypart_overlay/mutant/frills
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
/datum/bodypart_overlay/mutant/frills
layers = EXTERNAL_ADJACENT
feature_key = "frills"
@@ -155,7 +160,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
return SSaccessories.frills_list
///Guess what part of the lizard this is?
/obj/item/organ/external/snout
/obj/item/organ/snout
name = "lizard snout"
desc = "Take a closer look at that snout!"
icon_state = "snout"
@@ -171,6 +176,8 @@ Unlike normal organs, we're actually inside a persons limbs at all times
bodypart_overlay = /datum/bodypart_overlay/mutant/snout
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
/datum/bodypart_overlay/mutant/snout
layers = EXTERNAL_ADJACENT
feature_key = "snout"
@@ -184,7 +191,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
return SSaccessories.snouts_list
///A moth's antennae
/obj/item/organ/external/antennae
/obj/item/organ/antennae
name = "moth antennae"
desc = "A moths antennae. What is it telling them? What are they sensing?"
icon_state = "antennae"
@@ -198,24 +205,26 @@ Unlike normal organs, we're actually inside a persons limbs at all times
bodypart_overlay = /datum/bodypart_overlay/mutant/antennae
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
///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)
/obj/item/organ/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)
/obj/item/organ/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)
/obj/item/organ/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
@@ -225,13 +234,13 @@ Unlike normal organs, we're actually inside a persons limbs at all times
human.update_body_parts()
///Burn our antennae off ;_;
/obj/item/organ/external/antennae/proc/burn_antennae()
/obj/item/organ/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)
/obj/item/organ/antennae/proc/heal_antennae(datum/source, heal_flags)
SIGNAL_HANDLER
if(!burnt)
@@ -246,6 +255,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
/datum/bodypart_overlay/mutant/antennae
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
feature_key = "moth_antennae"
dyable = TRUE
///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
@@ -268,7 +278,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
return FALSE
///The leafy hair of a podperson
/obj/item/organ/external/pod_hair
/obj/item/organ/pod_hair
name = "podperson hair"
desc = "Base for many-o-salads."
@@ -283,10 +293,13 @@ Unlike normal organs, we're actually inside a persons limbs at all times
bodypart_overlay = /datum/bodypart_overlay/mutant/pod_hair
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
///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"
dyable = TRUE
///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
@@ -300,8 +313,9 @@ Unlike normal organs, we're actually inside a persons limbs at all times
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)
var/color_to_use = dye_color || draw_color
if(color_to_use) // can someone explain to me why draw_color is allowed to EVER BE AN EMPTY STRING
var/list/rgb_list = rgb2num(color_to_use)
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
+13 -5
View File
@@ -1,5 +1,5 @@
///A lizards spines (those things on their back), but also including tail spines (gasp)
/obj/item/organ/external/spines
/obj/item/organ/spines
name = "lizard spines"
desc = "Not an actual spine, obviously."
icon_state = "spines"
@@ -14,15 +14,17 @@
bodypart_overlay = /datum/bodypart_overlay/mutant/spines
/obj/item/organ/external/spines/mob_insert(mob/living/carbon/receiver, special, movement_flags)
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
/obj/item/organ/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)
var/obj/item/organ/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/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)
var/obj/item/organ/tail/our_tail = organ_owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
our_tail?.remove_tail_spines(our_tail.bodypart_owner)
return ..()
@@ -30,6 +32,7 @@
/datum/bodypart_overlay/mutant/spines
layers = EXTERNAL_ADJACENT|EXTERNAL_BEHIND
feature_key = "spines"
dyable = TRUE
/datum/bodypart_overlay/mutant/spines/get_global_feature_list()
return SSaccessories.spines_list
@@ -38,3 +41,8 @@
. = ..()
if(human.wear_suit && (human.wear_suit.flags_inv & HIDEJUMPSUIT))
return FALSE
/datum/bodypart_overlay/mutant/spines/set_dye_color(new_color, obj/item/organ/tail/organ)
var/obj/item/organ/tail/tail = organ?.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
tail?.tail_spines_overlay?.set_dye_color(new_color, organ)
return ..()
+23 -17
View File
@@ -1,5 +1,5 @@
///Tail parent, it doesn't do very much.
/obj/item/organ/external/tail
/obj/item/organ/tail
name = "tail"
desc = "A severed tail. What did you cut this off of?"
icon_state = "severedtail"
@@ -13,6 +13,8 @@
// defaults to cat, but the parent type shouldn't be created regardless
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/cat
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
///Does this tail have a wagging sprite, and is it currently wagging?
var/wag_flags = NONE
///The original owner of this tail
@@ -20,7 +22,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/tail/mob_insert(mob/living/carbon/receiver, special, movement_flags)
. = ..()
if(.)
receiver.clear_mood_event("tail_lost")
@@ -39,18 +41,18 @@
else
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_wrong)
/obj/item/organ/external/tail/on_bodypart_insert(obj/item/bodypart/bodypart)
var/obj/item/organ/external/spines/our_spines = bodypart.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_SPINES)
/obj/item/organ/tail/on_bodypart_insert(obj/item/bodypart/bodypart)
var/obj/item/organ/spines/our_spines = bodypart.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_SPINES)
if(our_spines)
try_insert_tail_spines(bodypart)
return ..()
/obj/item/organ/external/tail/on_bodypart_remove(obj/item/bodypart/bodypart)
/obj/item/organ/tail/on_bodypart_remove(obj/item/bodypart/bodypart)
remove_tail_spines(bodypart)
return ..()
/// If the owner has spines and an appropriate overlay exists, add a tail spines overlay.
/obj/item/organ/external/tail/proc/try_insert_tail_spines(obj/item/bodypart/bodypart)
/obj/item/organ/tail/proc/try_insert_tail_spines(obj/item/bodypart/bodypart)
// Don't insert another overlay if there already is one.
if(tail_spines_overlay)
return
@@ -69,13 +71,13 @@
bodypart.add_bodypart_overlay(tail_spines_overlay)
/// If we have a tail spines overlay, delete it
/obj/item/organ/external/tail/proc/remove_tail_spines(obj/item/bodypart/bodypart)
/obj/item/organ/tail/proc/remove_tail_spines(obj/item/bodypart/bodypart)
if(!tail_spines_overlay)
return
bodypart.remove_bodypart_overlay(tail_spines_overlay)
QDEL_NULL(tail_spines_overlay)
/obj/item/organ/external/tail/on_mob_remove(mob/living/carbon/organ_owner, special)
/obj/item/organ/tail/on_mob_remove(mob/living/carbon/organ_owner, special)
. = ..()
if(wag_flags & WAG_WAGGING)
@@ -90,7 +92,7 @@
///We need some special behaviour for accessories, wrapped here so we can easily add more interactions later
///Accepts an optional timeout after which we remove the tail wagging
///Returns false if the wag worked, true otherwise
/obj/item/organ/external/tail/proc/start_wag(mob/living/carbon/organ_owner, stop_after = INFINITY)
/obj/item/organ/tail/proc/start_wag(mob/living/carbon/organ_owner, stop_after = INFINITY)
if(wag_flags & WAG_WAGGING || !(wag_flags & WAG_ABLE)) // we are already wagging
return FALSE
if(organ_owner.stat == DEAD || organ_owner != owner) // no wagging when owner is dead or tail has been disembodied
@@ -108,13 +110,13 @@
RegisterSignal(organ_owner, COMSIG_LIVING_DEATH, PROC_REF(owner_died))
return TRUE
/obj/item/organ/external/tail/proc/owner_died(mob/living/carbon/organ_owner) // Resisting the urge to replace owner with daddy
/obj/item/organ/tail/proc/owner_died(mob/living/carbon/organ_owner) // Resisting the urge to replace owner with daddy
SIGNAL_HANDLER
stop_wag(organ_owner)
///We need some special behaviour for accessories, wrapped here so we can easily add more interactions later
///Returns false if the wag stopping worked, true otherwise
/obj/item/organ/external/tail/proc/stop_wag(mob/living/carbon/organ_owner)
/obj/item/organ/tail/proc/stop_wag(mob/living/carbon/organ_owner)
if(!(wag_flags & WAG_ABLE))
return FALSE
@@ -134,12 +136,13 @@
UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH)
return succeeded
/obj/item/organ/external/tail/proc/get_butt_sprite()
/obj/item/organ/tail/proc/get_butt_sprite()
return null
///Tail parent type, with wagging functionality
/datum/bodypart_overlay/mutant/tail
layers = EXTERNAL_FRONT|EXTERNAL_BEHIND
dyable = TRUE
var/wagging = FALSE
/datum/bodypart_overlay/mutant/tail/get_base_icon_state()
@@ -150,7 +153,7 @@
return FALSE
return TRUE
/obj/item/organ/external/tail/cat
/obj/item/organ/tail/cat
name = "tail"
preference = "feature_human_tail"
@@ -158,7 +161,7 @@
wag_flags = WAG_ABLE
/obj/item/organ/external/tail/cat/get_butt_sprite()
/obj/item/organ/tail/cat/get_butt_sprite()
return icon('icons/mob/butts.dmi', BUTT_SPRITE_CAT)
///Cat tail bodypart overlay
@@ -169,7 +172,7 @@
/datum/bodypart_overlay/mutant/tail/cat/get_global_feature_list()
return SSaccessories.tails_list_felinid
/obj/item/organ/external/tail/monkey
/obj/item/organ/tail/monkey
name = "monkey tail"
preference = "feature_monkey_tail"
@@ -185,7 +188,7 @@
/datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list()
return SSaccessories.tails_list_monkey
/obj/item/organ/external/tail/lizard
/obj/item/organ/tail/lizard
name = "lizard tail"
desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves."
preference = "feature_lizard_tail"
@@ -202,7 +205,7 @@
/datum/bodypart_overlay/mutant/tail/lizard/get_global_feature_list()
return SSaccessories.tails_list_lizard
/obj/item/organ/external/tail/lizard/fake
/obj/item/organ/tail/lizard/fake
name = "fabricated lizard tail"
desc = "A fabricated severed lizard tail. This one's made of synthflesh. Probably not usable for lizard wine."
@@ -225,3 +228,6 @@
. = ..()
if(human.wear_suit && (human.wear_suit.flags_inv & HIDEJUMPSUIT))
return FALSE
/datum/bodypart_overlay/mutant/tail_spines/set_dye_color(new_color, obj/item/organ/organ)
dye_color = new_color //no update_body_parts() call, tail/set_dye_color will do it.
@@ -10,12 +10,12 @@
/datum/action/innate/flight/Activate()
var/mob/living/carbon/human/human = owner
var/obj/item/organ/external/wings/functional/wings = human.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS)
var/obj/item/organ/wings/functional/wings = human.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS)
if(wings?.can_fly(human))
wings.toggle_flight(human)
///The true wings that you can use to fly and shit (you cant actually shit with them)
/obj/item/organ/external/wings/functional
/obj/item/organ/wings/functional
///The flight action object
var/datum/action/innate/flight/fly
@@ -29,29 +29,29 @@
// grind_results = list(/datum/reagent/flightpotion = 5)
food_reagents = list(/datum/reagent/flightpotion = 5)
/obj/item/organ/external/wings/functional/Destroy()
/obj/item/organ/wings/functional/Destroy()
QDEL_NULL(fly)
return ..()
/obj/item/organ/external/wings/functional/mob_insert(mob/living/carbon/receiver, special, movement_flags)
/obj/item/organ/wings/functional/mob_insert(mob/living/carbon/receiver, special, movement_flags)
. = ..()
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/wings/functional/mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
. = ..()
fly?.Remove(organ_owner)
if(wings_open)
toggle_flight(organ_owner)
/obj/item/organ/external/wings/functional/on_life(seconds_per_tick, times_fired)
/obj/item/organ/wings/functional/on_life(seconds_per_tick, times_fired)
. = ..()
handle_flight(owner)
///Called on_life(). Handle flight code and check if we're still flying
/obj/item/organ/external/wings/functional/proc/handle_flight(mob/living/carbon/human/human)
/obj/item/organ/wings/functional/proc/handle_flight(mob/living/carbon/human/human)
if(!HAS_TRAIT_FROM(human, TRAIT_MOVE_FLOATING, SPECIES_FLIGHT_TRAIT))
return FALSE
if(!can_fly(human))
@@ -61,7 +61,7 @@
///Check if we're still eligible for flight (wings covered, atmosphere too thin, etc)
/obj/item/organ/external/wings/functional/proc/can_fly(mob/living/carbon/human/human)
/obj/item/organ/wings/functional/proc/can_fly(mob/living/carbon/human/human)
if(human.stat || human.body_position == LYING_DOWN || isnull(human.client))
return FALSE
//Jumpsuits have tail holes, so it makes sense they have wing holes too
@@ -79,7 +79,7 @@
return TRUE
///Slipping but in the air?
/obj/item/organ/external/wings/functional/proc/fly_slip(mob/living/carbon/human/human)
/obj/item/organ/wings/functional/proc/fly_slip(mob/living/carbon/human/human)
var/obj/buckled_obj
if(human.buckled)
buckled_obj = human.buckled
@@ -102,7 +102,7 @@
return TRUE
///UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly
/obj/item/organ/external/wings/functional/proc/toggle_flight(mob/living/carbon/human/human)
/obj/item/organ/wings/functional/proc/toggle_flight(mob/living/carbon/human/human)
if(!HAS_TRAIT_FROM(human, TRAIT_MOVE_FLOATING, SPECIES_FLIGHT_TRAIT))
human.physiology.stun_mod *= 2
human.add_traits(list(TRAIT_NO_FLOATING_ANIM, TRAIT_MOVE_FLOATING, TRAIT_IGNORING_GRAVITY, TRAIT_NOGRAV_ALWAYS_DRIFT), SPECIES_FLIGHT_TRAIT)
@@ -129,7 +129,7 @@
close_wings()
human.refresh_gravity()
/obj/item/organ/external/wings/functional/proc/on_client_move(mob/source, list/move_args)
/obj/item/organ/wings/functional/proc/on_client_move(mob/source, list/move_args)
SIGNAL_HANDLER
if (!can_fly(source))
@@ -139,7 +139,7 @@
source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = FUNCTIONAL_WING_FORCE, controlled_cap = max_drift_force)
source.setDir(source.client.intended_direction)
/obj/item/organ/external/wings/functional/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup)
/obj/item/organ/wings/functional/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup)
SIGNAL_HANDLER
if (get_dir(source, backup) == movement_dir || source.loc == backup.loc)
@@ -150,7 +150,7 @@
return COMPONENT_PREVENT_SPACEMOVE_HALT
/obj/item/organ/external/wings/functional/process(seconds_per_tick)
/obj/item/organ/wings/functional/process(seconds_per_tick)
if (!owner || !can_fly(owner) || isnull(owner.drift_handler))
return
@@ -158,14 +158,14 @@
owner.drift_handler.stabilize_drift(owner.client.intended_direction ? dir2angle(owner.client.intended_direction) : null, owner.client.intended_direction ? max_drift_force : 0, FUNCTIONAL_WING_STABILIZATION * (seconds_per_tick * 1 SECONDS))
///SPREAD OUR WINGS AND FLLLLLYYYYYY
/obj/item/organ/external/wings/functional/proc/open_wings()
/obj/item/organ/wings/functional/proc/open_wings()
var/datum/bodypart_overlay/mutant/wings/functional/overlay = bodypart_overlay
overlay.open_wings()
wings_open = TRUE
owner.update_body_parts()
///close our wings
/obj/item/organ/external/wings/functional/proc/close_wings()
/obj/item/organ/wings/functional/proc/close_wings()
var/datum/bodypart_overlay/mutant/wings/functional/overlay = bodypart_overlay
wings_open = FALSE
overlay.close_wings()
@@ -205,7 +205,7 @@
. += wings_open ? "open" : "closed"
///angel wings, which relate to humans. comes with holiness.
/obj/item/organ/external/wings/functional/angel
/obj/item/organ/wings/functional/angel
name = "angel wings"
desc = "Holier-than-thou attitude not included."
sprite_accessory_override = /datum/sprite_accessory/wings_open/angel
@@ -213,47 +213,47 @@
organ_traits = list(TRAIT_HOLY)
///dragon wings, which relate to lizards.
/obj/item/organ/external/wings/functional/dragon
/obj/item/organ/wings/functional/dragon
name = "dragon wings"
desc = "Hey, HEY- NOT lizard wings. Dragon wings. Mighty dragon wings."
sprite_accessory_override = /datum/sprite_accessory/wings/dragon
///robotic wings, which relate to androids.
/obj/item/organ/external/wings/functional/robotic
/obj/item/organ/wings/functional/robotic
name = "robotic wings"
desc = "Using microscopic hover-engines, or \"microwings,\" as they're known in the trade, these tiny devices are able to lift a few grams at a time. Gathering enough of them, and you can lift impressively large things."
organ_flags = ORGAN_ROBOTIC
sprite_accessory_override = /datum/sprite_accessory/wings/robotic
///skeletal wings, which relate to skeletal races.
/obj/item/organ/external/wings/functional/skeleton
/obj/item/organ/wings/functional/skeleton
name = "skeletal wings"
desc = "Powered by pure edgy-teenager-notebook-scribblings. Just kidding. But seriously, how do these keep you flying?!"
sprite_accessory_override = /datum/sprite_accessory/wings/skeleton
/obj/item/organ/external/wings/functional/moth/make_flap_sound(mob/living/carbon/wing_owner)
/obj/item/organ/wings/functional/moth/make_flap_sound(mob/living/carbon/wing_owner)
playsound(wing_owner, 'sound/mobs/humanoids/moth/moth_flutter.ogg', 50, TRUE)
///mothra wings, which relate to moths.
/obj/item/organ/external/wings/functional/moth/mothra
/obj/item/organ/wings/functional/moth/mothra
name = "mothra wings"
desc = "Fly like the mighty mothra of legend once did."
sprite_accessory_override = /datum/sprite_accessory/wings/mothra
///megamoth wings, which relate to moths as an alternate choice. they're both pretty cool.
/obj/item/organ/external/wings/functional/moth/megamoth
/obj/item/organ/wings/functional/moth/megamoth
name = "megamoth wings"
desc = "Don't get murderous."
sprite_accessory_override = /datum/sprite_accessory/wings/megamoth
///fly wings, which relate to flies.
/obj/item/organ/external/wings/functional/fly
/obj/item/organ/wings/functional/fly
name = "fly wings"
desc = "Fly as a fly."
sprite_accessory_override = /datum/sprite_accessory/wings/fly
///slime wings, which relate to slimes.
/obj/item/organ/external/wings/functional/slime
/obj/item/organ/wings/functional/slime
name = "slime wings"
desc = "How does something so squishy even fly?"
sprite_accessory_override = /datum/sprite_accessory/wings/slime
+12 -12
View File
@@ -1,7 +1,7 @@
#define MOTH_WING_FORCE 1 NEWTONS
///Moth wings! They can flutter in low-grav and burn off in heat
/obj/item/organ/external/wings/moth
/obj/item/organ/wings/moth
name = "moth wings"
desc = "Spread your wings and FLOOOOAAAAAT!"
@@ -16,7 +16,7 @@
///Store our old datum here for if our burned wings are healed
var/original_sprite_datum
/obj/item/organ/external/wings/moth/on_mob_insert(mob/living/carbon/receiver)
/obj/item/organ/wings/moth/on_mob_insert(mob/living/carbon/receiver)
. = ..()
RegisterSignal(receiver, COMSIG_HUMAN_BURNING, PROC_REF(try_burn_wings))
RegisterSignal(receiver, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(heal_wings))
@@ -24,18 +24,18 @@
RegisterSignal(receiver, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(on_pushoff))
START_PROCESSING(SSnewtonian_movement, src)
/obj/item/organ/external/wings/moth/on_mob_remove(mob/living/carbon/organ_owner)
/obj/item/organ/wings/moth/on_mob_remove(mob/living/carbon/organ_owner)
. = ..()
UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE))
STOP_PROCESSING(SSnewtonian_movement, src)
/obj/item/organ/external/wings/moth/make_flap_sound(mob/living/carbon/wing_owner)
/obj/item/organ/wings/moth/make_flap_sound(mob/living/carbon/wing_owner)
playsound(wing_owner, 'sound/mobs/humanoids/moth/moth_flutter.ogg', 50, TRUE)
/obj/item/organ/external/wings/moth/can_soften_fall()
/obj/item/organ/wings/moth/can_soften_fall()
return !burnt
/obj/item/organ/external/wings/moth/proc/allow_flight()
/obj/item/organ/wings/moth/proc/allow_flight()
if(!owner || !owner.client)
return FALSE
if(!isturf(owner.loc))
@@ -59,14 +59,14 @@
return TRUE
return FALSE
/obj/item/organ/external/wings/moth/process(seconds_per_tick)
/obj/item/organ/wings/moth/process(seconds_per_tick)
if (!owner || !allow_flight() || isnull(owner.drift_handler))
return
var/max_drift_force = (DEFAULT_INERTIA_SPEED / owner.cached_multiplicative_slowdown - 1) / INERTIA_SPEED_COEF + 1
owner.drift_handler.stabilize_drift(owner.client.intended_direction ? dir2angle(owner.client.intended_direction) : null, owner.client.intended_direction ? max_drift_force : 0, MOTH_WING_FORCE * (seconds_per_tick * 1 SECONDS))
/obj/item/organ/external/wings/moth/proc/on_client_move(mob/source, list/move_args)
/obj/item/organ/wings/moth/proc/on_client_move(mob/source, list/move_args)
SIGNAL_HANDLER
if (!allow_flight())
@@ -76,7 +76,7 @@
source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = MOTH_WING_FORCE, controlled_cap = max_drift_force)
source.setDir(source.client.intended_direction)
/obj/item/organ/external/wings/moth/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup)
/obj/item/organ/wings/moth/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup)
SIGNAL_HANDLER
if (get_dir(source, backup) == movement_dir || source.loc == backup.loc)
@@ -88,7 +88,7 @@
return COMPONENT_PREVENT_SPACEMOVE_HALT
///check if our wings can burn off ;_;
/obj/item/organ/external/wings/moth/proc/try_burn_wings(mob/living/carbon/human/human)
/obj/item/organ/wings/moth/proc/try_burn_wings(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
@@ -99,13 +99,13 @@
human.update_body_parts()
///burn the wings off
/obj/item/organ/external/wings/moth/proc/burn_wings()
/obj/item/organ/wings/moth/proc/burn_wings()
var/datum/bodypart_overlay/mutant/wings/moth/wings = bodypart_overlay
wings.burnt = TRUE
burnt = TRUE
///heal our wings back up!!
/obj/item/organ/external/wings/moth/proc/heal_wings(datum/source, heal_flags)
/obj/item/organ/wings/moth/proc/heal_wings(datum/source, heal_flags)
SIGNAL_HANDLER
if(!burnt)
+5 -3
View File
@@ -1,5 +1,5 @@
///Wing base type. doesn't really do anything
/obj/item/organ/external/wings
/obj/item/organ/wings
name = "wings"
desc = "Spread your wings and FLLLLLLLLYYYYY!"
@@ -9,12 +9,14 @@
use_mob_sprite_as_obj_sprite = TRUE
bodypart_overlay = /datum/bodypart_overlay/mutant/wings
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
///Checks if the wings can soften short falls
/obj/item/organ/external/wings/proc/can_soften_fall()
/obj/item/organ/wings/proc/can_soften_fall()
return TRUE
///Implement as needed to play a sound effect on *flap emote
/obj/item/organ/external/wings/proc/make_flap_sound(mob/living/carbon/wing_owner)
/obj/item/organ/wings/proc/make_flap_sound(mob/living/carbon/wing_owner)
return
///Bodypart overlay of default wings. Does not have any wing functionality