Moved a few monkeys features out of species code (+ updated a couple infusion organs) (#96735)

## About The Pull Request
Title. I'm moving a few monkey features away from the species and into
its bodyparts and organs. I plan on following up with another PR for the
various `ismonkey()` in the code, as these are necessary changes for a
niche thing I'm ultimately working on.

Also one carp organ and one stoat organ both had bits of code made
redundant by available traits. This takes care of them.
Also removed the passwindow_on/off and passtable_on/off procs. We can
just register the associated trait signals on init for living mobs (plus
they were being misused on non-mobs).

## Why It's Good For The Game
Less code associated directly to the species and more to its body parts
and organs, which is basically something we've been doing for a few
years ~~(also I need it for skeletonized monkeys)~~.

## Changelog
N/A
This commit is contained in:
Ghom
2026-07-11 21:51:39 +01:00
committed by GitHub
parent 5d5d68b87b
commit 54df8cab2d
21 changed files with 88 additions and 103 deletions
-26
View File
@@ -466,32 +466,6 @@ GLOBAL_LIST_INIT(skin_tone_names, list(
var/mob/living/spawned_mob = new chosen(spawn_location)
return spawned_mob
/proc/passtable_on(target, source)
var/mob/living/L = target
if (!HAS_TRAIT(L, TRAIT_PASSTABLE) && L.pass_flags & PASSTABLE)
ADD_TRAIT(L, TRAIT_PASSTABLE, INNATE_TRAIT)
ADD_TRAIT(L, TRAIT_PASSTABLE, source)
L.pass_flags |= PASSTABLE
/proc/passtable_off(target, source)
var/mob/living/L = target
REMOVE_TRAIT(L, TRAIT_PASSTABLE, source)
if(!HAS_TRAIT(L, TRAIT_PASSTABLE))
L.pass_flags &= ~PASSTABLE
/proc/passwindow_on(target, source)
var/mob/living/target_mob = target
if (!HAS_TRAIT(target_mob, TRAIT_PASSWINDOW) && target_mob.pass_flags & PASSWINDOW)
ADD_TRAIT(target_mob, TRAIT_PASSWINDOW, INNATE_TRAIT)
ADD_TRAIT(target_mob, TRAIT_PASSWINDOW, source)
target_mob.pass_flags |= PASSWINDOW
/proc/passwindow_off(target, source)
var/mob/living/target_mob = target
REMOVE_TRAIT(target_mob, TRAIT_PASSWINDOW, source)
if(!HAS_TRAIT(target_mob, TRAIT_PASSWINDOW))
target_mob.pass_flags &= ~PASSWINDOW
/proc/dance_rotate(atom/movable/AM, datum/callback/callperrotate, set_original_dir=FALSE)
set waitfor = FALSE
var/originaldir = AM.dir
+2 -2
View File
@@ -60,7 +60,7 @@
human_owner.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/shoes)
human_owner.AddElement(/datum/element/forced_gravity, 0)
SEND_SIGNAL(human_owner, COMSIG_JETBOOTS_ACTIVE, human_owner)
passtable_on(human_owner, SHOES_TRAIT)
ADD_TRAIT(human_owner, TRAIT_PASSTABLE, SHOES_TRAIT)
to_chat(human_owner, span_notice("You click your jet boots together and begin to hover gently above the ground..."))
human_owner.set_resting(FALSE, TRUE)
human_owner.refresh_gravity()
@@ -79,7 +79,7 @@
human_owner.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/shoes)
human_owner.RemoveElement(/datum/element/forced_gravity, 0)
SEND_SIGNAL(human_owner, COMSIG_JETBOOTS_INACTIVE, human_owner)
passtable_off(human_owner, SHOES_TRAIT)
REMOVE_TRAIT(human_owner, TRAIT_PASSTABLE, SHOES_TRAIT)
to_chat(human_owner, span_notice("You're lowered back onto the ground..."))
human_owner.refresh_gravity()
UnregisterSignal(human_owner, list(COMSIG_LIVING_STATUS_STUN, COMSIG_LIVING_STATUS_KNOCKDOWN, COMSIG_LIVING_STATUS_PARALYZE))
+4 -4
View File
@@ -14,7 +14,7 @@
/datum/component/glass_passer/RegisterWithParent()
if(!pass_time)
passwindow_on(parent, type)
ADD_TRAIT(parent, TRAIT_PASSWINDOW, type)
else
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(bumped))
@@ -27,7 +27,7 @@
/datum/component/glass_passer/UnregisterFromParent()
if(parent)
passwindow_off(parent, type)
REMOVE_TRAIT(parent, TRAIT_PASSWINDOW, type)
/datum/component/glass_passer/proc/on_cross_over(mob/passer, atom/crosser)
SIGNAL_HANDLER
@@ -72,6 +72,6 @@
/datum/component/glass_passer/proc/phase_through_glass(mob/living/owner, atom/bumpee)
if(!do_after(owner, pass_time, bumpee))
return
passwindow_on(owner, type)
ADD_TRAIT(owner, TRAIT_PASSWINDOW, type)
try_move_adjacent(owner, get_dir(owner, bumpee))
passwindow_off(owner, type)
REMOVE_TRAIT(owner, TRAIT_PASSWINDOW, type)
+2 -2
View File
@@ -143,13 +143,13 @@
return
var/passtable_key = REF(user)
passtable_on(pushed_mob, passtable_key)
ADD_TRAIT(pushed_mob, TRAIT_PASSTABLE, passtable_key)
for (var/obj/obj in user.loc.contents)
if (!obj.CanAllowThrough(pushed_mob))
return
pushed_mob.Move(table.loc)
passtable_off(pushed_mob, passtable_key)
REMOVE_TRAIT(pushed_mob, TRAIT_PASSTABLE, passtable_key)
if (pushed_mob.loc != table.loc) //Something prevented the tabling
return
+2 -2
View File
@@ -11,7 +11,7 @@
return ELEMENT_INCOMPATIBLE
var/mob/living/living_target = target
RegisterSignal(living_target, COMSIG_MOVABLE_MOVED, PROC_REF(flying_window_smash))
passwindow_on(target, TRAM_PASSENGER_TRAIT)
ADD_TRAIT(target, TRAIT_PASSWINDOW, TRAM_PASSENGER_TRAIT)
addtimer(CALLBACK(src, PROC_REF(Detach), living_target), duration)
/// Smash any windows that the mob is flying through
@@ -29,5 +29,5 @@
/datum/element/window_smashing/Detach(datum/source)
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
passwindow_off(source, TRAM_PASSENGER_TRAIT)
REMOVE_TRAIT(source, TRAIT_PASSWINDOW, TRAM_PASSENGER_TRAIT)
return ..()
@@ -120,6 +120,7 @@
greyscale_colors = CARP_COLORS
can_smoothen_out = FALSE
shade_color = "blue"
organ_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_LITERATE, TRAIT_CAN_STRIP, TRAIT_FERAL_BITER)
///Timer counting down. When finished, the owner gets a bad moodlet.
var/cooldown_timer
@@ -125,29 +125,13 @@
greyscale_colors = STOAT_COLORS
beat_noise = "a fast-paced high-pitched pit-pat"
maxHealth = parent_type::maxHealth * 0.8 // weaker heart
/// Tracks height of the mob on add
var/mob_base_height = HUMAN_HEIGHT_MEDIUM
organ_traits = list(TRAIT_TOO_TALL) //noodly boy
/obj/item/organ/heart/stoat/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat)
AddElement(/datum/element/update_icon_blocker)
/obj/item/organ/heart/stoat/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags)
. = ..()
if(!ishuman(organ_owner))
return
var/mob/living/carbon/human/human_owner = organ_owner
mob_base_height = human_owner.get_base_mob_height()
human_owner.set_mob_height(HUMAN_HEIGHT_TALLEST, update_dna = FALSE)
/obj/item/organ/heart/stoat/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
. = ..()
if(!ishuman(organ_owner))
return
var/mob/living/carbon/human/human_owner = organ_owner
human_owner.set_mob_height(mob_base_height, update_dna = FALSE)
/obj/item/organ/tongue/stoat
name = "mutated stoat-tongue"
desc = "Stoat DNA infused into what was once a normal tongue."
+1 -1
View File
@@ -129,7 +129,7 @@
flags_1 &= ~PREVENT_CLICK_UNDER_1
if(glass)
passwindow_on(src, INNATE_TRAIT)
pass_flags |= PASSWINDOW
//doors only block while dense though so we have to use the proc
real_explosion_block = explosion_block
update_explosive_block()
@@ -109,7 +109,7 @@
charge.Grant(src)
// Glass passing is handled by the glass passer component
passtable_on(src, type)
ADD_TRAIT(src, TRAIT_PASSWINDOW, INNATE_TRAIT)
// Voidwalker lore is that radio's actually attracted them, so they should be able to listen to it
var/obj/item/radio/internal_radio = new /obj/item/radio(src)
@@ -281,7 +281,7 @@ GLOBAL_LIST_INIT(raptor_colors, init_raptor_colors())
else
user.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/raptor)
user.AddElement(/datum/element/forced_gravity, 0)
passtable_on(user, REF(src))
ADD_TRAIT(user, TRAIT_PASSTABLE, REF(src))
to_chat(user, span_notice("You begin gently hovering above ground as [held_mob] on your back starts furiously flapping [held_mob.p_their()] wings[struggling ? ", struggling to keep you up in the air" : ""]!"))
user.set_resting(FALSE, TRUE)
user.refresh_gravity()
@@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(raptor_colors, init_raptor_colors())
user.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/raptor/slow)
user.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/raptor)
user.RemoveElement(/datum/element/forced_gravity, 0)
passtable_off(user, REF(src))
REMOVE_TRAIT(user, TRAIT_PASSTABLE, REF(src))
to_chat(user, span_notice("You settle gently back onto the ground[struggling ? ", [held_mob] on your back breathing out a sigh of releif" : ""]..."))
user.refresh_gravity()
STOP_PROCESSING(SSprocessing, src)
@@ -2039,20 +2039,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(needs_update && !(hooman.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS))
hooman.update_body_parts()
/**
* Calculates the expected height values for this species
*
* Return a height value corresponding to a specific height filter
* Return null to just use the mob's base height
*/
/datum/species/proc/update_species_heights(mob/living/carbon/human/holder)
if(HAS_TRAIT(holder, TRAIT_DWARF))
return HUMAN_HEIGHT_DWARF
if(HAS_TRAIT(holder, TRAIT_TOO_TALL))
return HUMAN_HEIGHT_TALLEST
return null
/**
@@ -283,7 +283,8 @@
*/
/mob/living/carbon/human/proc/update_mob_height()
var/old_height = mob_height
mob_height = dna?.species?.update_species_heights(src) || base_mob_height
var/obj/item/bodypart/chest/chest = get_bodypart(BODY_ZONE_CHEST)
mob_height = chest?.update_mob_heights(src) || base_mob_height
if(old_height != mob_height)
regenerate_icons()
readjust_atom_huds()
@@ -23,9 +23,9 @@
update_mob_height()
// Toggle passtable
if(HAS_TRAIT(src, TRAIT_DWARF))
passtable_on(src, TRAIT_DWARF)
ADD_TRAIT(src, TRAIT_PASSTABLE, TRAIT_DWARF)
else
passtable_off(src, TRAIT_DWARF)
REMOVE_TRAIT(src, TRAIT_PASSTABLE, TRAIT_DWARF)
/// Gaining or losing [TRAIT_TOO_TALL] updates our height
/mob/living/carbon/human/proc/on_tootall_trait(datum/source)
@@ -12,12 +12,9 @@
meat = /obj/item/food/meat/slab/monkey
knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/carbon/monkey = 1)
inherent_traits = list(
TRAIT_NO_AUGMENTS,
TRAIT_NO_BLOOD_OVERLAY,
TRAIT_NO_DNA_COPY,
TRAIT_NO_UNDERWEAR,
TRAIT_VENTCRAWLER_NUDE,
TRAIT_WEAK_SOUL,
)
no_equip_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_GLOVES | ITEM_SLOT_FEET | ITEM_SLOT_SUITSTORE
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN | SLIME_EXTRACT
@@ -44,26 +41,11 @@
. = ..()
if (pref_load)
ADD_TRAIT(human_who_gained_species, TRAIT_BORN_MONKEY, INNATE_TRAIT) // Not a species trait, you cannot escape your genetic destiny
passtable_on(human_who_gained_species, SPECIES_TRAIT)
human_who_gained_species.dna.add_mutation(/datum/mutation/race, MUTATION_SOURCE_ACTIVATED)
human_who_gained_species.AddElement(/datum/element/human_biter)
human_who_gained_species.update_mob_height()
/datum/species/monkey/on_species_loss(mob/living/carbon/human/C)
. = ..()
passtable_off(C, SPECIES_TRAIT)
C.dna.remove_mutation(/datum/mutation/race, MUTATION_SOURCE_ACTIVATED)
C.RemoveElement(/datum/element/human_biter)
C.update_mob_height()
/datum/species/monkey/update_species_heights(mob/living/carbon/human/holder)
if(HAS_TRAIT(holder, TRAIT_DWARF))
return MONKEY_HEIGHT_DWARF
if(HAS_TRAIT(holder, TRAIT_TOO_TALL))
return MONKEY_HEIGHT_TALL
return MONKEY_HEIGHT_MEDIUM
/datum/species/monkey/check_roundstart_eligible()
// STOP ADDING MONKEY SUBTYPES YOU HEATHEN
@@ -136,7 +118,7 @@
/obj/item/organ/brain/primate //Ook Ook
name = "Primate Brain"
desc = "This wad of meat is small, but has enlarged occipital lobes for spotting bananas."
organ_traits = list(TRAIT_CAN_STRIP, TRAIT_PRIMITIVE, TRAIT_GUN_NATURAL) // No literacy or advanced tool usage.
organ_traits = list(TRAIT_CAN_STRIP, TRAIT_PRIMITIVE, TRAIT_GUN_NATURAL, TRAIT_WEAK_SOUL) // No literacy or advanced tool usage.
actions_types = list(/datum/action/item_action/organ_action/toggle_trip)
/// Will this monkey stumble if they are crossed by a simple mob or a carbon in combat mode? Toggable by monkeys with clients, and is messed automatically set to true by monkey AI.
var/tripping = TRUE
@@ -164,10 +146,12 @@
/obj/item/organ/brain/primate/on_mob_insert(mob/living/carbon/primate)
. = ..()
RegisterSignal(primate, COMSIG_LIVING_MOB_BUMPED, PROC_REF(on_mob_bump))
primate.AddElement(/datum/element/human_biter)
/obj/item/organ/brain/primate/on_mob_remove(mob/living/carbon/primate)
. = ..()
UnregisterSignal(primate, COMSIG_LIVING_MOB_BUMPED)
primate.RemoveElement(/datum/element/human_biter)
/obj/item/organ/brain/primate/proc/on_mob_bump(mob/source, mob/living/crossing_mob)
SIGNAL_HANDLER
+19
View File
@@ -79,6 +79,9 @@
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_MIND_TEMPORARILY_GONE), PROC_REF(on_mind_temporarily_gone_trait_gain))
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_MIND_TEMPORARILY_GONE), PROC_REF(on_mind_temporarily_gone_trait_loss))
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_PASSTABLE), SIGNAL_REMOVETRAIT(TRAIT_PASSTABLE)), PROC_REF(on_passtable_trait_toggled))
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_PASSWINDOW), SIGNAL_REMOVETRAIT(TRAIT_PASSWINDOW)), PROC_REF(on_passwindow_trait_toggled))
/// Called when [TRAIT_KNOCKEDOUT] is added to the mob.
/mob/living/proc/on_knockedout_trait_gain(datum/source)
SIGNAL_HANDLER
@@ -341,3 +344,19 @@
/mob/living/proc/on_mind_temporarily_gone_trait_loss(datum/source)
SIGNAL_HANDLER
med_hud_set_status()
/// Called when [TRAIT_PASSTABLE] is added/removed to/from the mob.
/mob/living/proc/on_passtable_trait_toggled(datum/source)
SIGNAL_HANDLER
if(HAS_TRAIT(src, TRAIT_PASSTABLE))
pass_flags |= PASSTABLE
else
pass_flags &= ~PASSTABLE
/// Called when [TRAIT_PASSWINDOW] is added/removed to/from the mob.
/mob/living/proc/on_passwindow_trait_toggled(datum/source)
SIGNAL_HANDLER
if(HAS_TRAIT(src, TRAIT_PASSWINDOW))
pass_flags |= PASSWINDOW
else
pass_flags &= ~PASSWINDOW
+2 -2
View File
@@ -341,7 +341,7 @@
RegisterSignal(mod.wearer, COMSIG_MOB_SAY, PROC_REF(on_talk))
RegisterSignal(mod.wearer, COMSIG_MOVABLE_PREBUCKLE, PROC_REF(on_someone_buckled))
ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src))
passtable_on(mod.wearer, REF(src))
ADD_TRAIT(mod.wearer, TRAIT_PASSTABLE, REF(src))
check_upstairs() //todo at some point flip your screen around
/obj/item/mod/module/atrocinator/deactivate(mob/activator, display_message = TRUE, deleting = FALSE)
@@ -359,7 +359,7 @@
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_PREBUCKLE)
step_count = 0
REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, REF(src))
passtable_off(mod.wearer, REF(src))
REMOVE_TRAIT(mod.wearer, TRAIT_PASSTABLE, REF(src))
var/turf/open/openspace/current_turf = get_turf(mod.wearer)
if(istype(current_turf))
current_turf.zFall(mod.wearer, falling_from_move = TRUE)
@@ -38,6 +38,12 @@
/// Which functional (i.e. flightpotion) wing types (if any) does this bodypart support? If count is >1 a radial menu is used to choose between all icons in list
var/list/wing_types = list(/obj/item/organ/wings/functional/angel)
/obj/item/bodypart/chest/apply_ownership(mob/living/carbon/new_owner)
. = ..()
if(ishuman(new_owner))
var/mob/living/carbon/human/humie = new_owner
humie.update_mob_height()
/obj/item/bodypart/chest/get_butcher_drops(force = FALSE)
. = ..()
if(!isnull(butcher_drops) && !force)
@@ -67,6 +73,21 @@
return FALSE
return ..()
/**
* Calculates the expected height values for the holder of this bodypart
*
* Return a height value corresponding to a specific height filter
* Return null to just use the mob's base height
*/
/obj/item/bodypart/chest/proc/update_mob_heights(mob/living/carbon/holder)
if(HAS_TRAIT(holder, TRAIT_DWARF))
return HUMAN_HEIGHT_DWARF
if(HAS_TRAIT(holder, TRAIT_TOO_TALL))
return HUMAN_HEIGHT_TALLEST
return null
/obj/item/bodypart/chest/Destroy()
QDEL_NULL(cavity_item)
QDEL_NULL(worn_uniform_offset)
@@ -37,6 +37,12 @@
bodyshape = BODYSHAPE_MONKEY
acceptable_bodyshape = BODYSHAPE_MONKEY
dmg_overlay_type = SPECIES_MONKEY
bodypart_traits = list(
TRAIT_PASSTABLE,
TRAIT_VENTCRAWLER_NUDE,
TRAIT_NO_AUGMENTS,
TRAIT_NO_UNDERWEAR,
)
/obj/item/bodypart/chest/monkey/Initialize(mapload)
worn_neck_offset = new(
@@ -46,6 +52,15 @@
)
return ..()
/obj/item/bodypart/chest/monkey/update_mob_heights(mob/living/carbon/holder)
if(HAS_TRAIT(holder, TRAIT_DWARF))
return MONKEY_HEIGHT_DWARF
if(HAS_TRAIT(holder, TRAIT_TOO_TALL))
return MONKEY_HEIGHT_TALL
return MONKEY_HEIGHT_MEDIUM
/obj/item/bodypart/arm/left/monkey
icon = 'icons/mob/human/species/monkey/bodyparts.dmi'
icon_static = 'icons/mob/human/species/monkey/bodyparts.dmi'
@@ -124,7 +124,7 @@
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)
ADD_TRAIT(human, TRAIT_PASSTABLE, 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)
@@ -135,7 +135,7 @@
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)
REMOVE_TRAIT(human, TRAIT_PASSTABLE, SPECIES_FLIGHT_TRAIT)
to_chat(human, span_notice("You settle gently back onto the ground..."))
close_wings()
human.refresh_gravity()
+2 -2
View File
@@ -105,11 +105,11 @@
if(is_portable)
interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
passtable_on(src, type)
pass_flags |= PASSTABLE
RemoveElement(/datum/element/noisy_movement)
else
interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
passtable_off(src, type)
pass_flags &= ~PASSTABLE
AddElement(/datum/element/noisy_movement)
update_appearance()
+4 -4
View File
@@ -387,11 +387,11 @@
animate(vehicle, pixel_z = 6, time = 0.3 SECONDS, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_z = -6, time = 0.1 SECONDS, flags = ANIMATION_RELATIVE)
playsound(vehicle, 'sound/vehicles/skateboard_ollie.ogg', 50, TRUE)
passtable_on(rider, VEHICLE_TRAIT)
passtable_on(vehicle, VEHICLE_TRAIT)
ADD_TRAIT(rider, TRAIT_PASSTABLE, VEHICLE_TRAIT)
vehicle.pass_flags |= PASSTABLE
rider.Move(landing_turf, vehicle_target.dir)
passtable_off(rider, VEHICLE_TRAIT)
passtable_off(vehicle, VEHICLE_TRAIT)
REMOVE_TRAIT(rider, TRAIT_PASSTABLE, VEHICLE_TRAIT)
vehicle.pass_flags &= ~PASSTABLE
/datum/action/vehicle/ridden/scooter/skateboard/kickflip
name = "Kickflip"