Merge pull request #11265 from Karolis2011/camera_fix

General camera fixes.
This commit is contained in:
GinjaNinja32
2015-11-23 09:29:02 +00:00
5 changed files with 86 additions and 100 deletions

View File

@@ -181,3 +181,8 @@
#define COLOR_PALE_RED_GRAY "#CC9090"
#define COLOR_PALE_PURPLE_GRAY "#BDA2BA"
#define COLOR_PURPLE_GRAY "#A2819E"
//Camera capture modes
#define CAPTURE_MODE_REGULAR 0 //Regular polaroid camera mode
#define CAPTURE_MODE_ALL 1 //Admin camera mode
#define CAPTURE_MODE_PARTIAL 3 //Simular to regular mode, but does not do dummy check

View File

@@ -760,7 +760,11 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
// Pull the default direction.
add = icon(I:icon, I:icon_state)
else // 'I' is an appearance object.
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
if(istype(A,/obj/machinery/atmospherics) && I in A.underlays)
var/image/Im = I
add = getFlatIcon(new/image(I), Im.dir, curicon, curstate, curblend, 1)
else
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, always_use_defdir)
// Find the new dimensions of the flat icon to fit the added overlay
addX1 = min(flatX1, I:pixel_x+1)
@@ -773,9 +777,15 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1)
flatX1=addX1;flatX2=addX2
flatY1=addY1;flatY2=addY2
var/iconmode
if(I in A.overlays)
iconmode = ICON_OVERLAY
else if(I in A.underlays)
iconmode = ICON_UNDERLAY
else
iconmode = blendMode2iconMode(curblend)
// Blend the overlay into the flattened icon
flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
flat.Blend(add, iconmode, I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
if(A.color)
flat.Blend(A.color, ICON_MULTIPLY)
@@ -853,3 +863,53 @@ proc/sort_atoms_by_layer(var/list/atoms)
result.Swap(i, gap + i)
swapped = 1
return result
/*
generate_image function generates image of specified range and location
arguments tx, ty, tz are target coordinates (requred), range defines render distance to opposite corner (requred)
cap_mode is capturing mode (optional), user is capturing mob (requred only wehen cap_mode = CAPTURE_MODE_REGULAR),
lighting determines lighting capturing (optional), suppress_errors suppreses errors and continues to capture (optional).
*/
proc/generate_image(var/tx as num, var/ty as num, var/tz as num, var/range as num, var/cap_mode = CAPTURE_MODE_PARTIAL, var/mob/living/user, var/lighting = 1, var/suppress_errors = 1)
var/list/turfstocapture = list()
//Lines below determine what tiles will be rendered
for(var/xoff = 0 to range)
for(var/yoff = 0 to range)
var/turf/T = locate(tx + xoff,ty + yoff,tz)
if(T)
if(cap_mode == CAPTURE_MODE_REGULAR)
if(user.can_capture_turf(T))
turfstocapture.Add(T)
continue
else
turfstocapture.Add(T)
else
//Capture includes non-existan turfs
if(!suppress_errors)
return
//Lines below determine what objects will be rendered
var/list/atoms = list()
for(var/turf/T in turfstocapture)
atoms.Add(T)
for(var/atom/A in T)
if(istype(A, /atom/movable/lighting_overlay) && lighting) //Special case for lighting
atoms.Add(A)
continue
if(A.invisibility) continue
atoms.Add(A)
//Lines below actually render all colected data
atoms = sort_atoms_by_layer(atoms)
var/icon/cap = icon('icons/effects/96x96.dmi', "")
cap.Scale(range*32, range*32)
cap.Blend("#000", ICON_OVERLAY)
for(var/atom/A in atoms)
if(A)
var/icon/img = getFlatIcon(A)
if(istype(img, /icon))
if(istype(A, /mob/living) && A:lying)
img.BecomeLying()
var/xoff = (A.x - tx) * 32
var/yoff = (A.y - ty) * 32
cap.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
return cap

View File

@@ -4,6 +4,7 @@
set desc = "Usage: Capture-Map-Part target_x_cord target_y_cord target_z_cord range (captures part of a map originating from bottom left corner)"
if(!check_rights(R_ADMIN|R_DEBUG|R_SERVER))
usr << "You are not allowed to use this command"
return
if(isnull(tx) || isnull(ty) || isnull(tz) || isnull(range))
@@ -17,41 +18,7 @@
return
if(locate(tx,ty,tz))
var/list/turfstocapture = list()
var/hasasked = 0
for(var/xoff = 0 to range)
for(var/yoff = 0 to range)
var/turf/T = locate(tx + xoff,ty + yoff,tz)
if(T)
turfstocapture.Add(T)
else
if(!hasasked)
var/answer = alert("Capture includes non existant turf, Continue capture?","Continue capture?", "No", "Yes")
hasasked = 1
if(answer == "No")
return
var/list/atoms = list()
for(var/turf/T in turfstocapture)
atoms.Add(T)
for(var/atom/A in T)
if(A.invisibility) continue
atoms.Add(A)
atoms = sort_atoms_by_layer(atoms)
var/icon/cap = icon('icons/effects/96x96.dmi', "")
cap.Scale(range*32, range*32)
cap.Blend("#000", ICON_OVERLAY)
for(var/atom/A in atoms)
if(A)
var/icon/img = getFlatIcon(A)
if(istype(img, /icon))
if(istype(A, /mob/living) && A:lying)
img.BecomeLying()
var/xoff = (A.x - tx) * 32
var/yoff = (A.y - ty) * 32
cap.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
var/cap = generate_image(tx ,ty ,tz ,range, CAPTURE_MODE_PARTIAL, null, 1, 1)
var/file_name = "map_capture_x[tx]_y[ty]_z[tz]_r[range].png"
usr << "Saved capture in cache as [file_name]."
usr << browse_rsc(cap, file_name)

View File

@@ -165,55 +165,6 @@ var/global/photo_count = 0
..()
/obj/item/device/camera/proc/get_icon(list/turfs, turf/center)
//Bigger icon base to capture those icons that were shifted to the next tile
//i.e. pretty much all wall-mounted machinery
var/icon/res = icon('icons/effects/96x96.dmi', "")
res.Scale(size*32, size*32)
// Initialize the photograph to black.
res.Blend("#000", ICON_OVERLAY)
var/atoms[] = list()
for(var/turf/the_turf in turfs)
// Add outselves to the list of stuff to draw
atoms.Add(the_turf);
// As well as anything that isn't invisible.
for(var/atom/A in the_turf)
if(A.invisibility) continue
atoms.Add(A)
// Sort the atoms into their layers
var/list/sorted = sort_atoms_by_layer(atoms)
var/center_offset = (size-1)/2 * 32 + 1
for(var/i; i <= sorted.len; i++)
var/atom/A = sorted[i]
if(A)
var/icon/img = getFlatIcon(A)//build_composite_icon(A)
// If what we got back is actually a picture, draw it.
if(istype(img, /icon))
// Check if we're looking at a mob that's lying down
if(istype(A, /mob/living) && A:lying)
// If they are, apply that effect to their picture.
img.BecomeLying()
// Calculate where we are relative to the center of the photo
var/xoff = (A.x - center.x) * 32 + center_offset
var/yoff = (A.y - center.y) * 32 + center_offset
if (istype(A,/atom/movable))
xoff+=A:step_x
yoff+=A:step_y
res.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
// Lastly, render any contained effects on top.
for(var/turf/the_turf in turfs)
// Calculate where we are relative to the center of the photo
var/xoff = (the_turf.x - center.x) * 32 + center_offset
var/yoff = (the_turf.y - center.y) * 32 + center_offset
res.Blend(getFlatIcon(the_turf.loc), blendMode2iconMode(the_turf.blend_mode),xoff,yoff)
return res
/obj/item/device/camera/proc/get_mobs(turf/the_turf as turf)
var/mob_detail
for(var/mob/living/carbon/A in the_turf)
@@ -248,37 +199,39 @@ var/global/photo_count = 0
icon_state = icon_on
on = 1
/obj/item/device/camera/proc/can_capture_turf(turf/T, mob/user)
//Proc for capturing check
/mob/living/proc/can_capture_turf(turf/T)
var/mob/dummy = new(T) //Go go visibility check dummy
var/viewer = user
if(user.client) //To make shooting through security cameras possible
viewer = user.client.eye
var/viewer = src
if(src.client) //To make shooting through security cameras possible
viewer = src.client.eye
var/can_see = (dummy in viewers(world.view, viewer))
qdel(dummy)
return can_see
/obj/item/device/camera/proc/captureimage(atom/target, mob/user, flag)
/obj/item/device/camera/proc/captureimage(atom/target, mob/living/user, flag)
var/x_c = target.x - (size-1)/2
var/y_c = target.y + (size-1)/2
var/z_c = target.z
var/list/turfs = list()
var/mobs = ""
for(var/i = 1; i <= size; i++)
for(var/j = 1; j <= size; j++)
var/turf/T = locate(x_c, y_c, z_c)
if(can_capture_turf(T, user))
turfs.Add(T)
if(user.can_capture_turf(T))
mobs += get_mobs(T)
x_c++
y_c--
x_c = x_c - size
var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag)
var/obj/item/weapon/photo/p = createpicture(target, user, mobs, flag)
printpicture(user, p)
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
var/icon/photoimage = get_icon(turfs, target)
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, mobs, flag)
var/x_c = target.x - (size-1)/2
var/y_c = target.y - (size-1)/2
var/z_c = target.z
var/icon/photoimage = generate_image(x_c, y_c, z_c, size, CAPTURE_MODE_REGULAR, user)
var/icon/small_img = icon(photoimage)
var/icon/tiny_img = icon(photoimage)

View File

@@ -69,8 +69,9 @@
aipictures -= selection
usr << "<span class='unconscious'>Local image deleted</span>"
/obj/item/device/camera/siliconcam/ai_camera/can_capture_turf(turf/T, mob/user)
var/mob/living/silicon/ai = user
//Capture Proc for AI / Robot
/mob/living/silicon/ai/can_capture_turf(turf/T)
var/mob/living/silicon/ai = src
return ai.TurfAdjacent(T)
/obj/item/device/camera/siliconcam/proc/toggle_camera_mode()