diff --git a/code/__DEFINES/quirks.dm b/code/__DEFINES/quirks.dm new file mode 100644 index 00000000000..290fed93c95 --- /dev/null +++ b/code/__DEFINES/quirks.dm @@ -0,0 +1,14 @@ +//Medical Categories for quirks +#define CAT_QUIRK_ALL 0 +#define CAT_QUIRK_NOTES 1 +#define CAT_QUIRK_MINOR_DISABILITY 2 +#define CAT_QUIRK_MAJOR_DISABILITY 3 + +/// This quirk can only be applied to humans +#define QUIRK_HUMAN_ONLY (1<<0) +/// This quirk processes on SSquirks (and should implement quirk process) +#define QUIRK_PROCESSES (1<<1) +/// This quirk is has a visual aspect in that it changes how the player looks. Used in generating dummies. +#define QUIRK_CHANGES_APPEARANCE (1<<2) +/// The only thing this quirk effects is mood so it should be disabled if mood is +#define QUIRK_MOODLET_BASED (1<<3) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 1fa4f4909ff..7e1c8a7d862 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -692,12 +692,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Echolocation has a higher range. #define TRAIT_ECHOLOCATION_EXTRA_RANGE "echolocation_extra_range" -//Medical Categories for quirks -#define CAT_QUIRK_ALL 0 -#define CAT_QUIRK_NOTES 1 -#define CAT_QUIRK_MINOR_DISABILITY 2 -#define CAT_QUIRK_MAJOR_DISABILITY 3 - // common trait sources #define TRAIT_GENERIC "generic" #define UNCONSCIOUS_TRAIT "unconscious" diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index cd75412aec5..d5bb0effa59 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -76,19 +76,19 @@ PROCESSING_SUBSYSTEM_DEF(quirks) continue hardcore_quirks[quirk_type] += hardcore_value -/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli) +/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/applied_client) var/badquirk = FALSE - for(var/quirk_name in cli.prefs.all_quirks) - var/datum/quirk/Q = quirks[quirk_name] - if(Q) - if(user.add_quirk(Q)) + for(var/quirk_name in applied_client.prefs.all_quirks) + var/datum/quirk/quirk_type = quirks[quirk_name] + if(ispath(quirk_type)) + if(user.add_quirk(quirk_type, override_client = applied_client)) SSblackbox.record_feedback("nested tally", "quirks_taken", 1, list("[quirk_name]")) else - stack_trace("Invalid quirk \"[quirk_name]\" in client [cli.ckey] preferences") - cli.prefs.all_quirks -= quirk_name + stack_trace("Invalid quirk \"[quirk_name]\" in client [applied_client.ckey] preferences") + applied_client.prefs.all_quirks -= quirk_name badquirk = TRUE if(badquirk) - cli.prefs.save_character() + applied_client.prefs.save_character() /* *Randomises the quirks for a specified mob @@ -169,7 +169,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks) if (isnull(quirk)) continue - if (initial(quirk.mood_quirk) && CONFIG_GET(flag/disable_human_mood)) + if ((initial(quirk.quirk_flags) & QUIRK_MOODLET_BASED) && CONFIG_GET(flag/disable_human_mood)) continue var/blacklisted = FALSE diff --git a/code/datums/quirks/_quirk.dm b/code/datums/quirks/_quirk.dm index 1f24e1e3034..85885e62127 100644 --- a/code/datums/quirks/_quirk.dm +++ b/code/datums/quirks/_quirk.dm @@ -1,20 +1,29 @@ //every quirk in this folder should be coded around being applied on spawn //these are NOT "mob quirks" like GOTTAGOFAST, but exist as a medium to apply them and other different effects /datum/quirk + /// The name of the quirk var/name = "Test Quirk" + /// The description of the quirk var/desc = "This is a test quirk." + /// What the quirk is worth in preferences, zero = neutral / free var/value = 0 - var/human_only = TRUE - var/gain_text - var/lose_text - var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented - var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled - var/mob_trait //if applicable, apply and remove this mob trait - /// Amount of points this trait is worth towards the hardcore character mode; minus points implies a positive quirk, positive means its hard. This is used to pick the quirks assigned to a hardcore character. 0 means its not available to hardcore draws. - var/hardcore_value = 0 + /// Flags related to this quirk. + var/quirk_flags = QUIRK_HUMAN_ONLY + /// Reference to the mob currently tied to this quirk datum. Quirks are not singletons. var/mob/living/quirk_holder - /// This quirk should START_PROCESSING when added and STOP_PROCESSING when removed. - var/processing_quirk = FALSE + /// Text displayed when this quirk is assigned to a mob (and not transferred) + var/gain_text + /// Text displayed when this quirk is removed from a mob (and not transferred) + var/lose_text + ///This text will appear on medical records for the trait. + var/medical_record_text + /// if applicable, apply and remove this mob trait + var/mob_trait + /// Amount of points this trait is worth towards the hardcore character mode. + /// Minus points implies a positive quirk, positive means its hard. + /// This is used to pick the quirks assigned to a hardcore character. + //// 0 means its not available to hardcore draws. + var/hardcore_value = 0 /// When making an abstract quirk (in OOP terms), don't forget to set this var to the type path for that abstract quirk. var/abstract_parent_type = /datum/quirk /// The icon to show in the preferences menu. @@ -45,11 +54,11 @@ * * new_holder - The mob to add this quirk to. * * quirk_transfer - If this is being added to the holder as part of a quirk transfer. Quirks can use this to decide not to spawn new items or apply any other one-time effects. */ -/datum/quirk/proc/add_to_holder(mob/living/new_holder, quirk_transfer = FALSE) +/datum/quirk/proc/add_to_holder(mob/living/new_holder, quirk_transfer = FALSE, client/client_source) if(!new_holder) CRASH("Quirk attempted to be added to null mob.") - if(human_only && !ishuman(new_holder)) + if((quirk_flags & QUIRK_HUMAN_ONLY) && !ishuman(new_holder)) CRASH("Human only quirk attempted to be added to non-human mob.") if(new_holder.has_quirk(type)) @@ -60,19 +69,21 @@ quirk_holder = new_holder quirk_holder.quirks += src + // If we weren't passed a client source try to use a present one + client_source ||= quirk_holder.client if(mob_trait) ADD_TRAIT(quirk_holder, mob_trait, QUIRK_TRAIT) - add() + add(client_source) - if(processing_quirk) + if(quirk_flags & QUIRK_PROCESSES) START_PROCESSING(SSquirks, src) if(!quirk_transfer) if(gain_text) to_chat(quirk_holder, gain_text) - add_unique() + add_unique(client_source) if(quirk_holder.client) post_add() @@ -98,7 +109,7 @@ if(mob_trait) REMOVE_TRAIT(quirk_holder, mob_trait, QUIRK_TRAIT) - if(processing_quirk) + if(quirk_flags & QUIRK_PROCESSES) STOP_PROCESSING(SSquirks, src) remove() @@ -119,13 +130,23 @@ post_add() /// Any effect that should be applied every single time the quirk is added to any mob, even when transferred. -/datum/quirk/proc/add() -/// Any effects from the proc that should not be done multiple times if the quirk is transferred between mobs. Put stuff like spawning items in here. -/datum/quirk/proc/add_unique() +/datum/quirk/proc/add(client/client_source) + return + +/// Any effects from the proc that should not be done multiple times if the quirk is transferred between mobs. +/// Put stuff like spawning items in here. +/datum/quirk/proc/add_unique(client/client_source) + return + /// Removal of any reversible effects added by the quirk. /datum/quirk/proc/remove() -/// Any special effects or chat messages which should be applied. This proc is guaranteed to run if the mob has a client when the quirk is added. Otherwise, it runs once on the next COMSIG_MOB_LOGIN. + return + +/// Any special effects or chat messages which should be applied. +/// This proc is guaranteed to run if the mob has a client when the quirk is added. +/// Otherwise, it runs once on the next COMSIG_MOB_LOGIN. /datum/quirk/proc/post_add() + return /// Subtype quirk that has some bonus logic to spawn items for the player. /datum/quirk/item_quirk @@ -219,12 +240,13 @@ return medical ? "No issues have been declared." : "None" return medical ? dat.Join("
") : dat.Join(", ") -/mob/living/proc/cleanse_trait_datums() //removes all trait datums - for(var/V in quirks) - var/datum/quirk/T = V - qdel(T) +/mob/living/proc/cleanse_quirk_datums() //removes all trait datums + QDEL_LIST(quirks) + +/mob/living/proc/transfer_quirk_datums(mob/living/to_mob) + // We could be done before the client was moved or after the client was moved + var/datum/preferences/to_pass = client || to_mob.client -/mob/living/proc/transfer_trait_datums(mob/living/to_mob) for(var/datum/quirk/quirk as anything in quirks) quirk.remove_from_current_holder(quirk_transfer = TRUE) - quirk.add_to_holder(to_mob, quirk_transfer = TRUE) + quirk.add_to_holder(to_mob, quirk_transfer = TRUE, client_source = to_pass) diff --git a/code/datums/quirks/negative_quirks.dm b/code/datums/quirks/negative_quirks.dm index f51bb7bfff2..2ea1b41004d 100644 --- a/code/datums/quirks/negative_quirks.dm +++ b/code/datums/quirks/negative_quirks.dm @@ -5,7 +5,7 @@ desc = "Thanks to your poor posture, backpacks and other bags never sit right on your back. More evenly weighted objects are fine, though." icon = "hiking" value = -8 - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED gain_text = "Your back REALLY hurts!" lose_text = "Your back feels better." medical_record_text = "Patient scans indicate severe and chronic back pain." @@ -13,7 +13,7 @@ mail_goodies = list(/obj/item/cane) var/datum/weakref/backpack -/datum/quirk/badback/add() +/datum/quirk/badback/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/storage/backpack/equipped_backpack = human_holder.back if(istype(equipped_backpack)) @@ -60,7 +60,7 @@ lose_text = "You feel vigorous again." medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood." hardcore_value = 8 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/item/reagent_containers/blood/o_minus) // universal blood type that is safe for all var/min_blood = BLOOD_VOLUME_SAFE - 25 // just barely survivable without treatment var/drain_rate = 0.275 @@ -87,12 +87,13 @@ lose_text = "You miraculously gain back your vision." medical_record_text = "Patient has permanent blindness." hardcore_value = 15 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE mail_goodies = list(/obj/item/clothing/glasses/sunglasses, /obj/item/cane/white) -/datum/quirk/item_quirk/blindness/add_unique() +/datum/quirk/item_quirk/blindness/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/glasses/blindfold/white, list(LOCATION_EYES = ITEM_SLOT_EYES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) -/datum/quirk/item_quirk/blindness/add() +/datum/quirk/item_quirk/blindness/add(client/client_source) quirk_holder.become_blind(QUIRK_TRAIT) /datum/quirk/item_quirk/blindness/remove() @@ -112,10 +113,10 @@ lose_text = "You feel wrinkled again." medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death." hardcore_value = 12 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/item/storage/pill_bottle/mannitol/braintumor) -/datum/quirk/item_quirk/brainproblems/add_unique() +/datum/quirk/item_quirk/brainproblems/add_unique(client/client_source) give_item_to_holder( /obj/item/storage/pill_bottle/mannitol/braintumor, list( @@ -148,7 +149,7 @@ hardcore_value = 12 mail_goodies = list(/obj/item/clothing/mask/whistle) -/datum/quirk/item_quirk/deafness/add_unique() +/datum/quirk/item_quirk/deafness/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/accessory/deaf_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) /datum/quirk/depression @@ -160,7 +161,7 @@ gain_text = "You start feeling depressed." lose_text = "You no longer feel depressed." //if only it were that easy! medical_record_text = "Patient has a mild mood disorder causing them to experience acute episodes of depression." - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED hardcore_value = 2 mail_goodies = list(/obj/item/storage/pill_bottle/happinesspsych) @@ -169,15 +170,14 @@ desc = "You are the current owner of an heirloom, passed down for generations. You have to keep it safe!" icon = "toolbox" value = -2 - mood_quirk = TRUE medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom." hardcore_value = 1 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES|QUIRK_MOODLET_BASED /// A weak reference to our heirloom. var/datum/weakref/heirloom mail_goodies = list(/obj/item/storage/secure/briefcase) -/datum/quirk/item_quirk/family_heirloom/add_unique() +/datum/quirk/item_quirk/family_heirloom/add_unique(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/heirloom_type @@ -266,7 +266,7 @@ /obj/item/clothing/mask/luchador/tecnicos, ) -/datum/quirk/glass_jaw/add() +/datum/quirk/glass_jaw/add(client/client_source) RegisterSignal(quirk_holder, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(punch_out)) /datum/quirk/glass_jaw/remove() @@ -332,7 +332,7 @@ hardcore_value = 3 mail_goodies = list(/obj/effect/spawner/random/entertainment/plushie_delux) -/datum/quirk/hypersensitive/add() +/datum/quirk/hypersensitive/add(client/client_source) if (quirk_holder.mob_mood) quirk_holder.mob_mood.mood_modifier += 0.5 @@ -361,26 +361,29 @@ lose_text = "You start seeing faraway things normally again." medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness." hardcore_value = 5 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE mail_goodies = list(/obj/item/clothing/glasses/regular) // extra pair if orginal one gets broken by somebody mean - var/glasses -/datum/quirk/item_quirk/nearsighted/add_unique() - glasses = glasses || quirk_holder.client?.prefs?.read_preference(/datum/preference/choiced/glasses) - switch(glasses) +/datum/quirk/item_quirk/nearsighted/add_unique(client/client_source) + var/glasses_name = client_source?.prefs.read_preference(/datum/preference/choiced/glasses) || "Regular" + var/obj/item/clothing/glasses/glasses_type + switch(glasses_name) if ("Thin") - glasses = /obj/item/clothing/glasses/regular/thin + glasses_type = /obj/item/clothing/glasses/regular/thin if ("Circle") - glasses = /obj/item/clothing/glasses/regular/circle + glasses_type = /obj/item/clothing/glasses/regular/circle if ("Hipster") - glasses = /obj/item/clothing/glasses/regular/hipster - if ("Modern") - glasses = /obj/item/clothing/glasses/betterunshit + glasses_type = /obj/item/clothing/glasses/regular/hipster else - glasses = /obj/item/clothing/glasses/regular + glasses_type = /obj/item/clothing/glasses/regular - give_item_to_holder(glasses, list(LOCATION_EYES = ITEM_SLOT_EYES, LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) + give_item_to_holder(glasses_type, list( + LOCATION_EYES = ITEM_SLOT_EYES, + LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, + LOCATION_HANDS = ITEM_SLOT_HANDS, + )) -/datum/quirk/item_quirk/nearsighted/add() +/datum/quirk/item_quirk/nearsighted/add(client/client_source) quirk_holder.become_nearsighted(QUIRK_TRAIT) /datum/quirk/item_quirk/nearsighted/remove() @@ -395,7 +398,7 @@ hardcore_value = 5 mail_goodies = list(/obj/effect/spawner/random/engineering/flashlight) -/datum/quirk/nyctophobia/add() +/datum/quirk/nyctophobia/add(client/client_source) RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved)) /datum/quirk/nyctophobia/remove() @@ -450,14 +453,13 @@ desc = "Your legs do not function. Nothing will ever fix this. But hey, free wheelchair!" icon = "wheelchair" value = -12 - human_only = TRUE gain_text = null // Handled by trauma. lose_text = null medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities." hardcore_value = 15 mail_goodies = list(/obj/vehicle/ridden/wheelchair/motorized) //yes a fullsized unfolded motorized wheelchair does fit -/datum/quirk/paraplegic/add_unique() +/datum/quirk/paraplegic/add_unique(client/client_source) if(quirk_holder.buckled) // Handle late joins being buckled to arrival shuttle chairs. quirk_holder.buckled.unbuckle_mob(quirk_holder) @@ -465,7 +467,7 @@ var/obj/structure/chair/spawn_chair = locate() in holder_turf var/obj/vehicle/ridden/wheelchair/wheels - if(quirk_holder.client?.get_award_status(/datum/award/score/hardcore_random) >= 5000) //More than 5k score? you unlock the gamer wheelchair. + if(client_source?.get_award_status(/datum/award/score/hardcore_random) >= 5000) //More than 5k score? you unlock the gamer wheelchair. wheels = new /obj/vehicle/ridden/wheelchair/gold(holder_turf) else wheels = new(holder_turf) @@ -480,7 +482,7 @@ if(dropped_item.fingerprintslast == quirk_holder.ckey) quirk_holder.put_in_hands(dropped_item) -/datum/quirk/paraplegic/add() +/datum/quirk/paraplegic/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder human_holder.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic, TRAUMA_RESILIENCE_ABSOLUTE) @@ -516,9 +518,10 @@ var/slot_string = "limb" medical_record_text = "During physical examination, patient was found to have a prosthetic limb." hardcore_value = 3 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE mail_goodies = list(/obj/item/weldingtool/mini, /obj/item/stack/cable_coil/five) -/datum/quirk/prosthetic_limb/add_unique() +/datum/quirk/prosthetic_limb/add_unique(client/client_source) var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/bodypart/prosthetic @@ -548,8 +551,9 @@ value = -6 medical_record_text = "During physical examination, patient was found to have all prosthetic limbs." hardcore_value = 6 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE -/datum/quirk/quadruple_amputee/add_unique() +/datum/quirk/quadruple_amputee/add_unique(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/left/robot/surplus) human_holder.del_and_replace_bodypart(new /obj/item/bodypart/arm/right/robot/surplus) @@ -587,7 +591,7 @@ /// Weakref to the trauma we give out var/datum/weakref/added_trama_ref -/datum/quirk/insanity/add() +/datum/quirk/insanity/add(client/client_source) if(!iscarbon(quirk_holder)) return var/mob/living/carbon/carbon_quirk_holder = quirk_holder @@ -630,7 +634,7 @@ mail_goodies = list(/obj/item/storage/pill_bottle/psicodine) var/dumb_thing = TRUE -/datum/quirk/social_anxiety/add() +/datum/quirk/social_anxiety/add(client/client_source) RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, PROC_REF(eye_contact)) RegisterSignal(quirk_holder, COMSIG_MOB_EXAMINATE, PROC_REF(looks_at_floor)) RegisterSignal(quirk_holder, COMSIG_MOB_SAY, PROC_REF(handle_speech)) @@ -740,7 +744,7 @@ gain_text = "You suddenly feel the craving for drugs." medical_record_text = "Patient has a history of hard drugs." hardcore_value = 4 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/effect/spawner/random/contraband/narcotics) var/drug_list = list(/datum/reagent/drug/blastoff, /datum/reagent/drug/krokodil, /datum/reagent/medicine/morphine, /datum/reagent/drug/happiness, /datum/reagent/drug/methamphetamine) //List of possible IDs var/datum/reagent/reagent_type //!If this is defined, reagent_id will be unused and the defined reagent type will be instead. @@ -753,7 +757,7 @@ var/next_process = 0 //! ticker for processing var/drug_flavour_text = "Better hope you don't run out..." -/datum/quirk/item_quirk/junkie/add_unique() +/datum/quirk/item_quirk/junkie/add_unique(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder if(!reagent_type) @@ -893,13 +897,13 @@ lose_text = "You feel your immune system phase back into perfect shape." medical_record_text = "Patient's immune system responds violently to certain chemicals." hardcore_value = 3 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/item/reagent_containers/hypospray/medipen) // epinephrine medipen stops allergic reactions var/list/allergies = list() var/list/blacklist = list(/datum/reagent/medicine/c2,/datum/reagent/medicine/epinephrine,/datum/reagent/medicine/adminordrazine,/datum/reagent/medicine/omnizine/godblood,/datum/reagent/medicine/cordiolis_hepatico,/datum/reagent/medicine/synaphydramine,/datum/reagent/medicine/diphenhydramine) var/allergy_string -/datum/quirk/item_quirk/allergic/add_unique() +/datum/quirk/item_quirk/allergic/add_unique(client/client_source) var/list/chem_list = subtypesof(/datum/reagent/medicine) - blacklist var/list/allergy_chem_names = list() for(var/i in 0 to 5) @@ -956,11 +960,11 @@ gain_text = "You just want people to leave you alone." lose_text = "You could use a big hug." medical_record_text = "Patient has disdain for being touched. Potentially has undiagnosed haphephobia." - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED hardcore_value = 1 mail_goodies = list(/obj/item/reagent_containers/spray/pepper) // show me on the doll where the bad man touched you -/datum/quirk/bad_touch/add() +/datum/quirk/bad_touch/add(client/client_source) RegisterSignals(quirk_holder, list(COMSIG_LIVING_GET_PULLED, COMSIG_CARBON_HELP_ACT), PROC_REF(uncomfortable_touch)) /datum/quirk/bad_touch/remove() @@ -986,7 +990,7 @@ value = -4 medical_record_text = "Patient demonstrates a fear of tight spaces." hardcore_value = 5 - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/item/reagent_containers/syringe/convermol) // to help breathing /datum/quirk/claustrophobia/remove() @@ -1044,12 +1048,24 @@ hardcore_value = 8 mail_goodies = list(/obj/item/pai_card) // can read things for you + +/datum/quirk/mute + name = "Mute" + desc = "For some reason you are completely unable to speak." + icon = "volume-xmark" + value = -4 + mob_trait = TRAIT_MUTE + gain_text = span_danger("You find yourself unable to speak!") + lose_text = span_notice("You feel a growing strength in your vocal chords.") + medical_record_text = "The patient is unable to use their voice in any capacity." + hardcore_value = 4 + /datum/quirk/body_purist name = "Body Purist" desc = "You believe your body is a temple and its natural form is an embodiment of perfection. Accordingly, you despise the idea of ever augmenting it with unnatural parts, cybernetic, prosthetic, or anything like it." icon = "person-rays" value = -2 - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED gain_text = "You now begin to hate the idea of having cybernetic implants." lose_text = "Maybe cybernetics aren't so bad. You now feel okay with augmentations and prosthetics." medical_record_text = "This patient has disclosed an extreme hatred for unnatural bodyparts and augmentations." @@ -1057,7 +1073,7 @@ mail_goodies = list(/obj/item/paper/pamphlet/cybernetics) var/cybernetics_level = 0 -/datum/quirk/body_purist/add() +/datum/quirk/body_purist/add(client/client_source) check_cybernetics() RegisterSignal(quirk_holder, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_organ_gain)) RegisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_organ_lose)) @@ -1116,14 +1132,3 @@ if(!IS_ORGANIC_LIMB(old_limb)) cybernetics_level-- update_mood() - -/datum/quirk/mute - name = "Mute" - desc = "For some reason you are completely unable to speak." - icon = "volume-xmark" - value = -4 - mob_trait = TRAIT_MUTE - gain_text = span_danger("You find yourself unable to speak!") - lose_text = span_notice("You feel a growing strength in your vocal chords.") - medical_record_text = "The patient is unable to use their voice in any capacity." - hardcore_value = 4 diff --git a/code/datums/quirks/neutral_quirks.dm b/code/datums/quirks/neutral_quirks.dm index f8e944577e3..da9b0d307b6 100644 --- a/code/datums/quirks/neutral_quirks.dm +++ b/code/datums/quirks/neutral_quirks.dm @@ -44,7 +44,7 @@ medical_record_text = "Patient does not speak Galactic Common and may require an interpreter." mail_goodies = list(/obj/item/taperecorder) // for translation -/datum/quirk/foreigner/add() +/datum/quirk/foreigner/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder human_holder.add_blocked_language(/datum/language/common) if(ishumanbasic(human_holder)) @@ -66,7 +66,7 @@ medical_record_text = "Patient reports a vegetarian diet." mail_goodies = list(/obj/effect/spawner/random/food_or_drink/salad) -/datum/quirk/vegetarian/add() +/datum/quirk/vegetarian/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/datum/species/species = human_holder.dna.species species.liked_food &= ~MEAT @@ -109,7 +109,7 @@ medical_record_text = "Patient demonstrates a pathological love of pineapple." mail_goodies = list(/obj/item/food/pizzaslice/pineapple) -/datum/quirk/pineapple_liker/add() +/datum/quirk/pineapple_liker/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/datum/species/species = human_holder.dna.species species.liked_food |= PINEAPPLE @@ -141,7 +141,7 @@ /obj/item/food/pizzaslice/sassysage, ) -/datum/quirk/pineapple_hater/add() +/datum/quirk/pineapple_hater/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/datum/species/species = human_holder.dna.species species.disliked_food |= PINEAPPLE @@ -167,7 +167,7 @@ medical_record_text = "Patient demonstrates irregular nutrition preferences." mail_goodies = list(/obj/item/food/urinalcake, /obj/item/food/badrecipe) // Mhhhmmm yummy -/datum/quirk/deviant_tastes/add() +/datum/quirk/deviant_tastes/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/datum/species/species = human_holder.dna.species var/liked = species.liked_food @@ -192,36 +192,27 @@ name = "Heterochromatic" desc = "One of your eyes is a different color than the other!" icon = "eye-low-vision" // Ignore the icon name, its actually a fairly good representation of different color eyes + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE value = 0 mail_goodies = list(/obj/item/clothing/glasses/eyepatch) - var/color -/datum/quirk/heterochromatic/add() - color = color || quirk_holder.client?.prefs?.read_preference(/datum/preference/color/heterochromatic) +// Only your first eyes are heterochromatic +// If someone comes and says "well mr coder you can have DNA bound heterochromia so it's not unrealistic +// to allow all inserted replacement eyes to become heterochromatic or for it to transfer between mobs" +// Then just change this to [proc/add] I really don't care +/datum/quirk/heterochromatic/add_unique(client/client_source) + var/color = client_source?.prefs.read_preference(/datum/preference/color/heterochromatic) if(!color) return - link_to_holder() + apply_heterochromatic_eyes(color) -/datum/quirk/heterochromatic/post_add() - if(color) - return - - color = quirk_holder.client?.prefs?.read_preference(/datum/preference/color/heterochromatic) - if(!color) - return - - link_to_holder() - -/datum/quirk/heterochromatic/remove() - UnregisterSignal(quirk_holder, COMSIG_CARBON_LOSE_ORGAN) - -/datum/quirk/heterochromatic/proc/link_to_holder() +/// Applies the passed color to this mob's eyes +/datum/quirk/heterochromatic/proc/apply_heterochromatic_eyes(color) var/mob/living/carbon/human/human_holder = quirk_holder + var/was_not_hetero = !human_holder.eye_color_heterochromatic human_holder.eye_color_heterochromatic = TRUE human_holder.eye_color_right = color - // We set override to TRUE as link to holder will be called whenever the preference is applied, given this quirk exists on the mob - RegisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_eye_removal), override=TRUE) var/obj/item/organ/internal/eyes/eyes_of_the_holder = quirk_holder.getorgan(/obj/item/organ/internal/eyes) if(!eyes_of_the_holder) @@ -231,6 +222,15 @@ eyes_of_the_holder.old_eye_color_right = color eyes_of_the_holder.refresh() + if(was_not_hetero) + RegisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_eye_removal)) + +/datum/quirk/heterochromatic/remove() + var/mob/living/carbon/human/human_holder = quirk_holder + human_holder.eye_color_heterochromatic = FALSE + human_holder.eye_color_right = human_holder.eye_color_left + UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN) + /datum/quirk/heterochromatic/proc/check_eye_removal(datum/source, obj/item/organ/internal/eyes/removed) SIGNAL_HANDLER @@ -240,7 +240,7 @@ // Eyes were removed, remove heterochromia from the human holder and bid them adieu var/mob/living/carbon/human/human_holder = quirk_holder human_holder.eye_color_heterochromatic = FALSE - human_holder.eye_color_right = initial(human_holder.eye_color_right) + human_holder.eye_color_right = human_holder.eye_color_left UnregisterSignal(human_holder, COMSIG_CARBON_LOSE_ORGAN) /datum/quirk/monochromatic @@ -256,7 +256,7 @@ /obj/item/clothing/head/fedora/white, ) -/datum/quirk/monochromatic/add() +/datum/quirk/monochromatic/add(client/client_source) quirk_holder.add_client_colour(/datum/client_colour/monochrome) /datum/quirk/monochromatic/post_add() @@ -273,21 +273,16 @@ icon = "spider" value = 0 medical_record_text = "Patient has an irrational fear of something." - var/phobia mail_goodies = list(/obj/item/clothing/glasses/blindfold, /obj/item/storage/pill_bottle/psicodine) -/datum/quirk/phobia/add() - phobia = phobia || quirk_holder.client?.prefs?.read_preference(/datum/preference/choiced/phobia) - - if(phobia) - var/mob/living/carbon/human/human_holder = quirk_holder - human_holder.gain_trauma(new /datum/brain_trauma/mild/phobia(phobia), TRAUMA_RESILIENCE_ABSOLUTE) - -/datum/quirk/phobia/post_add() +// Phobia will follow you between transfers +/datum/quirk/phobia/add(client/client_source) + var/phobia = client_source?.prefs.read_preference(/datum/preference/choiced/phobia) if(!phobia) - var/mob/living/carbon/human/human_holder = quirk_holder - phobia = human_holder.client.prefs.read_preference(/datum/preference/choiced/phobia) - human_holder.gain_trauma(new /datum/brain_trauma/mild/phobia(phobia), TRAUMA_RESILIENCE_ABSOLUTE) + return + + var/mob/living/carbon/human/human_holder = quirk_holder + human_holder.gain_trauma(new /datum/brain_trauma/mild/phobia(phobia), TRAUMA_RESILIENCE_ABSOLUTE) /datum/quirk/phobia/remove() var/mob/living/carbon/human/human_holder = quirk_holder @@ -315,7 +310,7 @@ /// The user's starting hairstyle var/old_hair -/datum/quirk/item_quirk/bald/add() +/datum/quirk/item_quirk/bald/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder old_hair = human_holder.hairstyle human_holder.hairstyle = "Bald" @@ -323,7 +318,7 @@ RegisterSignal(human_holder, COMSIG_CARBON_EQUIP_HAT, PROC_REF(equip_hat)) RegisterSignal(human_holder, COMSIG_CARBON_UNEQUIP_HAT, PROC_REF(unequip_hat)) -/datum/quirk/item_quirk/bald/add_unique() +/datum/quirk/item_quirk/bald/add_unique(client/client_source) var/obj/item/clothing/head/wig/natural/baldie_wig = new(get_turf(quirk_holder)) if (old_hair == "Bald") @@ -369,7 +364,7 @@ medical_record_text = "Patient mentions photography as a stress-relieving hobby." mail_goodies = list(/obj/item/camera_film) -/datum/quirk/item_quirk/photographer/add_unique() +/datum/quirk/item_quirk/photographer/add_unique(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/storage/photo_album/personal/photo_album = new(get_turf(human_holder)) photo_album.persistence_id = "personal_[human_holder.last_mind?.key]" // this is a persistent album, the ID is tied to the account's key to avoid tampering @@ -397,7 +392,7 @@ medical_record_text = "Patient enjoys dyeing their hair with pretty colors." mail_goodies = list(/obj/item/dyespray) -/datum/quirk/item_quirk/colorist/add_unique() +/datum/quirk/item_quirk/colorist/add_unique(client/client_source) give_item_to_holder(/obj/item/dyespray, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) */ @@ -415,7 +410,7 @@ /// Timer for gaming withdrawal to kick in var/gaming_withdrawal_timer = TIMER_ID_NULL -/datum/quirk/gamer/add() +/datum/quirk/gamer/add(client/client_source) // Gamer diet var/mob/living/carbon/human/human_holder = quirk_holder var/datum/species/species = human_holder.dna.species @@ -438,7 +433,7 @@ UnregisterSignal(human_holder, COMSIG_MOB_LOST_VIDEOGAME) UnregisterSignal(human_holder, COMSIG_MOB_PLAYED_VIDEOGAME) -/datum/quirk/gamer/add_unique() +/datum/quirk/gamer/add_unique(client/client_source) // The gamer starts off quelled gaming_withdrawal_timer = addtimer(CALLBACK(src, PROC_REF(enter_withdrawal)), GAMING_WITHDRAWAL_TIME, TIMER_STOPPABLE) diff --git a/code/datums/quirks/positive_quirks.dm b/code/datums/quirks/positive_quirks.dm index 7e43c0e35b3..a0e29e32d97 100644 --- a/code/datums/quirks/positive_quirks.dm +++ b/code/datums/quirks/positive_quirks.dm @@ -17,17 +17,15 @@ desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess." icon = "meh" value = 4 - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED medical_record_text = "Patient was administered the Apathy Evaluation Scale but did not bother to complete it." mail_goodies = list(/obj/item/hourglass) -/datum/quirk/apathetic/add() - if (quirk_holder.mob_mood) - quirk_holder.mob_mood.mood_modifier -= 0.2 +/datum/quirk/apathetic/add(client/client_source) + quirk_holder.mob_mood?.mood_modifier -= 0.2 /datum/quirk/apathetic/remove() - if (quirk_holder.mob_mood) - quirk_holder.mob_mood.mood_modifier += 0.2 + quirk_holder.mob_mood?.mood_modifier += 0.2 /datum/quirk/drunkhealing name = "Drunken Resilience" @@ -37,7 +35,7 @@ gain_text = "You feel like a drink would do you good." lose_text = "You no longer feel like drinking would ease your pain." medical_record_text = "Patient has unusually efficient liver metabolism and can slowly regenerate wounds by drinking alcoholic beverages." - processing_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/effect/spawner/random/food_or_drink/booze) /datum/quirk/drunkhealing/process(delta_time) @@ -85,10 +83,10 @@ /obj/item/toy/figure/clown, ) -/datum/quirk/item_quirk/clown_enjoyer/add_unique() +/datum/quirk/item_quirk/clown_enjoyer/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/accessory/clown_enjoyer_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) -/datum/quirk/item_quirk/clown_enjoyer/add() +/datum/quirk/item_quirk/clown_enjoyer/add(client/client_source) var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] fan.show_to(quirk_holder) @@ -115,10 +113,10 @@ /obj/item/toy/crayon/spraycan/mimecan, ) -/datum/quirk/item_quirk/mime_fan/add_unique() +/datum/quirk/item_quirk/mime_fan/add_unique(client/client_source) give_item_to_holder(/obj/item/clothing/accessory/mime_fan_pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) -/datum/quirk/item_quirk/mime_fan/add() +/datum/quirk/item_quirk/mime_fan/add(client/client_source) var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN] fan.show_to(quirk_holder) @@ -141,7 +139,7 @@ mob_trait = TRAIT_FRIENDLY gain_text = "You want to hug someone." lose_text = "You no longer feel compelled to hug others." - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED medical_record_text = "Patient demonstrates low-inhibitions for physical contact and well-developed arms. Requesting another doctor take over this case." mail_goodies = list(/obj/item/storage/box/hug) @@ -151,7 +149,7 @@ icon = "grin" value = 4 mob_trait = TRAIT_JOLLY - mood_quirk = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_MOODLET_BASED medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest." mail_goodies = list(/obj/item/clothing/mask/joy) @@ -177,7 +175,7 @@ medical_record_text = "Patient brain scans show a highly-developed auditory pathway." mail_goodies = list(/obj/effect/spawner/random/entertainment/musical_instrument, /obj/item/instrument/piano_synth/headphones) -/datum/quirk/item_quirk/musician/add_unique() +/datum/quirk/item_quirk/musician/add_unique(client/client_source) give_item_to_holder(/obj/item/choice_beacon/music, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) /datum/quirk/night_vision @@ -195,7 +193,7 @@ /obj/item/skillchip/light_remover, ) -/datum/quirk/night_vision/add() +/datum/quirk/night_vision/add(client/client_source) refresh_quirk_holder_eyes() /datum/quirk/night_vision/remove() @@ -244,7 +242,7 @@ /obj/item/storage/fancy/candle_box, ) -/datum/quirk/item_quirk/spiritual/add_unique() +/datum/quirk/item_quirk/spiritual/add_unique(client/client_source) give_item_to_holder(/obj/item/storage/fancy/candle_box, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) give_item_to_holder(/obj/item/storage/box/matches, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) @@ -264,7 +262,7 @@ /obj/item/canvas/twentythree_twentythree ) -/datum/quirk/item_quirk/tagger/add_unique() +/datum/quirk/item_quirk/tagger/add_unique(client/client_source) give_item_to_holder(/obj/item/toy/crayon/spraycan, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) /datum/quirk/voracious @@ -282,9 +280,10 @@ desc = "You possess excellent communication skills in sign language." icon = "hands" value = 4 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE mail_goodies = list(/obj/item/clothing/gloves/radio) -/datum/quirk/item_quirk/signer/add_unique() +/datum/quirk/item_quirk/signer/add_unique(client/client_source) quirk_holder.AddComponent(/datum/component/sign_language) var/obj/item/clothing/gloves/gloves_type = /obj/item/clothing/gloves/radio if(isplasmaman(quirk_holder)) diff --git a/code/modules/client/preferences/heterochromatic.dm b/code/modules/client/preferences/heterochromatic.dm index 03753a290f5..38d0d646089 100644 --- a/code/modules/client/preferences/heterochromatic.dm +++ b/code/modules/client/preferences/heterochromatic.dm @@ -10,6 +10,5 @@ return "Heterochromatic" in preferences.all_quirks /datum/preference/color/heterochromatic/apply_to_human(mob/living/carbon/human/target, value) - for(var/datum/quirk/heterochromatic/hetero_quirk in target.quirks) - hetero_quirk.color = value - hetero_quirk.link_to_holder() + var/datum/quirk/heterochromatic/hetero_quirk = locate() in target.quirks + hetero_quirk?.apply_heterochromatic_eyes(value) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 55c7b4fd0dc..a16daec0b31 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -67,7 +67,7 @@ available_hardcore_quirks -= picked_quirk continue - if(initial(picked_quirk.mood_quirk) && CONFIG_GET(flag/disable_human_mood)) //check for moodlet quirks + if((initial(picked_quirk.quirk_flags) & QUIRK_MOODLET_BASED) && CONFIG_GET(flag/disable_human_mood)) //check for moodlet quirks available_hardcore_quirks -= picked_quirk continue @@ -106,5 +106,16 @@ mannequin.job = preview_job.title mannequin.dress_up_as_job(preview_job, TRUE) + // Apply visual quirks + // Yes we do it every time because it needs to be done after job gear + if(SSquirks?.initialized) + // And yes we need to clean all the quirk datums every time + mannequin.cleanse_quirk_datums() + for(var/quirk_name as anything in all_quirks) + var/datum/quirk/quirk_type = SSquirks.quirks[quirk_name] + if(!(initial(quirk_type.quirk_flags) & QUIRK_CHANGES_APPEARANCE)) + continue + mannequin.add_quirk(quirk_type, parent) + return mannequin.appearance */ diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 6d5f65a414e..1522b357421 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -297,7 +297,7 @@ var/datum/species/jelly/slime/spare_datum = spare.dna.species spare_datum.bodies = origin_datum.bodies - H.transfer_trait_datums(spare) + H.transfer_quirk_datums(spare) H.mind.transfer_to(spare) spare.visible_message("[H] distorts as a new body \ \"steps out\" of [H.p_them()].", @@ -443,7 +443,7 @@ span_notice("You stop moving this body...")) else to_chat(M.current, span_notice("You abandon this body...")) - M.current.transfer_trait_datums(dupe) + M.current.transfer_quirk_datums(dupe) M.transfer_to(dupe) dupe.visible_message("[dupe] blinks and looks \ around.", diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index c5af051f4ce..216bba9f836 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -483,15 +483,24 @@ priority_absorb_key["stuns_absorbed"] += amount return TRUE -/mob/living/proc/add_quirk(quirktype) //separate proc due to the way these ones are handled - if(HAS_TRAIT(src, quirktype)) - return - var/datum/quirk/quirk = quirktype - var/qname = initial(quirk.name) +/** + * Adds the passed quirk to the mob + * + * Arguments + * * quirktype - Quirk typepath to add to the mob + * * override_client - optional, allows a client to be passed to the quirks on add procs. + * If not passed, defaults to this mob's client. + * + * Returns TRUE on success, FALSE on failure (already has the quirk, etc) + */ +/mob/living/proc/add_quirk(datum/quirk/quirktype, client/override_client) + if(has_quirk(quirktype)) + return FALSE + var/qname = initial(quirktype.name) if(!SSquirks || !SSquirks.quirks[qname]) - return - quirk = new quirktype() - if(quirk.add_to_holder(src)) + return FALSE + var/datum/quirk/quirk = new quirktype() + if(quirk.add_to_holder(new_holder = src, client_source = override_client)) return TRUE qdel(quirk) return FALSE diff --git a/code/modules/mob_spawn/ghost_roles/golem_roles.dm b/code/modules/mob_spawn/ghost_roles/golem_roles.dm index 64d0280558e..7f703ac88fd 100644 --- a/code/modules/mob_spawn/ghost_roles/golem_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/golem_roles.dm @@ -89,7 +89,7 @@ H.visible_message(span_notice("A faint light leaves [H], moving to [src] and animating it!"),span_notice("You leave your old body behind, and transfer into [src]!")) show_flavor = FALSE var/mob/living/carbon/human/newgolem = create(newname = H.real_name) - H.transfer_trait_datums(newgolem) + H.transfer_quirk_datums(newgolem) H.mind.transfer_to(newgolem) H.death() return diff --git a/modular_skyrat/master_files/code/datums/quirks/negative.dm b/modular_skyrat/master_files/code/datums/quirks/negative.dm index 6f1cdc11ae9..08599ea2875 100644 --- a/modular_skyrat/master_files/code/datums/quirks/negative.dm +++ b/modular_skyrat/master_files/code/datums/quirks/negative.dm @@ -42,17 +42,18 @@ // If brainproblems is added to a synth, this detours to the brainproblems/synth quirk. // TODO: Add more brain-specific detours when PR #16105 is merged -/datum/quirk/item_quirk/brainproblems/add_to_holder(mob/living/new_holder, quirk_transfer) - if(!(issynthetic(new_holder) && (src.type == /datum/quirk/item_quirk/brainproblems))) +/datum/quirk/item_quirk/brainproblems/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source) + if(!issynthetic(new_holder) || type != /datum/quirk/item_quirk/brainproblems) // Defer to TG brainproblems if the character isn't robotic. return ..() + // TODO: Check brain type and detour to appropriate brainproblems quirk var/datum/quirk/item_quirk/brainproblems/synth/bp_synth = new qdel(src) - return bp_synth.add_to_holder(new_holder, quirk_transfer) + return bp_synth.add_to_holder(new_holder, quirk_transfer, client_source) // Synthetics get liquid_solder with Brain Tumor instead of mannitol. -/datum/quirk/item_quirk/brainproblems/synth/add_unique() +/datum/quirk/item_quirk/brainproblems/synth/add_unique(client/client_source) give_item_to_holder( /obj/item/storage/pill_bottle/liquid_solder/braintumor, list( @@ -76,10 +77,11 @@ hidden_quirk = TRUE // If blooddeficiency is added to a synth, this detours to the blooddeficiency/synth quirk. -/datum/quirk/blooddeficiency/add_to_holder(mob/living/new_holder, quirk_transfer) - if(!(issynthetic(new_holder) && (src.type == /datum/quirk/blooddeficiency))) +/datum/quirk/blooddeficiency/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source) + if(!issynthetic(new_holder) || type != /datum/quirk/blooddeficiency) // Defer to TG blooddeficiency if the character isn't robotic. return ..() + var/datum/quirk/blooddeficiency/synth/bd_synth = new qdel(src) return bd_synth.add_to_holder(new_holder, quirk_transfer) diff --git a/modular_skyrat/master_files/code/datums/quirks/neutral.dm b/modular_skyrat/master_files/code/datums/quirks/neutral.dm index efb84d5e292..ff7f149fa88 100644 --- a/modular_skyrat/master_files/code/datums/quirks/neutral.dm +++ b/modular_skyrat/master_files/code/datums/quirks/neutral.dm @@ -1,11 +1,12 @@ /datum/quirk/equipping abstract_parent_type = /datum/quirk/equipping + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE /// the items that will be equipped, formatted in the way of [item_path = list of slots it can be equipped to], will not equip over nodrop items var/list/items = list() /// the items that will be forcefully equipped, formatted in the way of [item_path = list of slots it can be equipped to], will equip over nodrop items var/list/forced_items = list() -/datum/quirk/equipping/add_unique() +/datum/quirk/equipping/add_unique(client/client_source) var/mob/living/carbon/carbon_holder = quirk_holder if (!items || !carbon_holder) return @@ -56,7 +57,7 @@ items = list(/obj/item/clothing/accessory/breathing = list(ITEM_SLOT_BACKPACK)) var/breath_type = "oxygen" -/datum/quirk/equipping/lungs/add() +/datum/quirk/equipping/lungs/add(client/client_source) var/mob/living/carbon/human/carbon_holder = quirk_holder if (!istype(carbon_holder) || !lungs_typepath) return diff --git a/modular_skyrat/master_files/code/datums/traits/neutral.dm b/modular_skyrat/master_files/code/datums/traits/neutral.dm index d5571e0b129..2810450f34f 100644 --- a/modular_skyrat/master_files/code/datums/traits/neutral.dm +++ b/modular_skyrat/master_files/code/datums/traits/neutral.dm @@ -36,14 +36,27 @@ name = "Pseudobulbar Affect" desc = "At random intervals, you suffer uncontrollable bursts of laughter." value = 0 + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES medical_record_text = "Patient suffers with sudden and uncontrollable bursts of laughter." var/pcooldown = 0 var/pcooldown_time = 60 SECONDS icon = "grin-squint-tears" -/datum/quirk/item_quirk/joker/add_unique() +/datum/quirk/item_quirk/joker/add_unique(client/client_source) give_item_to_holder(/obj/item/paper/joker, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) +/datum/quirk/item_quirk/joker/process() + if(pcooldown > world.time) + return + pcooldown = world.time + pcooldown_time + var/mob/living/carbon/human/user = quirk_holder + if(user && istype(user)) + if(user.stat == CONSCIOUS) + if(prob(20)) + user.emote("laugh") + addtimer(CALLBACK(user, /mob/proc/emote, "laugh"), 5 SECONDS) + addtimer(CALLBACK(user, /mob/proc/emote, "laugh"), 10 SECONDS) + /obj/item/paper/joker name = "disability card" icon = 'modular_skyrat/master_files/icons/obj/card.dmi' @@ -153,18 +166,6 @@ balloon_alert(user, "card flipped") -/datum/quirk/item_quirk/joker/process() - if(pcooldown > world.time) - return - pcooldown = world.time + pcooldown_time - var/mob/living/carbon/human/user = quirk_holder - if(user && istype(user)) - if(user.stat == CONSCIOUS) - if(prob(20)) - user.emote("laugh") - addtimer(CALLBACK(user, /mob/proc/emote, "laugh"), 5 SECONDS) - addtimer(CALLBACK(user, /mob/proc/emote, "laugh"), 10 SECONDS) - /datum/quirk/feline_aspect name = "Feline Traits" desc = "You happen to act like a feline, for whatever reason." @@ -181,7 +182,7 @@ value = 0 medical_record_text = "Patient was seen digging through the trash can. Keep an eye on them." -/datum/quirk/item_quirk/canine/add_unique() +/datum/quirk/item_quirk/canine/add_unique(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/organ/internal/tongue/old_tongue = human_holder.getorganslot(ORGAN_SLOT_TONGUE) old_tongue.Remove(human_holder) diff --git a/modular_skyrat/modules/hydra/code/neutral.dm b/modular_skyrat/modules/hydra/code/neutral.dm index 6da99e20ecb..7187c550fec 100644 --- a/modular_skyrat/modules/hydra/code/neutral.dm +++ b/modular_skyrat/modules/hydra/code/neutral.dm @@ -8,7 +8,7 @@ medical_record_text = "There are multiple heads and personalities affixed to one body." icon = "horse-head" -/datum/quirk/hydra/add() +/datum/quirk/hydra/add(client/client_source) var/mob/living/carbon/human/hydra = quirk_holder var/datum/action/innate/hydra/spell = new var/datum/action/innate/hydrareset/resetspell = new diff --git a/modular_skyrat/modules/oversized/code/oversized_quirk.dm b/modular_skyrat/modules/oversized/code/oversized_quirk.dm index 195b5c0222f..cf1dc995c39 100644 --- a/modular_skyrat/modules/oversized/code/oversized_quirk.dm +++ b/modular_skyrat/modules/oversized/code/oversized_quirk.dm @@ -13,8 +13,9 @@ mob_trait = TRAIT_OVERSIZED icon = "expand-arrows-alt" veteran_only = TRUE + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE -/datum/quirk/oversized/add() +/datum/quirk/oversized/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder human_holder.dna.features["body_size"] = 2 human_holder.maptext_height = 32 * human_holder.dna.features["body_size"] //Adjust runechat height diff --git a/tgstation.dme b/tgstation.dme index 30b368280f6..b9767fd0f49 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -157,6 +157,7 @@ #include "code\__DEFINES\profile.dm" #include "code\__DEFINES\projectiles.dm" #include "code\__DEFINES\qdel.dm" +#include "code\__DEFINES\quirks.dm" #include "code\__DEFINES\radiation.dm" #include "code\__DEFINES\radio.dm" #include "code\__DEFINES\reactions.dm"