diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 838b11542a..59123c1254 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -699,3 +699,33 @@ hear |= recursive_mob_check(A, hear, 3, 1, 0, 1) return hear +<<<<<<< HEAD +======= + +/proc/get_belly(var/atom/A) // return a belly we're in, one way or another; and if we aren't (or are too deep to comprehend being in belly), returns null + var/atom/loc_check = A.loc + var/recursion_level = 0 + while(loc_check && !isbelly(loc_check) && !isturf(loc_check)) + if(recursion_level > 7) // abstractly picked number, but basically means we tried going 8 levels up. Something is wrong if youre THAT deep anyway + break + loc_check = loc_check.loc + recursion_level++ + if(isbelly(loc_check)) + return loc_check + return null + +/proc/get_all_prey_recursive(var/mob/living/L, var/client_check = 1) // returns all prey inside the target as well all prey of target's prey, as well as all prey inside target's prey, etc. + var/list/result = list() + + if(!istype(L) || !(L.vore_organs) || !(L.vore_organs.len)) + return result + + for(var/obj/belly/B in L.vore_organs) + for(var/mob/living/P in B.contents) + if(istype(P)) + if(client_check && P.client) + result |= P + result |= get_all_prey_recursive(P, client_check) + + return result +>>>>>>> 71677c47a8... Merge pull request #15139 from Heroman3003/custom-subtle diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 8d5d8012a2..9b3dc91644 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -10,13 +10,11 @@ if(say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return - //VOREStation Addition Start if(forced_psay) pme(message) return - //VOREStation Addition End - message = sanitize_or_reflect(message,src) //VOREStation Edit - Reflect too-long messages (within reason) + message = sanitize_or_reflect(message,src) // Reflect too-long messages (within reason) if(!message) return @@ -26,7 +24,33 @@ else usr.emote_vr(message) +<<<<<<< HEAD /mob/proc/custom_emote_vr(var/m_type=1,var/message = null, var/distanced=FALSE) //This would normally go in emote.dm //CHOMPEdit: subtle-distance +======= +/mob/verb/me_verb_subtle_custom(message as message) // Literally same as above but with mode_selection set to true + set name = "Subtle (Custom)" + set category = "IC" + set desc = "Emote to nearby people, with ability to choose which specific portion of people you wish to target." + + if(say_disabled) //This is here to try to identify lag problems + to_chat(usr, "Speech is currently admin-disabled.") + return + if(forced_psay) + pme(message) + return + + message = sanitize_or_reflect(message,src) // Reflect too-long messages (within reason) + if(!message) + return + + set_typing_indicator(FALSE) + if(use_me) + usr.emote_vr("me",4,message,TRUE) + else + usr.emote_vr(message) + +/mob/proc/custom_emote_vr(var/m_type=1,var/message = null,var/mode_selection = FALSE) //This would normally go in emote.dm +>>>>>>> 71677c47a8... Merge pull request #15139 from Heroman3003/custom-subtle if(stat || !use_me && usr == src) to_chat(src, "You are unable to emote.") return @@ -40,6 +64,17 @@ var/muzzled = is_muzzled() if(m_type == 2 && muzzled) return + var/subtle_mode + if(mode_selection) + subtle_mode = tgui_input_list(src, "Select Custom Subtle Mode", "Custom Subtle Mode", list("Adjacent Turfs (Default)", "My Turf", "My Table", "Current Belly (Prey)", "Specific Belly (Pred)", "Specific Person")) + if(!subtle_mode) + if(mode_selection) + if(message) + to_chat(src, "Subtle mode not selected. Your input has not been sent, but preserved: [message]") + return + else + subtle_mode = "Adjacent Turfs (Default)" + var/input if(!message) input = sanitize_or_reflect(tgui_input_text(src,"Choose an emote to display."), src) @@ -49,6 +84,8 @@ if(input) log_subtle(message,src) message = "[src] [input]" + if(!(subtle_mode == "Adjacent Turfs (Default)")) + message = "(T) " + message else return @@ -56,9 +93,110 @@ var/undisplayed_message = "[src] does something too subtle for you to see." message = encode_html_emphasis(message) - var/list/vis = get_mobs_and_objs_in_view_fast(get_turf(src),1,2) //Turf, Range, and type 2 is emote - var/list/vis_mobs = vis["mobs"] - var/list/vis_objs = vis["objs"] + var/list/vis + var/list/vis_mobs + var/list/vis_objs + + switch(subtle_mode) + if("Adjacent Turfs (Default)") + vis = get_mobs_and_objs_in_view_fast(get_turf(src),1,2) + vis_mobs = vis["mobs"] + vis_objs = vis["objs"] + if("My Turf") + vis = get_mobs_and_objs_in_view_fast(get_turf(src),0,2) + vis_mobs = vis["mobs"] + vis_objs = vis["objs"] + if("My Table") + vis = get_mobs_and_objs_in_view_fast(get_turf(src),7,2) + vis_mobs = vis["mobs"] + vis_objs = vis["objs"] + var/list/tablelist = list() + var/list/newmoblist = list() + var/list/newobjlist = list() + for(var/obj/structure/table/T in range(src, 1)) + if(istype(T) && !(T in tablelist) && !istype(T, /obj/structure/table/rack) && !istype(T, /obj/structure/table/bench)) + tablelist |= T.get_all_connected_tables() + if(!(tablelist.len)) + to_chat(src, "No nearby tables detected. Your input has not been sent, but preserved: [input]") + return + for(var/obj/structure/table/T in tablelist) + for(var/mob/M in vis_mobs) + var/dist = get_dist(T, M) + if(dist >= 0 && dist <= 1) + newmoblist |= M + for(var/obj/O in vis_objs) + var/dist = get_dist(T, O) + if(dist >= 0 && dist <= 1) + newobjlist |= O + vis_mobs = newmoblist + vis_objs = newobjlist + if("Current Belly (Prey)") + var/obj/belly/B = get_belly(src) + if(!istype(B)) + to_chat(src, "You are currently not in the belly. Your input has not been sent, but preserved: [input]") + return + vis = get_mobs_and_objs_in_view_fast(get_turf(src),0,2) + vis_mobs = vis["mobs"] + vis_objs = vis["objs"] + for(var/mob/M in vis_mobs) // Clean out everyone NOT in our specific belly + if(M == B.owner) + continue + var/obj/belly/BB = get_belly(M) + if(!(istype(BB)) || !(BB == B)) + vis_mobs -= M + for(var/mob/M in vis_mobs) // Re-add anything in bellies of people in our belly + if(M == B.owner) + continue + vis_mobs |= get_all_prey_recursive(M, TRUE) + for(var/obj/O in vis_objs) // Clean out everyone NOT in our specific belly but for objs. No re-adding will happen there. Just don't be that deep and youre an obj anyway. + var/obj/belly/BB = get_belly(O) + if(!(istype(BB)) || !(BB == B)) + vis_objs -= O + if("Specific Belly (Pred)") + if(!isliving(src)) + to_chat(src, "You do not appear to be a living mob capable of having bellies. Your input has not been sent, but preserved: [input]") + return + var/mob/living/L = src + if(!(L.vore_organs) || !(L.vore_organs.len)) + to_chat(src, "You do not have any bellies. Your input has not been sent, but preserved: [input]") + return + var/obj/belly/B = tgui_input_list(src, "Which belly do you want to sent the subtle to?","Select Belly", L.vore_organs) + if(!B || !istype(B)) + to_chat(src, "You have not selected a valid belly. Your input has not been sent, but preserved: [input]") + return + vis = get_mobs_and_objs_in_view_fast(get_turf(src),0,2) + vis_mobs = vis["mobs"] + vis_objs = vis["objs"] + for(var/mob/M in vis_mobs) // Clean out everyone NOT in our specific belly + if(M == B.owner) + continue + var/obj/belly/BB = get_belly(M) + if(!(istype(BB)) || !(BB == B)) + vis_mobs -= M + for(var/mob/M in vis_mobs) // Re-add anything in bellies of people in our belly + if(M == B.owner) + continue + vis_mobs |= get_all_prey_recursive(M, TRUE) + for(var/obj/O in vis_objs) // Clean out everyone NOT in our specific belly but for objs. No re-adding will happen there. Just don't be that deep and youre an obj anyway. + var/obj/belly/BB = get_belly(O) + if(!(istype(BB)) || !(BB == B)) + vis_objs -= O + if("Specific Person") + vis = get_mobs_and_objs_in_view_fast(get_turf(src),1,2) + vis_mobs = vis["mobs"] + vis_objs = list() + vis_mobs -= src + for(var/mob/M in vis_mobs) // ghosts get ye gone + if(isobserver(M) || (M.stat == DEAD)) + vis_mobs -= M + if(!(vis_mobs.len)) + to_chat(src, "No valid targets found. Your input has not been sent, but preserved: [input]") + return + var/target = tgui_input_list(src, "Who do we send our message to?","Select Target", vis_mobs) + if(!(target)) + to_chat(src, "No target selected. Your input has not been sent, but preserved: [input]") + return + vis_mobs = list(target, src) //CHOMPEdit: subtle target selection var/all_targets_mobs = list() @@ -187,9 +325,9 @@ spawn(0) O.see_emote(src, message, 2) -/mob/proc/emote_vr(var/act, var/type, var/message) //This would normally go in say.dm +/mob/proc/emote_vr(var/act, var/type, var/message, var/mode_selection) //This would normally go in say.dm if(act == "me") - return custom_emote_vr(type, message) + return custom_emote_vr(type, message, mode_selection) #define MAX_HUGE_MESSAGE_LEN 8192 #define POST_DELIMITER_STR "\<\>" diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 9a71cbdba7..3e682a518d 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -417,6 +417,27 @@ var/list/table_icon_cache = list() if(carpeted) add_overlay("carpet_flip[type]") +/obj/structure/table/proc/get_all_connected_tables(var/list/connections) + if(!connections) + connections = list(src) + else + connections |= src + if(istype(src, /obj/structure/table/rack)) + return connections + + for(var/direction in cardinal) + var/turf/T = get_step(src, direction) + if(T) + var/obj/structure/table/nextT = locate(/obj/structure/table) in T + if(!nextT || !istype(nextT)) + continue + if(istype(nextT, /obj/structure/table/rack) || (istype(nextT, /obj/structure/table/bench) && !istype(src, /obj/structure/table/bench)) || (!istype(nextT, /obj/structure/table/bench) && istype(src, /obj/structure/table/bench))) + continue + if(!(nextT in connections)) + connections |= nextT.get_all_connected_tables(connections) + + return connections + #define CORNER_NONE 0 #define CORNER_COUNTERCLOCKWISE 1