Files
nevimer 00ccf0c6b5 Merge remote-tracking branch 'tgstation/master' into upstream-feb12-2026
# Conflicts:
#	.github/CODEOWNERS
#	.github/workflows/compile_changelogs.yml
#	.github/workflows/stale.yml
#	SQL/database_changelog.md
#	_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
#	code/__DEFINES/atom_hud.dm
#	code/__DEFINES/inventory.dm
#	code/__DEFINES/mobs.dm
#	code/__DEFINES/species_clothing_paths.dm
#	code/__DEFINES/subsystems.dm
#	code/__DEFINES/surgery.dm
#	code/__HELPERS/global_lists.dm
#	code/_globalvars/lists/maintenance_loot.dm
#	code/_globalvars/traits/_traits.dm
#	code/controllers/subsystem/minor_mapping.dm
#	code/controllers/subsystem/processing/quirks.dm
#	code/controllers/subsystem/shuttle.dm
#	code/datums/components/palette.dm
#	code/datums/components/surgery_initiator.dm
#	code/datums/diseases/advance/advance.dm
#	code/datums/hud.dm
#	code/datums/mood.dm
#	code/datums/mutations/chameleon.dm
#	code/datums/quirks/negative_quirks/nyctophobia.dm
#	code/datums/status_effects/debuffs/debuffs.dm
#	code/datums/status_effects/debuffs/drunk.dm
#	code/datums/status_effects/debuffs/slime/slime_leech.dm
#	code/datums/weather/weather.dm
#	code/game/data_huds.dm
#	code/game/objects/items.dm
#	code/game/objects/items/devices/scanners/health_analyzer.dm
#	code/game/objects/items/frog_statue.dm
#	code/game/objects/items/rcd/RLD.dm
#	code/game/objects/items/robot/items/hypo.dm
#	code/game/objects/items/stacks/medical.dm
#	code/game/objects/items/stacks/wrap.dm
#	code/game/objects/items/storage/garment.dm
#	code/game/objects/items/tools/medical/defib.dm
#	code/game/objects/items/weaponry.dm
#	code/game/objects/items/weaponry/melee/misc.dm
#	code/game/objects/structures/crates_lockers/closets/secure/security.dm
#	code/game/objects/structures/curtains.dm
#	code/game/objects/structures/dresser.dm
#	code/game/objects/structures/girders.dm
#	code/game/objects/structures/maintenance.dm
#	code/game/objects/structures/mirror.dm
#	code/modules/admin/greyscale_modify_menu.dm
#	code/modules/admin/verbs/light_debug.dm
#	code/modules/antagonists/ashwalker/ashwalker.dm
#	code/modules/antagonists/heretic/knowledge/starting_lore.dm
#	code/modules/antagonists/ninja/ninjaDrainAct.dm
#	code/modules/art/paintings.dm
#	code/modules/client/preferences.dm
#	code/modules/client/verbs/ooc.dm
#	code/modules/clothing/head/wig.dm
#	code/modules/events/disease_outbreak.dm
#	code/modules/holodeck/holo_effect.dm
#	code/modules/jobs/job_types/head_of_security.dm
#	code/modules/jobs/job_types/security_officer.dm
#	code/modules/library/skill_learning/generic_skillchips/point.dm
#	code/modules/mining/lavaland/ash_flora.dm
#	code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm
#	code/modules/mob/dead/new_player/new_player.dm
#	code/modules/mob/living/basic/guardian/guardian.dm
#	code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm
#	code/modules/mob/living/carbon/carbon.dm
#	code/modules/mob/living/carbon/human/human.dm
#	code/modules/mob/living/carbon/human/human_defines.dm
#	code/modules/mob/living/carbon/life.dm
#	code/modules/mob/living/living.dm
#	code/modules/mob/living/living_defines.dm
#	code/modules/mob/mob.dm
#	code/modules/mob_spawn/ghost_roles/mining_roles.dm
#	code/modules/mod/mod_control.dm
#	code/modules/mod/modules/modules_general.dm
#	code/modules/modular_computers/computers/item/computer_ui.dm
#	code/modules/paperwork/paper.dm
#	code/modules/paperwork/paperbin.dm
#	code/modules/power/lighting/light.dm
#	code/modules/projectiles/guns/energy/kinetic_accelerator.dm
#	code/modules/projectiles/projectile.dm
#	code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
#	code/modules/reagents/chemistry/reagents/food_reagents.dm
#	code/modules/reagents/chemistry/reagents/other_reagents.dm
#	code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
#	code/modules/research/xenobiology/crossbreeding/_clothing.dm
#	code/modules/research/xenobiology/crossbreeding/prismatic.dm
#	code/modules/surgery/advanced/brainwashing.dm
#	code/modules/surgery/advanced/lobotomy.dm
#	code/modules/surgery/amputation.dm
#	code/modules/surgery/blood_filter.dm
#	code/modules/surgery/bodyparts/_bodyparts.dm
#	code/modules/surgery/brain_surgery.dm
#	code/modules/surgery/cavity_implant.dm
#	code/modules/surgery/coronary_bypass.dm
#	code/modules/surgery/gastrectomy.dm
#	code/modules/surgery/healing.dm
#	code/modules/surgery/limb_augmentation.dm
#	code/modules/surgery/organ_manipulation.dm
#	code/modules/surgery/revival.dm
#	code/modules/surgery/sleeper_protocol.dm
#	code/modules/surgery/surgery_helpers.dm
#	code/modules/surgery/surgery_step.dm
#	code/modules/unit_tests/_unit_tests.dm
#	code/modules/unit_tests/designs.dm
#	code/modules/unit_tests/icon_state_worn.dm
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png
#	icons/map_icons/clothing/head/_head.dmi
#	icons/map_icons/clothing/shoes.dmi
#	icons/map_icons/items/_item.dmi
#	icons/mob/huds/hud.dmi
#	icons/mob/inhands/64x64_lefthand.dmi
#	icons/mob/inhands/64x64_righthand.dmi
#	icons/obj/machines/computer.dmi
#	tgui/packages/tgui/interfaces/OperatingComputer.jsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/types.ts
#	tgui/packages/tgui/interfaces/SurgeryInitiator.tsx
#	tools/icon_cutter/check.py
2026-02-12 23:50:09 -05:00

