diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 394fe4cd206..df95a6031c7 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -52,6 +52,9 @@ if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlShiftClickOn(A) return + if(LAZYACCESS(modifiers, MIDDLE_CLICK)) + ShiftMiddleClickOn(A) + return ShiftClickOn(A) return if(LAZYACCESS(modifiers, ALT_CLICK)) // alt and alt-gr (rightalt) @@ -269,6 +272,15 @@ togglelock(user) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN +/mob/living/silicon/ai/ShiftMiddleClickOn(atom/A) + if(control_disabled || incapacitated) + return + if(!can_see(A)) + return + if(!point_at(A, TRUE)) + return + log_message("points at [A] using holopad", LOG_EMOTE) + /* AI Turrets */ /obj/machinery/turretid/ai_click_alt(mob/living/silicon/ai/user) //toggles lethal on turrets if(ailock) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 881caa03028..7284793063a 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -89,6 +89,8 @@ Possible to do for anyone motivated enough: var/secure = FALSE /// If we are currently calling another holopad var/calling = FALSE + /// Whether this pad is currently projecting a pointing arrow + var/pointing = FALSE ///bitfield. used to turn on and off hearing sensitivity depending on if we can act on Hear() at all - meant for lowering the number of unessesary hearable atoms var/can_hear_flags = NONE @@ -738,6 +740,43 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ else ray.transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle) +/// Project a holographic pointing arrow from this holopad toward a target +/obj/machinery/holopad/proc/holo_point(atom/target, invisibility = 0) + if(pointing) + return + var/turf/pad_turf = get_turf(src) + var/turf/target_turf = get_turf(target) + if(!pad_turf || !target_turf) + return + pointing = TRUE + var/obj/effect/temp_visual/point/holo/visual = new(pad_turf, invisibility) + var/obj/effect/overlay/holoray/ray = new(pad_turf) + var/disty = target_turf.y - pad_turf.y + var/distx = target_turf.x - pad_turf.x + var/distance = sqrt(distx*distx + disty*disty) + var/angle + if(!disty) + angle = (distx >= 0) ? 90 : 270 + else + angle = arctan(distx/disty) + if(disty < 0) + angle += 180 + else if(distx < 0) + angle += 360 + var/matrix/M = matrix() + ray.transform = turn(M.Scale(1, distance), angle) + animate(visual, pixel_x = (target_turf.x - pad_turf.x) * ICON_SIZE_X + target.pixel_x, pixel_y = (target_turf.y - pad_turf.y) * ICON_SIZE_Y + target.pixel_y, time = 1.7, easing = EASE_OUT) + set_light(2) + icon_state = "[base_icon_state]1" + addtimer(CALLBACK(src, PROC_REF(clear_holo_point), ray), 2.5 SECONDS) + return visual + +/// Called after the holo-point expires to restore the holopad's state +/obj/machinery/holopad/proc/clear_holo_point(obj/effect/overlay/holoray/ray) + qdel(ray) + pointing = FALSE + SetLightsAndPower() + // RECORDED MESSAGES /obj/machinery/holopad/proc/setup_replay_holo(datum/holorecord/record) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 05c8f2cb269..0689c2c59e5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1279,6 +1279,31 @@ . += emissive_appearance(icon, lights_state, src) +/mob/living/silicon/ai/point_at(atom/pointed_atom, intentional = FALSE) + if(pointed_atom in src) + return FALSE + var/turf/target_turf = get_turf(pointed_atom) + if(!target_turf) + return FALSE + var/obj/machinery/holopad/best_pad + for(var/obj/machinery/holopad/pad as anything in SSmachines.get_machines_by_type(/obj/machinery/holopad)) + if(!pad.on_network || !pad.is_operational || pad.pointing) + continue + if(!pad.validate_location(target_turf)) + continue + var/turf/pad_turf = get_turf(pad) + if(!SScameras.is_visible_by_cameras(pad_turf)) + continue + if(!best_pad || get_dist(pad_turf, target_turf) < get_dist(get_turf(best_pad), target_turf)) + best_pad = pad + if(!best_pad) + return FALSE + var/obj/visual = best_pad.holo_point(pointed_atom, invisibility) + if(!visual) + return FALSE + SEND_SIGNAL(src, COMSIG_MOVABLE_POINTED, pointed_atom, visual, intentional) + return TRUE + #undef HOLOGRAM_CHOICE_CHARACTER #undef CHARACTER_TYPE_SELF #undef CHARACTER_TYPE_CREWMEMBER diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm index 00b2e995f24..f72e5a97438 100644 --- a/code/modules/point/point.dm +++ b/code/modules/point/point.dm @@ -84,6 +84,13 @@ pixel_y = old_loc.pixel_y SetInvisibility(set_invis) +/obj/effect/temp_visual/point/holo + icon_state = "arrow_large_white" + +/obj/effect/temp_visual/point/holo/Initialize(mapload, set_invis = 0) + . = ..() + makeHologram() + #undef POINT_TIME /**