diff --git a/code/__defines/species_traits.dm b/code/__defines/species_traits.dm new file mode 100644 index 0000000000..8b44872b4e --- /dev/null +++ b/code/__defines/species_traits.dm @@ -0,0 +1,6 @@ +//////flag defines specifically for species traits + +//touch reaction flags + +#define SPECIES_TRAIT_PATTING_DEFENCE 1 +#define SPECIES_TRAIT_PERSONAL_BUBBLE 2 diff --git a/code/game/objects/items/devices/communicator/cartridge.dm b/code/game/objects/items/devices/communicator/cartridge.dm index 77b049e627..5910b76849 100644 --- a/code/game/objects/items/devices/communicator/cartridge.dm +++ b/code/game/objects/items/devices/communicator/cartridge.dm @@ -375,11 +375,12 @@ icon_state = "cart-e" ui_templates = list(list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl")) -/obj/item/commcard/engineering/New() +/obj/item/commcard/engineering/Initialize(mapload) ..() internal_devices |= new /obj/item/halogen_counter(src) + return INITIALIZE_HINT_LATELOAD -/obj/item/commcard/engineering/Initialize(mapload) +/obj/item/commcard/engineering/LateInitialize() . = ..() internal_data["grid_sensors"] = find_powernet_sensors() internal_data["powernet_target"] = "" @@ -789,12 +790,13 @@ list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl") ) -/obj/item/commcard/head/ce/New() +/obj/item/commcard/head/ce/Initialize(mapload) ..() internal_devices |= new /obj.item/analyzer(src) internal_devices |= new /obj/item/halogen_counter(src) + return INITIALIZE_HINT_LATELOAD -/obj/item/commcard/head/ce/Initialize(mapload) +/obj/item/commcard/head/ce/LateInitialize() . = ..() internal_data["grid_sensors"] = find_powernet_sensors() internal_data["powernet_target"] = "" diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index c9e6189c58..e328f2b868 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -489,19 +489,44 @@ t_him = "him" if(FEMALE) t_him = "her" + + if(target.touch_reaction_flags & SPECIES_TRAIT_PERSONAL_BUBBLE) + H.visible_message( \ + span_notice("[target] moves to avoid being touched by [H]!"), \ + span_notice("[target] moves to avoid being touched by you!"), ) + return + //VOREStation Edit Start - Headpats and Handshakes. if(H.zone_sel.selecting == "head") - H.visible_message( \ - span_notice("[H] pats [target] on the head."), \ - span_notice("You pat [target] on the head."), ) + if(target.touch_reaction_flags & SPECIES_TRAIT_PATTING_DEFENCE) + H.visible_message( \ + span_warning("[target] reflexively bites the hand of [H] to prevent head patting!"), \ + span_warning("[target] reflexively bites your hand!"), ) + if(H.hand) + H.apply_damage(1, BRUTE, BP_L_HAND) + else + H.apply_damage(1, BRUTE, BP_R_HAND) + else + H.visible_message( \ + span_notice("[H] pats [target] on the head."), \ + span_notice("You pat [target] on the head."), ) else if(H.zone_sel.selecting == "r_hand" || H.zone_sel.selecting == "l_hand") H.visible_message( \ span_notice("[H] shakes [target]'s hand."), \ span_notice("You shake [target]'s hand."), ) else if(H.zone_sel.selecting == "mouth") - H.visible_message( \ - span_notice("[H] boops [target]'s nose."), \ - span_notice("You boop [target] on the nose."), ) + if(target.touch_reaction_flags & SPECIES_TRAIT_PATTING_DEFENCE) + H.visible_message( \ + span_warning("[target] reflexively bites the hand of [H] to prevent nose booping!"), \ + span_warning("[target] reflexively bites your hand!"), ) + if(H.hand) + H.apply_damage(1, BRUTE, BP_L_HAND) + else + H.apply_damage(1, BRUTE, BP_R_HAND) + else + H.visible_message( \ + span_notice("[H] boops [target]'s nose."), \ + span_notice("You boop [target] on the nose."), ) else if(H.zone_sel.selecting == BP_GROIN) //CHOMPEdit H.vore_bellyrub(target) //VOREStation Edit End diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index b89ef58164..ef7e86ccce 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -1418,3 +1418,25 @@ cost = 0 var_changes = list("mudking" = TRUE) custom_only = FALSE + +/datum/trait/neutral/patting_defence + name = "Reflexive Biting" + desc = "You will reflexively bite hands that attempt to pat your head or boop your nose, this can be toggled off." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/patting_defence/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.touch_reaction_flags |= SPECIES_TRAIT_PATTING_DEFENCE + add_verb(H, /mob/living/proc/toggle_patting_defence) + +/datum/trait/neutral/personal_space + name = "Personal Space Bubble" + desc = "You are adept at avoiding unwanted physical contact and dodge it with ease. You will reflexively dodge any attempt to hug, pat, boop, lick, sniff you or even shake your hand, this can be toggled off." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/patting_defence/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..() + H.touch_reaction_flags |= SPECIES_TRAIT_PERSONAL_BUBBLE + add_verb(H, /mob/living/proc/toggle_personal_space) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index db9a065e46..de04366b18 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -105,3 +105,5 @@ "'s hands are shaking.", " is rocking slightly from side to side." ) + + var/touch_reaction_flags diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index 2ff8857c0a..f36e5b2b18 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -31,6 +31,30 @@ to_chat(src, span_notice("You will [allow_self_surgery ? "now" : "no longer"] attempt to operate upon yourself.")) log_admin("DEBUG \[[world.timeofday]\]: [src.ckey ? "[src.name]:([src.ckey])" : "[src.name]"] has [allow_self_surgery ? "Enabled" : "Disabled"] self surgery.") +/mob/living/proc/toggle_patting_defence() + set name = "Toggle Reflexive Biting" + set desc = "Toggles the automatic biting for if someone pats you on the head or boops your nose." + set category = "Abilities.General" + + if(touch_reaction_flags & SPECIES_TRAIT_PATTING_DEFENCE) + touch_reaction_flags &= ~(SPECIES_TRAIT_PATTING_DEFENCE) + to_chat(src,span_notice("You will no longer bite hands who pat or boop you.")) + else + touch_reaction_flags |= SPECIES_TRAIT_PATTING_DEFENCE + to_chat(src,span_notice("You will now longer bite hands who pat or boop you.")) + +/mob/living/proc/toggle_personal_space() + set name = "Toggle Personal Space" + set desc = "Toggles dodging any attempts to hug or pat you." + set category = "Abilities.General" + + if(touch_reaction_flags & SPECIES_TRAIT_PERSONAL_BUBBLE) + touch_reaction_flags &= ~(SPECIES_TRAIT_PERSONAL_BUBBLE) + to_chat(src,span_notice("You will no longer dodge all attempts at hugging, patting, booping, licking, smelling and hand shaking.")) + else + touch_reaction_flags |= SPECIES_TRAIT_PERSONAL_BUBBLE + to_chat(src,span_notice("You will now dodge all attempts at hugging, patting, booping, licking, smelling and hand shaking.")) + //ChompEDIT START - re-assert our layer and plane /mob/living/Moved(var/atom/oldloc, direct, forced, movetime) . = ..() diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 2148c78b33..2376f3de59 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -530,15 +530,17 @@ return setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(tasted == src) visible_message(span_vwarning("[src] licks themself!"),span_notice("You lick yourself. You taste rather like [tasted.get_taste_message()]."),span_infoplain(span_bold("Slurp!"))) //balloon_alert_visible("licks themself!", "tastes like [tasted.get_taste_message()]") else + if((tasted.touch_reaction_flags & SPECIES_TRAIT_PERSONAL_BUBBLE) && (!tasted.grabbed_by.len || !tasted.stat)) + visible_message(span_warning("[src] tries to lick [tasted], but they dodge out of the way!"),span_warning("You try to lick [tasted], but they deftly avoid your attempt.")) + return visible_message(span_vwarning("[src] licks [tasted]!"),span_notice("You lick [tasted]. They taste rather like [tasted.get_taste_message()]."),span_infoplain(span_bold("Slurp!"))) //balloon_alert_visible("licks [tasted]!", "tastes like [tasted.get_taste_message()]") - - /mob/living/proc/get_taste_message(allow_generic = 1) if(!vore_taste && !allow_generic) return FALSE @@ -575,14 +577,17 @@ return setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(smelled == src) visible_message(span_vwarning("[src] smells themself!"),span_notice("You smell yourself. You smell like [smelled.get_smell_message()]."),span_infoplain(span_bold("Sniff!"))) //balloon_alert_visible("smells themself!", "smells like [smelled.get_smell_message()]") else + if((smelled.touch_reaction_flags & SPECIES_TRAIT_PERSONAL_BUBBLE) && (!smelled.grabbed_by.len || !smelled.stat)) + visible_message(span_warning("[src] tries to smell [smelled], but they dodge out of the way!"),span_warning("You try to smell [smelled], but they deftly avoid your attempt.")) + return visible_message(span_vwarning("[src] smells [smelled]!"),span_notice("You smell [smelled]. They smell like [smelled.get_smell_message()]."),span_infoplain(span_bold("Sniff!"))) //balloon_alert_visible("smells [smelled]!", "smells like [smelled.get_smell_message()]") - /mob/living/proc/get_smell_message(allow_generic = 1) if(!vore_smell && !allow_generic) return FALSE diff --git a/vorestation.dme b/vorestation.dme index 59eecebb20..f81e254166 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -151,6 +151,7 @@ #include "code\__defines\species_languages.dm" #include "code\__defines\species_languages_vr.dm" #include "code\__defines\species_languages_YW.dm" +#include "code\__defines\species_traits.dm" #include "code\__defines\speech_channels.dm" #include "code\__defines\spells.dm" #include "code\__defines\sprite_sheets.dm"