254 lines
9.0 KiB
Plaintext

#define FUNCTIONAL_WING_FORCE 2.25 NEWTONS
#define FUNCTIONAL_WING_STABILIZATION 4.5 NEWTONS
///hud action for starting and stopping flight
/datum/action/innate/flight
name = "Toggle Flight"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE|AB_CHECK_INCAPACITATED
button_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "flight"
/datum/action/innate/flight/Activate()
var/mob/living/carbon/human/human = owner
var/obj/item/organ/wings/functional/wings = human.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS)
if(wings?.can_fly())
wings.toggle_flight(human)
///The true wings that you can use to fly and shit (you cant actually shit with them)
/obj/item/organ/wings/functional
///The flight action object
var/datum/action/innate/flight/fly
bodypart_overlay = /datum/bodypart_overlay/mutant/wings/functional
///Are our wings open or closed?
var/wings_open = FALSE
///We cant hide this wings in suit
var/cant_hide = FALSE
food_reagents = list(/datum/reagent/flightpotion = 5)
var/drift_force = FUNCTIONAL_WING_FORCE
var/stabilizer_force = FUNCTIONAL_WING_STABILIZATION
/obj/item/organ/wings/functional/Initialize(mapload)
. = ..()
AddComponent( \
/datum/component/jetpack, \
TRUE, \
drift_force, \
stabilizer_force, \
COMSIG_WINGS_OPENED, \
COMSIG_WINGS_CLOSED, \
null, \
CALLBACK(src, PROC_REF(can_fly)), \
CALLBACK(src, PROC_REF(can_fly)), \
)
/obj/item/organ/wings/functional/Destroy()
QDEL_NULL(fly)
return ..()
/obj/item/organ/wings/functional/grind_results()
return list(/datum/reagent/flightpotion = 5)
/obj/item/organ/wings/functional/on_mob_insert(mob/living/carbon/receiver, special, movement_flags)
. = ..()
if(QDELETED(fly))
fly = new
fly.Grant(receiver)
/obj/item/organ/wings/functional/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
. = ..()
fly?.Remove(organ_owner)
if(wings_open)
toggle_flight(organ_owner)
/obj/item/organ/wings/functional/on_life(seconds_per_tick)
. = ..()
handle_flight(owner)
///Called on_life(). Handle flight code and check if we're still flying
/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())
toggle_flight(human)
return FALSE
return TRUE
///Check if we're still eligible for flight (wings covered, atmosphere too thin, etc)
/obj/item/organ/wings/functional/proc/can_fly()
var/mob/living/carbon/human/human = owner
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
if(!cant_hide && (human.obscured_slots & HIDEJUMPSUIT))
to_chat(human, span_warning("Your clothing blocks your wings from extending!"))
return FALSE
var/turf/location = get_turf(human)
if(!location)
return FALSE
var/datum/gas_mixture/environment = location.return_air()
if(environment?.return_pressure() < HAZARD_LOW_PRESSURE + 10)
to_chat(human, span_warning("The atmosphere is too thin for you to fly!"))
return FALSE
return TRUE
///Slipping but in the air?
/obj/item/organ/wings/functional/proc/fly_slip(mob/living/carbon/human/human)
var/obj/buckled_obj
if(human.buckled)
buckled_obj = human.buckled
to_chat(human, span_notice("Your wings spazz out and launch you!"))
playsound(human.loc, 'sound/misc/slip.ogg', 50, TRUE, -3)
for(var/obj/item/choking_hazard in human.held_items)
human.accident(choking_hazard)
var/olddir = human.dir
human.stop_pulling()
if(buckled_obj)
buckled_obj.unbuckle_mob(human)
step(buckled_obj, olddir)
else
human.AddComponent(/datum/component/force_move, get_ranged_target_turf(human, olddir, 4), TRUE)
return TRUE
///UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly
/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_MOVE_FLOATING, TRAIT_IGNORING_GRAVITY, TRAIT_NOGRAV_ALWAYS_DRIFT), SPECIES_FLIGHT_TRAIT)
human.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/wings)
human.AddElement(/datum/element/forced_gravity, 0)
passtable_on(human, SPECIES_FLIGHT_TRAIT)
open_wings()
to_chat(human, span_notice("You beat your wings and begin to hover gently above the ground..."))
human.set_resting(FALSE, TRUE)
human.refresh_gravity()
return
human.physiology.stun_mod *= 0.5
human.remove_traits(list(TRAIT_MOVE_FLOATING, TRAIT_IGNORING_GRAVITY, TRAIT_NOGRAV_ALWAYS_DRIFT), SPECIES_FLIGHT_TRAIT)
human.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/wings)
human.RemoveElement(/datum/element/forced_gravity, 0)
passtable_off(human, SPECIES_FLIGHT_TRAIT)
to_chat(human, span_notice("You settle gently back onto the ground..."))
close_wings()
human.refresh_gravity()
///SPREAD OUR WINGS AND FLLLLLYYYYYY
/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()
SEND_SIGNAL(src, COMSIG_WINGS_OPENED, owner)
///close our 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()
owner.update_body_parts()
if(isturf(owner?.loc))
var/turf/location = loc
location.Entered(src, NONE)
SEND_SIGNAL(src, COMSIG_WINGS_CLOSED, owner)
///Bodypart overlay of function wings, including open and close functionality!
/datum/bodypart_overlay/mutant/wings/functional
///Are our wings currently open? Change through open_wings or close_wings()
VAR_PRIVATE/wings_open = FALSE
/datum/bodypart_overlay/mutant/wings/functional/get_global_feature_list()
/* SKYRAT EDIT - CUSTOMIZATION - ORIGINAL:
if(wings_open)
return SSaccessories.feature_list[FEATURE_WINGS_OPEN]
return ..()
*/
if(wings_open)
return SSaccessories.sprite_accessories["wings_open"]
return SSaccessories.sprite_accessories[FEATURE_WINGS]
// SKYRAT EDIT ADDITION END
///Update our wingsprite to the open wings variant
/datum/bodypart_overlay/mutant/wings/functional/proc/open_wings()
wings_open = TRUE
feature_key = FEATURE_WINGS_OPEN
set_appearance_from_name(sprite_datum.name) //It'll look for the same name again, but this time from the open wings list
///Update our wingsprite to the closed wings variant
/datum/bodypart_overlay/mutant/wings/functional/proc/close_wings()
wings_open = FALSE
feature_key = initial(feature_key)
set_appearance_from_name(sprite_datum.name)
/datum/bodypart_overlay/mutant/wings/functional/generate_icon_cache()
. = ..()
. += wings_open ? "open" : "closed"
///angel wings, which relate to humans. comes with holiness.
/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
organ_traits = list(TRAIT_HOLY)
///dragon wings, which relate to lizards.
/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/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. Gather 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/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/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/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/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/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/wings/functional/slime
name = "slime wings"
desc = "How does something so squishy even fly?"
sprite_accessory_override = /datum/sprite_accessory/wings/slime
#undef FUNCTIONAL_WING_FORCE
#undef FUNCTIONAL_WING_STABILIZATION