mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-13 17:14:47 +01:00
Allows taking pictures over advanced consoles or looking up/down, and fixes some multi-z photography issues. (#91632)
## About The Pull Request I wanted to allow you to take pictures over advanced camera consoles for heist planning style point reasons, and parity with the AI, and in the process found a small pile of bugs. So, this aims to fix a pile of those, and slightly clean up the code in the process. The biggest part of this change involves making the multi-z part of photography code properly account for turfs below open or glass turfs, rather than trying to skip to the bottom. This needs to be done because objects can exist above those open turfs, most commonly lattices/catwalks, but also nograv stuff. ...Parallax is its whole own other issue with how photography works right now, so uh. Yeah, no. Sadly I couldn't get this to work with regular camera consoles, and as I found it to be an entirely different can of worms that would only slightly touch this code I decided that would be best explored in a separate pr. ## Why It's Good For The Game I think it's cute to be able to take a picture of your screen and show it off to people, maybe even combine it with a detective board for a cool little planning thing. And the AI can take pictures over the cameranet so, y'know. Doing so while looking up/down was a side-effect, but really I think it's fine to let you photograph it if you can see it. Less multi-z jank is good 👍 ### Actual Pictures: <details> <summary>Unfold</summary>        </details> ## Changelog 🆑 add: You can take pictures over advanced camera consoles. add: You can take pictures while looking up or down. fix: AIs taking pictures in multi-z shows the objects of your floor and the ones below, instead of just the ones below. fix: Humans taking pictures through holes in multi-z actually shows the floor below, instead of pitch-black nothingness. fix: Taking pictures of glass floors in multi-z actually shows the floor below. /🆑
This commit is contained in:
@@ -159,26 +159,49 @@
|
||||
disk = new_disk
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
//user can be atom or mob
|
||||
/obj/item/camera/proc/can_target(atom/target, mob/user)
|
||||
/// Attempt to take an image, optionally given a user.
|
||||
/obj/item/camera/proc/attempt_picture(atom/target, atom/user)
|
||||
if(!can_target(target, user))
|
||||
return FALSE
|
||||
if(!photo_taken(target, user))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Check whether we can take a picture of the target, optionally given a user.
|
||||
/obj/item/camera/proc/can_target(atom/target, atom/user)
|
||||
if(!on || blending || !pictures_left)
|
||||
return FALSE
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(isnull(target_turf))
|
||||
return FALSE
|
||||
if(istype(user))
|
||||
if(isAI(user) && !GLOB.cameranet.checkTurfVis(T))
|
||||
return FALSE
|
||||
else if(user.client && !(get_turf(target) in get_hear(user.client.view, user)))
|
||||
return FALSE
|
||||
else if(!(get_turf(target) in get_hear(CONFIG_GET(string/default_view), user)))
|
||||
return FALSE
|
||||
else if(isliving(loc))
|
||||
if(!(get_turf(target) in view(world.view, loc)))
|
||||
return FALSE
|
||||
else //user is an atom or null
|
||||
if(!(get_turf(target) in view(world.view, user || src)))
|
||||
|
||||
if(isAI(user))
|
||||
return can_ai_target(target_turf)
|
||||
if(ismob(user))
|
||||
return can_mob_target(target_turf, user)
|
||||
|
||||
if(isliving(loc))
|
||||
if(!(target_turf in view(world.view, loc)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// User is an atom or null
|
||||
if(!(target_turf in view(world.view, user || src)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Check whether an AI could take a picture of the target turf.
|
||||
/obj/item/camera/proc/can_ai_target(turf/target_turf)
|
||||
if(!GLOB.cameranet.checkTurfVis(target_turf))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Check whether a mob could take a picture of the target turf.
|
||||
/obj/item/camera/proc/can_mob_target(turf/target_turf, mob/user)
|
||||
var/user_view = user.client ? user.client.view : CONFIG_GET(string/default_view)
|
||||
var/user_eye = user.client ? user.client.eye : user
|
||||
if(!(target_turf in get_hear(user_view, user_eye)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/camera/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
|
||||
@@ -201,11 +224,7 @@
|
||||
disk.record.caller_name = recorded_mob.name
|
||||
disk.record.set_caller_image(recorded_mob)
|
||||
|
||||
if(!can_target(interacting_with, user))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!photo_taken(interacting_with, user))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
return attempt_picture(interacting_with, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING
|
||||
|
||||
/obj/item/camera/proc/photo_taken(atom/target, mob/user)
|
||||
|
||||
@@ -242,7 +261,6 @@
|
||||
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
|
||||
var/list/mobs_spotted = list()
|
||||
var/list/dead_spotted = list()
|
||||
var/ai_user = isAI(user)
|
||||
var/list/seen
|
||||
var/list/viewlist = user?.client ? getviewsize(user.client.view) : getviewsize(world.view)
|
||||
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
|
||||
@@ -254,22 +272,33 @@
|
||||
var/clone_area = SSmapping.request_turf_block_reservation(size_x * 2 + 1, size_y * 2 + 1, 1)
|
||||
///list of human names taken on picture
|
||||
var/list/names = list()
|
||||
var/cameranet_user = isAI(user) || istype(viewc, /mob/eye/camera)
|
||||
|
||||
var/width = size_x * 2 + 1
|
||||
var/height = size_y * 2 + 1
|
||||
for(var/turf/placeholder as anything in CORNER_BLOCK_OFFSET(target_turf, width, height, -size_x, -size_y))
|
||||
while(istype(placeholder, /turf/open/openspace)) //Multi-z photography
|
||||
placeholder = GET_TURF_BELOW(placeholder)
|
||||
if(!placeholder)
|
||||
break
|
||||
for(var/turf/seen_placeholder as anything in CORNER_BLOCK_OFFSET(target_turf, width, height, -size_x, -size_y))
|
||||
if(isnull(seen_placeholder))
|
||||
continue
|
||||
|
||||
if(placeholder && ((ai_user && GLOB.cameranet.checkTurfVis(placeholder)) || (placeholder in seen)))
|
||||
turfs += placeholder
|
||||
for(var/mob/M in placeholder)
|
||||
mobs += M
|
||||
if(locate(/obj/item/blueprints) in placeholder)
|
||||
if(cameranet_user && !GLOB.cameranet.checkTurfVis(seen_placeholder))
|
||||
continue
|
||||
if(!cameranet_user && !(seen_placeholder in seen))
|
||||
continue
|
||||
|
||||
//Multi-z photography
|
||||
var/turf/target_placeholder = seen_placeholder
|
||||
while(!isnull(target_placeholder))
|
||||
turfs += target_placeholder
|
||||
for(var/mob/mob_there in target_placeholder)
|
||||
mobs += mob_there
|
||||
if(locate(/obj/item/blueprints) in target_placeholder)
|
||||
blueprints = TRUE
|
||||
|
||||
if(isopenspaceturf(target_placeholder) || istype(target_placeholder, /turf/open/floor/glass))
|
||||
target_placeholder = GET_TURF_BELOW(target_placeholder)
|
||||
else
|
||||
break
|
||||
|
||||
// do this before picture is taken so we can reveal revenants for the photo
|
||||
steal_souls(mobs)
|
||||
|
||||
@@ -398,8 +427,6 @@
|
||||
target = locate(our_turf.x + picture_coord_x.value, our_turf.y + picture_coord_y.value, our_turf.z)
|
||||
if(!target)
|
||||
return
|
||||
if(!camera.can_target(target))
|
||||
return
|
||||
INVOKE_ASYNC(camera, TYPE_PROC_REF(/obj/item/camera, captureimage), target, null, camera.picture_size_x - 1, camera.picture_size_y - 1)
|
||||
INVOKE_ASYNC(camera, TYPE_PROC_REF(/obj/item/camera, attempt_picture), target)
|
||||
|
||||
#undef CAMERA_PICTURE_SIZE_HARD_LIMIT
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
/obj/effect/appearance_clone
|
||||
|
||||
/obj/effect/appearance_clone/New(loc, atom/A) //Intentionally not Initialize(), to make sure the clone assumes the intended appearance in time for the camera getFlatIcon.
|
||||
if(istype(A))
|
||||
appearance = A.appearance
|
||||
dir = A.dir
|
||||
if(ismovable(A))
|
||||
var/atom/movable/AM = A
|
||||
step_x = AM.step_x
|
||||
step_y = AM.step_y
|
||||
. = ..()
|
||||
/obj/effect/appearance_clone/New(loc, atom/our_atom) //Intentionally not Initialize(), to make sure the clone assumes the intended appearance in time for the camera getFlatIcon.
|
||||
if(!istype(our_atom))
|
||||
return ..()
|
||||
if(!isopenspaceturf(our_atom))
|
||||
appearance = our_atom.appearance
|
||||
dir = our_atom.dir
|
||||
if(ismovable(our_atom))
|
||||
var/atom/movable/our_movable = our_atom
|
||||
step_x = our_movable.step_x
|
||||
step_y = our_movable.step_y
|
||||
return ..()
|
||||
|
||||
#define PHYSICAL_POSITION(atom) ((atom.y * ICON_SIZE_Y) + (atom.pixel_y))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user