diff --git a/.travis.yml b/.travis.yml index 72a40f36442..834475ca40e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: BYOND_MINOR="1517" MACRO_COUNT=0 GENDER_COUNT=6 - TO_WORLD_COUNT=207 + TO_WORLD_COUNT=206 FLYWAY_BUILD="5.2.4" NODE_VERSION=10 RUST_G_VERSION="0.4.2+a2" diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 766ed93b6b0..6e212907b47 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -25,10 +25,6 @@ Possible to do for anyone motivated enough: #define HOLOPAD_PASSIVE_POWER_USAGE 1 #define HOLOGRAM_POWER_USAGE 2 -#define RANGE_BASED 4 -#define AREA_BASED 6 - -var/const/HOLOPAD_MODE = RANGE_BASED /obj/machinery/hologram/holopad name = "\improper AI holopad" @@ -41,313 +37,277 @@ var/const/HOLOPAD_MODE = RANGE_BASED idle_power_usage = 5 use_power = 1 - var/list/mob/living/silicon/ai/masters = new() //List of AIs that use the holopad + var/holopad_id + + var/list/active_holograms var/last_request = 0 //to prevent request spam. ~Carn - var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating - var/hacked = 0 // if hacked the hologram doesn't display. It only gives audio feedback. + var/holo_range = 7 // Change to change how far the AI can move away from the holopad before deactivating - var/incoming_connection = 0 - var/mob/living/caller_id - var/obj/machinery/hologram/holopad/sourcepad - var/obj/machinery/hologram/holopad/targetpad - var/forced + var/incoming_connection = FALSE + var/established_connection = FALSE + var/obj/machinery/hologram/holopad/connected_pad + var/forced = FALSE + var/hacked = FALSE var/last_message -/obj/machinery/hologram/holopad/check_eye(mob/user) - if (user && user == caller_id) - return 0 - - return -1 - /obj/machinery/hologram/holopad/Initialize() . = ..() - desc = "It's a floor-mounted device for projecting holographic images. Its ID is '[loc.loc]'" + var/area/A = get_area(src) + holopad_id = A.name + desc += " Its ID is '[holopad_id]'" -/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests. +/obj/machinery/hologram/holopad/update_icon() + if(LAZYLEN(active_holograms) || connected_pad) + icon_state = "holopad1" + set_light(2) + else + icon_state = "holopad0" + set_light(0) + +/obj/machinery/hologram/holopad/attack_hand(var/mob/user) //Carn: Hologram requests. + if(incoming_connection) + audible_message("The pad hums quietly as it establishes a connection.") + take_call() + return + else if(connected_pad) + if(forced) + audible_message("Access denied. Terminating a command-level transmission locally is not permitted.") + return + audible_message("Severing connection to distant holopad.") + end_call() + return + + if(last_request + 20 SECONDS > world.time) + to_chat(user, SPAN_WARNING("\The [src] is still cooling down since the last transmission.")) + return + + switch(alert(user, "Would you like to request an AI's presence or establish communications with another pad?", "Holopad", "AI", "Holocomms", "Cancel")) + if("AI") + last_request = world.time + to_chat(user, SPAN_NOTICE("You request an AI's presence.")) + var/area/area = get_area(src) + for(var/mob/living/silicon/ai/AI in silicon_mob_list) + if(!AI.client) + continue + to_chat(AI, SPAN_INFO("Your presence is requested at \the [area].")) + if("Holocomms") + last_request = world.time + var/obj/item/card/id/I = user.GetIdCard() + if(!I) + to_chat(user, SPAN_NOTICE("You need authorization to use the holocall system. Please equip a valid ID card.")) + return + var/forced_call = FALSE + if(access_heads in I.access) //Special functions for command level people + switch(alert(user,"Command level authorization detected. Additional functions available.", "Command Level Menu", "Forced Call", "Regular Call")) + if("Forced Call") + forced_call = TRUE + var/list/holopadlist = list() + for(var/obj/machinery/hologram/holopad/H in SSmachinery.processing_machines - src) + if(ARE_Z_CONNECTED(H.z, z) && H.operable()) + holopadlist["[H.holopad_id]"] = H //Define a list and fill it with the area of every holopad in the world + holopadlist = sortAssoc(holopadlist) + var/chosen_pad = input(user, "Which holopad would you like to contact?", "Holopad List") as null|anything in holopadlist + if(!chosen_pad) + last_request = world.time - 15 SECONDS + return + connected_pad = holopadlist[chosen_pad] + make_call(connected_pad, user, forced_call) + +/obj/machinery/hologram/holopad/proc/make_call(var/obj/machinery/hologram/holopad/connected_pad, var/mob/user, forced_call) + connected_pad.last_request = world.time + connected_pad.connected_pad = src //This marks the holopad you are making the call from + connected_pad.incoming_connection = TRUE + playsound(connected_pad.loc, 'sound/machines/chime.ogg', 25, 5) + connected_pad.update_icon() + + if(forced_call) + connected_pad.audible_message("[src] announces, \"Incoming call with command authorization from [connected_pad.holopad_id].\"") + to_chat(user, SPAN_NOTICE("Establishing forced connection to the holopad in [connected_pad.holopad_id].")) + connected_pad.forced = TRUE + sleep(80) + connected_pad.take_call() + else + connected_pad.audible_message("[src] announces, \"Incoming communications request from [connected_pad.connected_pad.holopad_id].\"") + to_chat(user, SPAN_NOTICE("Trying to establish a connection to the holopad in [connected_pad.holopad_id]... Please await confirmation from recipient.")) + +/obj/machinery/hologram/holopad/proc/take_call() + incoming_connection = FALSE + established_connection = TRUE + connected_pad.established_connection = TRUE + create_holos() + +/obj/machinery/hologram/holopad/proc/end_call() + connected_pad.clear_holos(FALSE) + connected_pad.connected_pad = null + clear_holos(FALSE) + established_connection = FALSE + connected_pad.established_connection = FALSE + connected_pad = null + update_icon() + +/obj/machinery/hologram/holopad/check_eye(mob/user) + if(LAZYISIN(active_holograms, user)) + return 0 + return -1 + +/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/user) if(!istype(user)) return - if(incoming_connection && caller_id) - visible_message("The pad hums quietly as it establishes a connection.") - if(caller_id.loc != sourcepad.loc) - visible_message("The pad flashes an error message. The caller has left their holopad.") - return - take_call(user) + + if(isrobot(user)) + attack_hand(user) return - else if(caller_id && !incoming_connection && forced) - audible_message("Access denied. Terminating a command-level transmission locally is not permitted.") - return - else if(caller_id && !incoming_connection) - visible_message("Severing connection to distant holopad.") - end_call(user) - return - switch(alert(user,"Would you like to request an AI's presence or establish communications with another pad?", "Holopad","AI","Holocomms","Cancel")) - if("AI") - if(last_request + 200 < world.time) //don't spam the AI with requests you jerk! - last_request = world.time - to_chat(user, "You request an AI's presence.") - var/area/area = get_area(src) - for(var/mob/living/silicon/ai/AI in silicon_mob_list) - if(!AI.client) continue - to_chat(AI, "Your presence is requested at \the [area].") - else - to_chat(user, "A request for AI presence was already sent recently.") - if("Holocomms") - if(user.loc != src.loc) - to_chat(user, "Please step unto the holopad.") - return - if(last_request + 200 < world.time) //don't spam other people with requests either, you jerk! - last_request = world.time - var/obj/item/card/id/I = user.GetIdCard() - if(!I) - to_chat(user, SPAN_NOTICE("You need authorization to use the holocall system. Please equip a valid ID card.")) - return - var/forcedcall = 0 - if(access_heads in I.access) //Special functions for command level people - switch(alert(user,"Command level authorization detected. Additional functions available", "Command level menu", "Forced call","Regular call")) - if("Forced call") - forcedcall = 1 - var/list/holopadlist = list() - for(var/obj/machinery/hologram/holopad/H in SSmachinery.processing_machines) - if((H.z in current_map.map_levels) && H.operable()) - holopadlist["[H.loc.loc.name]"] = H //Define a list and fill it with the area of every holopad in the world - holopadlist = sortAssoc(holopadlist) - var/temppad = input(user, "Which holopad would you like to contact?", "holopad list") as null|anything in holopadlist - targetpad = holopadlist["[temppad]"] - if(targetpad == src) - to_chat(user, "Using such sophisticated technology, just to talk to yourself seems a bit silly.") - return - if(targetpad) - make_call(targetpad, user, forcedcall) -/obj/machinery/hologram/holopad/proc/make_call(var/obj/machinery/hologram/holopad/targetpad, var/mob/living/carbon/user, forcedcall) - targetpad.last_request = world.time - targetpad.sourcepad = src //This marks the holopad you are making the call from - targetpad.caller_id = user //This marks you as the caller - targetpad.incoming_connection = 1 - playsound(targetpad.loc, 'sound/machines/chime.ogg', 25, 5) - targetpad.icon_state = "holopad1" - if(forcedcall) - targetpad.audible_message("[src] announces, \"Incoming call with command authorization from [targetpad.sourcepad.loc.loc].\"") - to_chat(user, "Establishing forced connection to the holopad in [targetpad.loc.loc]") - targetpad.forced = 1 - sleep(80) - targetpad.take_call(user) - else - targetpad.audible_message("[src] announces, \"Incoming communications request from [targetpad.sourcepad.loc.loc].\"") - to_chat(user, "Trying to establish a connection to the holopad in [targetpad.loc.loc]... Please await confirmation from recipient.") - -/obj/machinery/hologram/holopad/proc/take_call(mob/living/carbon/user) - incoming_connection = 0 - caller_id.set_machine(src) - caller_id.reset_view(src) - if(!masters[caller_id]) //If there is no hologram, possibly make one. - activate_holocall(caller_id) - -/obj/machinery/hologram/holopad/proc/end_call(mob/user) - if(caller_id) - caller_id.unset_machine() - caller_id.reset_view() //Send the caller back to his body - clear_holo(null, caller_id) // destroy the hologram - caller_id = null - - if(user) - user.unset_machine() - user.reset_view() //Send the caller back to his body - clear_holo(null, user) // destroy the hologram - user = null - -/obj/machinery/hologram/holopad/proc/activate_holocall(mob/living/carbon/caller_id) - if(caller_id) - create_holo(0, caller_id)//Create one. - visible_message("A holographic image of [caller_id] flicks to life right before your eyes!") - else - to_chat(caller_id, "ERROR: Unable to project hologram.") - return - -/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user) - if (!istype(user)) - return - /*There are pretty much only three ways to interact here. - I don't need to check for client since they're clicking on an object. - This may change in the future but for now will suffice.*/ - if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. + if(user.eyeobj.loc != src.loc) user.eyeobj.setLoc(get_turf(src)) - else if(!masters[user])//If there is no hologram, possibly make one. - activate_holo(user) - else//If there is a hologram, remove it. - clear_holo(user) - return -/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user) - if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it - if (user.holo) - to_chat(user, "ERROR: Image feed in progress.") - return - create_holo(user)//Create one. - if(hacked == 0) - src.visible_message("A holographic image of [user] flicks to life right before your eyes!") - else - to_chat(user, "ERROR: Unable to project hologram.") - return + if(!LAZYISIN(active_holograms, user)) //If there is no hologram, possibly make one. + visible_message("A holographic image of [user] flicks to life right before your eyes!") + user.holo = src + create_holo(user) + else //If there is a hologram, remove it. + user.holo = null + clear_holo(user) /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ /obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking) - if(M) - for(var/mob/living/silicon/ai/master in masters) - if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. - if(speaking) - text = speaking.scramble(text) - else - text = stars(text) - var/name_used = M.GetVoice() - //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. - var/rendered - if(speaking) - rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]" - else - rendered = "Holopad received, [name_used] [verb], \"[text]\"" - master.show_message(rendered, 2) var/name_used = M.GetVoice() - if(targetpad) //If this is the pad you're making the call from + for(var/mob/living/silicon/ai/master in active_holograms) + if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. + if(speaking) + text = speaking.scramble(text) + else + text = stars(text) + + //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. + var/rendered + if(speaking) + rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]" + else + rendered = "Holopad received, [name_used] [verb], \"[text]\"" + master.show_message(rendered, 2) + if(connected_pad) var/message if(speaking) message = "Holopad received, [name_used] [speaking.format_message(text, verb)]" - targetpad.audible_message(message) - targetpad.last_message = message else message = "Holopad received, [name_used] [verb], \"[text]\"" - if(sourcepad) //If this is a pad receiving a call - if(name_used==caller_id||text==last_message||findtext(text, "Holopad received")) //prevent echoes - return - sourcepad.audible_message("Holopad received, [name_used] [speaking.format_message(text, verb)]") + connected_pad.audible_message(message) + connected_pad.last_message = message /obj/machinery/hologram/holopad/see_emote(mob/living/M, text) - if(M) - for(var/mob/living/silicon/ai/master in masters) - //var/name_used = M.GetVoice() - var/rendered = "Holopad received, [text]" - //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. - master.show_message(rendered, 2) - for(var/mob/living/carbon/master in masters) - //var/name_used = M.GetVoice() - var/rendered = "Holopad received, [text]" - //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. - master.show_message(rendered, 2) - if(targetpad) - targetpad.visible_message("[text]") + for(var/mob/living/silicon/ai/master in active_holograms) + var/rendered = "Holopad received, [text]" + //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. + master.show_message(rendered, 2) + for(var/mob/living/carbon/master in active_holograms) + var/rendered = "Holopad received, [text]" + //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. + master.show_message(rendered, 2) + if(connected_pad) + connected_pad.visible_message("[text]") /obj/machinery/hologram/holopad/show_message(msg, type, alt, alt_type) - for(var/mob/living/silicon/ai/master in masters) + for(var/mob/living/silicon/ai/master in active_holograms) var/rendered = "The holographic image of [msg]" master.show_message(rendered, type) if(findtext(msg, "Holopad received,")) return - for(var/mob/living/carbon/master in masters) + for(var/mob/living/carbon/master in active_holograms) var/rendered = "The holographic image of [msg]" master.show_message(rendered, type) - if(targetpad) - for(var/mob/living/carbon/master in view(targetpad)) - var/rendered = "The holographic image of [msg]" - master.show_message(rendered, type) -/obj/machinery/hologram/holopad/proc/create_holo(mob/living/silicon/ai/A, mob/living/carbon/caller_id, turf/T = loc) - if(hacked == 0) - var/obj/effect/overlay/hologram = new(T)//Spawn a blank effect at the location. - hologram.no_clean = TRUE - if(caller_id) - var/tempicon = getFlatIcon(caller_id) +/obj/machinery/hologram/holopad/proc/create_holos() + for(var/mob/living/M in viewers(world.view, connected_pad)) + if(LAZYISIN(active_holograms, M)) + continue + create_holo(M) - hologram.name = "[caller_id.name] (Hologram)" - hologram.forceMove(get_step(src,1)) - masters[caller_id] = hologram - hologram.icon = getHologramIcon(icon(tempicon)) // Add the callers image as an overlay to keep coloration! - else - hologram.icon = A.holo_icon // Add the AI's configured holo Icon - hologram.name = "[A.name] (Hologram)"//If someone decides to right click. - A.holo = src - masters[A] = hologram +/obj/machinery/hologram/holopad/proc/create_holo(mob/M) + var/obj/effect/overlay/hologram/H = new(get_turf(src)) + if(!isAI(M) && connected_pad) + H.x = src.x - (connected_pad.x - M.x) + H.y = src.y - (connected_pad.y - M.y) + if(!isInSight(H, src)) + qdel(H) + return + H.assume_form(M) + LAZYSET(active_holograms, M, H) - hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - hologram.mouse_opacity = 0//So you can't click on it. - hologram.anchored = 1//So space wind cannot drag it. - hologram.set_light(2) //hologram lighting - hologram.color = color //painted holopad gives coloured holograms - set_light(2) //pad lighting - icon_state = "holopad1" - return 1 - else if(hacked == 1) - var/obj/effect/overlay/hologram = new(T)//Spawn a blank effect at the location. - hologram.no_clean = TRUE - hologram.mouse_opacity = 0//So you can't click on it. - hologram.anchored = 1//So space wind cannot drag it. - masters[A] = hologram - A.holo = src - return 1 + update_icon() -/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/silicon/ai/user, mob/living/carbon/call_user) - if(user) - qdel(masters[user])//Get rid of user's hologram - user.holo = null - masters -= user //Discard AI from the list of those who use holopad - if(call_user) - qdel(masters[call_user]) //Get rid of user's hologram - masters -= call_user //Discard the caller from the list of those who use holopad - if (!masters.len)//If no users left - set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted) - icon_state = "holopad0" - if(sourcepad) - sourcepad.targetpad = null - sourcepad = null - caller_id = null - return 1 +/obj/machinery/hologram/holopad/proc/update_holos() + for(var/thing in active_holograms) + var/mob/M = thing + if(isAI(M)) + continue + var/obj/effect/overlay/hologram/H = active_holograms[thing] + if(connected_pad) + H.x = src.x - (connected_pad.x - M.x) + H.y = src.y - (connected_pad.y - M.y) + if(get_dist(H, src) > world.view || !isInSight(H, src)) + clear_holo(M) + return + H.assume_form(M) + +/obj/machinery/hologram/holopad/proc/clear_holos(var/clear_ai = TRUE) + for(var/M in active_holograms) + if(!clear_ai && isAI(M)) + continue + clear_holo(M) + +/obj/machinery/hologram/holopad/proc/clear_holo(var/mob/M) + if(!LAZYLEN(active_holograms)) + return + qdel(active_holograms[M]) + LAZYREMOVE(active_holograms, M) + update_icon() /obj/machinery/hologram/holopad/machinery_process() - for (var/mob/living/silicon/ai/master in masters) - var/active_ai = (master && !master.incapacitated() && master.client && master.eyeobj)//If there is an AI with an eye attached, it's not incapacitated, and it has a client - if((stat & NOPOWER) || !active_ai) - clear_holo(master) + for(var/thing in active_holograms) + var/mob/M = thing + var/is_inactive_ai = FALSE + if(isAI(M)) + var/mob/living/silicon/ai/master = M + is_inactive_ai = !(master && !master.incapacitated() && master.client && master.eyeobj) //If there is an AI with an eye attached, it's not incapacitated, and it has a client + if((stat & NOPOWER) || is_inactive_ai) + clear_holo(M) continue - if(!(masters[master] in view(src))) - clear_holo(master) - continue - - use_power(power_per_hologram) - if(last_request + 200 < world.time && incoming_connection==1) - incoming_connection = 0 - end_call() - if(sourcepad) - sourcepad.audible_message("The holopad connection timed out") - sourcepad = 0 - if (caller_id && sourcepad) - if(caller_id.loc != sourcepad.loc) - forced = 0 - sourcepad.visible_message("Severing connection to distant holopad.") - visible_message("The connection has been terminated by [caller_id].") + if(connected_pad) + if(connected_pad.stat & NOPOWER) end_call() - return 1 + return TRUE + if(established_connection && !hacked) + create_holos() + update_holos() + + use_power(power_per_hologram * LAZYLEN(active_holograms)) + + if(last_request + 20 SECONDS < world.time && incoming_connection) + incoming_connection = FALSE + clear_holos(FALSE) + if(connected_pad) + connected_pad.audible_message("The holopad connection timed out") + connected_pad = null + return TRUE /obj/machinery/hologram/holopad/proc/move_hologram(mob/living/silicon/ai/user) - if(masters[user]) - step_to(masters[user], user.eyeobj) // So it turns. - var/obj/effect/overlay/H = masters[user] + if(LAZYISIN(active_holograms, user)) + step_to(active_holograms[user], user.eyeobj) // So it turns. + var/obj/effect/overlay/H = active_holograms[user] H.forceMove(get_turf(user.eyeobj)) - masters[user] = H + active_holograms[user] = H if(!(H in view(src))) clear_holo(user) return 0 - if((HOLOPAD_MODE == RANGE_BASED && (get_dist(user.eyeobj, src) > holo_range))) + if(get_dist(user.eyeobj, src) > holo_range || !isInSight(H, src)) + user.holo = null clear_holo(user) - - if(HOLOPAD_MODE == AREA_BASED) - var/area/holo_area = get_area(src) - var/area/hologram_area = get_area(H) - if(hologram_area != holo_area) - clear_holo(user) - return 1 + return TRUE /* * Hologram @@ -365,47 +325,33 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(1.0) qdel(src) if(2.0) - if (prob(50)) + if(prob(50)) qdel(src) if(3.0) - if (prob(5)) + if(prob(5)) qdel(src) - return /obj/machinery/hologram/holopad/Destroy() - for (var/mob/living/master in masters) - clear_holo(master) + clear_holos() return ..() -/* -Holographic project of everything else. -/mob/verb/hologram_test() - set name = "Hologram Debug New" - set category = "CURRENT DEBUG" - var/obj/effect/overlay/hologram = new(loc)//Spawn a blank effect at the location. - var/icon/flat_icon = icon(getFlatIcon(src,0))//Need to make sure it's a new icon so the old one is not reused. - flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish. - flat_icon.ChangeOpacity(0.5)//Make it half transparent. - var/input = input("Select what icon state to use in effect.",,"") - if(input) - var/icon/alpha_mask = new('icons/effects/effects.dmi', "[input]") - flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. - hologram.icon = flat_icon - to_world("Your icon should appear now.") - return -*/ +/obj/effect/overlay/hologram + name = "hologram" + layer = FLY_LAYER + anchored = TRUE //So space wind cannot drag it. + no_clean = TRUE -/* - * Other Stuff: Is this even used? - */ -/obj/machinery/hologram/projector - name = "hologram projector" - desc = "It makes a hologram appear...with magnets or something..." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "holopad0" +/obj/effect/overlay/hologram/proc/assume_form(var/atom/A) + if(isAI(A)) + var/mob/living/silicon/ai/AI = A + icon = AI.holo_icon + else + appearance = A.appearance + mouse_opacity = 0 //So you can't click on it. + dir = A.dir + color = rgb(125, 180, 225) + alpha = 100 + set_light(2, 1, rgb(125, 180, 225)) - -#undef RANGE_BASED -#undef AREA_BASED #undef HOLOPAD_PASSIVE_POWER_USAGE -#undef HOLOGRAM_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE \ No newline at end of file diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index 9682e12361a..0bf16501158 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -156,7 +156,7 @@ // Specific mob type exceptions below. /mob/living/silicon/ai/emote(var/act, var/type, var/message) var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.masters[src]) //Is the AI using a holopad? + if(T?.active_holograms[src]) //Is the AI using a holopad? src.holopad_emote(message) else //Emote normally, then. ..() diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index bf6f29f50cf..b1867e0d63b 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -86,7 +86,7 @@ return var/obj/machinery/hologram/holopad/H = src.holo - if(H && H.masters[src])//If there is a hologram and its master is the user. + if(H?.active_holograms[src])//If there is a hologram and its master is the user. // AI can hear their own message, this formats it for them. if(speaking) to_chat(src, "Holopad transmitted, [real_name] [speaking.format_message(message, verb)]") @@ -135,7 +135,7 @@ return var/obj/machinery/hologram/holopad/T = src.holo - if(T?.masters[src]) + if(T?.active_holograms[src]) var/rendered = "[name] [message]" to_chat(src, "Holopad action relayed, [real_name] [message]") @@ -148,7 +148,7 @@ /mob/living/silicon/ai/emote(var/act, var/type, var/message) var/obj/machinery/hologram/holopad/T = src.holo - if(T?.masters[src]) //Is the AI using a holopad? + if(T?.active_holograms[src]) //Is the AI using a holopad? src.holopad_emote(message) else //Emote normally, then. ..() diff --git a/html/changelogs/geeves-cool_holocomms.yml b/html/changelogs/geeves-cool_holocomms.yml new file mode 100644 index 00000000000..f45c13ebfcb --- /dev/null +++ b/html/changelogs/geeves-cool_holocomms.yml @@ -0,0 +1,6 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Holocalls now send holograms of people in the vicinity to whichever pad it's connected to, instead of just sending the caller's hologram. You no longer have to stand on the holopad to talk. Give it a try." \ No newline at end of file