From 9cf164d66ceefbe4fbbe691acb43b7064c737bde Mon Sep 17 00:00:00 2001 From: ShadowLarkens Date: Sun, 10 May 2020 21:14:52 -0700 Subject: [PATCH] Fix AI multicam exploits & a few other bugs --- code/_onclick/hud/picture_in_picture.dm | 51 +++++++-- code/_onclick/hud/screen_objects.dm | 1 - .../modules/mob/living/silicon/ai/multicam.dm | 103 +++++++++++++++--- code/modules/overmap/spacetravel.dm | 5 + icons/misc/pic_in_pic.dmi | Bin 3370 -> 3598 bytes 5 files changed, 130 insertions(+), 30 deletions(-) diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index b824fad6879..14b6a862c20 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -12,7 +12,7 @@ var/obj/screen/component_button/button_expand var/obj/screen/component_button/button_shrink - var/mutable_appearance/standard_background + var/list/background_mas = list() var/const/max_dimensions = 10 /obj/screen/movable/pic_in_pic/Initialize() @@ -36,11 +36,17 @@ set_view_size(width-1, height-1) /obj/screen/movable/pic_in_pic/proc/make_backgrounds() - standard_background = new /mutable_appearance() - standard_background.icon = 'icons/misc/pic_in_pic.dmi' - standard_background.icon_state = "background" - standard_background.layer = DISPOSAL_LAYER - standard_background.plane = PLATING_PLANE + var/mutable_appearance/base = new /mutable_appearance() + base.icon = 'icons/misc/pic_in_pic.dmi' + base.layer = DISPOSAL_LAYER + base.plane = PLATING_PLANE + base.appearance_flags = PIXEL_SCALE + + for(var/direction in cardinal) + var/mutable_appearance/dir = new /mutable_appearance(base) + dir.dir = direction + dir.icon_state = "background_[direction]" + background_mas += dir /obj/screen/movable/pic_in_pic/proc/add_buttons() var/static/mutable_appearance/move_tab @@ -97,11 +103,34 @@ /obj/screen/movable/pic_in_pic/proc/add_background() if((width > 0) && (height > 0)) - var/matrix/M = matrix() - M.Scale(width + 0.5, height + 0.5) - M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size) - standard_background.transform = M - overlays += standard_background + for(var/mutable_appearance/dir in background_mas) + var/matrix/M = matrix() + var/x_scale = 1 + var/y_scale = 1 + + var/x_off = 0 + var/y_off = 0 + + if(dir.dir & (NORTH|SOUTH)) + x_scale = width + x_off = (width-1)/2 * world.icon_size + if(dir.dir & NORTH) + y_off = ((height-1) * world.icon_size) + 3 + else + y_off = -3 + + if(dir.dir & (EAST|WEST)) + y_scale = height + y_off = (height-1)/2 * world.icon_size + if(dir.dir & EAST) + x_off = ((width-1) * world.icon_size) + 3 + else + x_off = -3 + + M.Scale(x_scale, y_scale) + M.Translate(x_off, y_off) + dir.transform = M + overlays += dir /obj/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE) width = CLAMP(width, 0, max_dimensions) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 367ed9d1533..ab6985bdbdc 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -610,7 +610,6 @@ /obj/screen/component_button var/obj/screen/parent - /obj/screen/component_button/Initialize(mapload, obj/screen/new_parent) . = ..() parent = new_parent diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm index 9a973e7fa38..018454608c5 100644 --- a/code/modules/mob/living/silicon/ai/multicam.dm +++ b/code/modules/mob/living/silicon/ai/multicam.dm @@ -2,7 +2,7 @@ /obj/screen/movable/pic_in_pic/ai var/mob/living/silicon/ai/ai - var/mutable_appearance/highlighted_background + var/list/highlighted_mas = list() var/highlighted = FALSE var/mob/observer/eye/aiEye/pic_in_pic/aiEye @@ -12,9 +12,12 @@ aiEye.screen = src /obj/screen/movable/pic_in_pic/ai/Destroy() + . = ..() + if(!QDELETED(aiEye)) + QDEL_NULL(aiEye) + else + aiEye = null set_ai(null) - QDEL_NULL(aiEye) - return ..() /obj/screen/movable/pic_in_pic/ai/Click() ..() @@ -23,22 +26,57 @@ /obj/screen/movable/pic_in_pic/ai/make_backgrounds() ..() - highlighted_background = new /mutable_appearance() - highlighted_background.icon = 'icons/misc/pic_in_pic.dmi' - highlighted_background.icon_state = "background_highlight" - highlighted_background.layer = DISPOSAL_LAYER - highlighted_background.plane = PLATING_PLANE + var/mutable_appearance/base = new /mutable_appearance() + base.icon = 'icons/misc/pic_in_pic.dmi' + base.layer = DISPOSAL_LAYER + base.plane = PLATING_PLANE + base.appearance_flags = PIXEL_SCALE + + for(var/direction in cardinal) + var/mutable_appearance/dir = new /mutable_appearance(base) + dir.dir = direction + dir.icon_state = "background_highlight_[direction]" + highlighted_mas += dir /obj/screen/movable/pic_in_pic/ai/add_background() if((width > 0) && (height > 0)) - var/matrix/M = matrix() - M.Scale(width + 0.5, height + 0.5) - M.Translate((width-1)/2 * world.icon_size, (height-1)/2 * world.icon_size) - highlighted_background.transform = M - standard_background.transform = M - overlays += highlighted ? highlighted_background : standard_background + if(!highlighted) + return ..() + + for(var/mutable_appearance/dir in highlighted_mas) + var/matrix/M = matrix() + var/x_scale = 1 + var/y_scale = 1 + + var/x_off = 0 + var/y_off = 0 + + if(dir.dir & (NORTH|SOUTH)) + x_scale = width + x_off = (width-1)/2 * world.icon_size + if(dir.dir & NORTH) + y_off = ((height-1) * world.icon_size) + 3 + else + y_off = -3 + + if(dir.dir & (EAST|WEST)) + y_scale = height + y_off = (height-1)/2 * world.icon_size + if(dir.dir & EAST) + x_off = ((width-1) * world.icon_size) + 3 + else + x_off = -3 + + M.Scale(x_scale, y_scale) + M.Translate(x_off, y_off) + dir.transform = M + overlays += dir /obj/screen/movable/pic_in_pic/ai/set_view_size(width, height, do_refresh = TRUE) + if(!aiEye) + qdel(src) + return + aiEye.static_visibility_range = (round(max(width, height) / 2) + 1) if(ai) ai.camera_visibility(aiEye) @@ -46,27 +84,50 @@ /obj/screen/movable/pic_in_pic/ai/set_view_center(atom/target, do_refresh = TRUE) ..() + if(!aiEye) + qdel(src) + return + aiEye.setLoc(get_turf(target)) /obj/screen/movable/pic_in_pic/ai/refresh_view() ..() + if(!aiEye) + qdel(src) + return + aiEye.setLoc(get_turf(center)) /obj/screen/movable/pic_in_pic/ai/proc/highlight() if(highlighted) return + if(!aiEye) + qdel(src) + return highlighted = TRUE - overlays -= standard_background - overlays += highlighted_background + overlays.Cut() + add_background() + add_buttons() /obj/screen/movable/pic_in_pic/ai/proc/unhighlight() if(!highlighted) return + if(!aiEye) + qdel(src) + return highlighted = FALSE - overlays -= highlighted_background - overlays += standard_background + overlays.Cut() + add_background() + add_buttons() /obj/screen/movable/pic_in_pic/ai/proc/set_ai(mob/living/silicon/ai/new_ai) + if(!aiEye && !QDELETED(src)) + if(new_ai) + to_chat(new_ai, "

You've run into a unfixable bug with AI eye code. \ +In order to create a new multicam, you will have to select a different camera first before trying to add one, or ask an admin to fix you. \ +Whatever you did that made the last camera window disappear-- don't do that again.

") + qdel(src) + return if(ai) ai.multicam_screens -= src ai.all_eyes -= aiEye @@ -88,6 +149,8 @@ icon = 'icons/misc/pic_in_pic.dmi' icon_state = "room_background" flags = NOJAUNT + plane = SPACE_PLANE + layer = AREA_LAYER + 0.1 /turf/unsimulated/ai_visible/Initialize() . = ..() @@ -182,6 +245,10 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room) disable_camera_telegraphing() if(screen && screen.ai) screen.ai.all_eyes -= src + if(!QDELETED(screen)) + QDEL_NULL(screen) + else + screen = null return ..() //AI procs diff --git a/code/modules/overmap/spacetravel.dm b/code/modules/overmap/spacetravel.dm index a51cfc3f6de..ac5846202a0 100644 --- a/code/modules/overmap/spacetravel.dm +++ b/code/modules/overmap/spacetravel.dm @@ -63,11 +63,16 @@ proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A) if (!M) return + // Don't let AI eyes yeet themselves off the map + if(istype(A, /mob/observer/eye)) + return + if(A.lost_in_space()) if(!QDELETED(A)) qdel(A) return + var/nx = 1 var/ny = 1 var/nz = 1 diff --git a/icons/misc/pic_in_pic.dmi b/icons/misc/pic_in_pic.dmi index 9c550f3c25ecdf6817afd63dc0843875e245dfaa..cdac1295132945eeb87decca007cef4a35d5f92b 100644 GIT binary patch literal 3598 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 literal 3370 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 E2DHmSY5)KL