Skip to content

Commit

Permalink
Merge branch 'master' into Command-Area-Remake
Browse files Browse the repository at this point in the history
  • Loading branch information
LC4492 committed Oct 12, 2023
2 parents f9fd78c + d9250db commit 2f3069b
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 85 deletions.
176 changes: 107 additions & 69 deletions code/modules/paperwork/photography.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,119 +175,157 @@
res.Scale(size*32, size*32)
// Initialize the photograph to black.
res.Blend("#000", ICON_OVERLAY)
CHECK_TICK

var/atoms[] = list()
for(var/turf/the_turf in turfs)
// Add outselves to the list of stuff to draw
var/pixel_size = world.icon_size
var/radius = (size - 1) * 0.5
var/center_offset = radius * pixel_size + 1
var/x_min = center.x - radius
var/x_max = center.x + radius
var/y_min = center.y - radius
var/y_max = center.y + radius

var/list/atoms = list()
for(var/turf/the_turf as anything in turfs)
// Add ourselves 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)
for(var/atom/cur_atom as anything in the_turf)
if(!cur_atom || cur_atom.invisibility)
continue
atoms.Add(cur_atom)

// 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/IM = getFlatIcon(A)//build_composite_icon(A)

// If what we got back is actually a picture, draw it.
if(istype(IM, /icon))
// Check if we're looking at a mob that's lying down
if(istype(A, /mob/living))
var/mob/living/L = A
if(!istype(L, /mob/living/carbon/xenomorph)) //xenos don't use icon rotatin for lying.
if(L.lying)
// If they are, apply that effect to their picture.
IM.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(IM, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff)
for(var/atom/cur_atom as anything in sorted)
if(QDELETED(cur_atom))
continue

if(cur_atom.x < x_min || cur_atom.x > x_max || cur_atom.y < y_min || cur_atom.y > y_max)
// they managed to move out of frame with all this CHECK_TICK...
continue

var/icon/cur_icon = getFlatIcon(cur_atom)//build_composite_icon(cur_atom)

// If what we got back is actually a picture, draw it.
if(istype(cur_icon, /icon))
// Check if we're looking at a mob that's lying down
if(istype(cur_atom, /mob/living))
var/mob/living/cur_mob = cur_atom
if(!isxeno(cur_mob) && cur_mob.lying) //xenos don't use icon rotatin for lying.
cur_icon.BecomeLying()

// Calculate where we are relative to the center of the photo
var/xoff = (cur_atom.x - center.x) * pixel_size + center_offset
var/yoff = (cur_atom.y - center.y) * pixel_size + center_offset
if(istype(cur_atom, /atom/movable))
xoff += cur_atom:step_x
yoff += cur_atom:step_y
res.Blend(cur_icon, blendMode2iconMode(cur_atom.blend_mode), cur_atom.pixel_x + xoff, cur_atom.pixel_y + yoff)

CHECK_TICK

// Lastly, render any contained effects on top.
for(var/turf/the_turf as anything 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
var/image/IM = getFlatIcon(the_turf.loc)
if(IM)
res.Blend(IM, blendMode2iconMode(the_turf.blend_mode),xoff,yoff)
var/xoff = (the_turf.x - center.x) * pixel_size + center_offset
var/yoff = (the_turf.y - center.y) * pixel_size + center_offset
var/image/cur_icon = getFlatIcon(the_turf.loc)
CHECK_TICK

if(cur_icon)
res.Blend(cur_icon, blendMode2iconMode(the_turf.blend_mode), xoff, yoff)
CHECK_TICK
return res

/obj/item/device/camera/proc/get_mob_descriptions(turf/the_turf, existing_descripion)
var/mob_detail = existing_descripion
for(var/mob/living/carbon/cur_carbon in the_turf)
if(cur_carbon.invisibility)
continue

/obj/item/device/camera/proc/get_mobs(turf/the_turf as turf)
var/mob_detail
for(var/mob/living/carbon/A in the_turf)
if(A.invisibility) continue
var/holding = null
if(A.l_hand || A.r_hand)
if(A.l_hand) holding = "They are holding \a [A.l_hand]"
if(A.r_hand)
if(cur_carbon.l_hand || cur_carbon.r_hand)
if(cur_carbon.l_hand)
holding = "They are holding \a [cur_carbon.l_hand]"
if(cur_carbon.r_hand)
if(holding)
holding += " and \a [A.r_hand]"
holding += " and \a [cur_carbon.r_hand]"
else
holding = "They are holding \a [A.r_hand]"
holding = "They are holding \a [cur_carbon.r_hand]"

var/hurt = ""
if(cur_carbon.health < 75)
hurt = prob(25) ? " - they look hurt" : " - [cur_carbon] looks hurt"

if(!mob_detail)
mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
mob_detail = "You can see [cur_carbon] in the photo[hurt].[holding ? " [holding]" : "."]."
else
mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
mob_detail += " You [prob(50) ? "can" : "also"] see [cur_carbon] in the photo[hurt].[holding ? " [holding]" : "."]."
return mob_detail

/obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
if(!on || !pictures_left || ismob(target.loc) || isstorage(target.loc)) return
if(user.contains(target) || istype(target, /atom/movable/screen)) return
captureimage(target, user, flag)
if(!on || !pictures_left || ismob(target.loc) || isstorage(target.loc))
return
if(user.contains(target) || istype(target, /atom/movable/screen))
return

playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 15, 1)

pictures_left--
desc = "A polaroid camera. It has [pictures_left] photos left."
to_chat(user, SPAN_NOTICE("[pictures_left] photos left."))

captureimage(target, user, flag)

icon_state = icon_off
on = 0
spawn(64)
icon_state = icon_on
on = 1

/obj/item/device/camera/proc/captureimage(atom/target, mob/user, flag)
var/mobs = ""
var/mob_descriptions = ""
var/radius = (size-1)*0.5
var/list/turf/turfs = RANGE_TURFS(radius, target) & view(world_view_size + radius, user.client)
for(var/turf/T as anything in turfs)
mobs += get_mobs(T)
var/datum/picture/P = createpicture(target, user, turfs, mobs, flag)
printpicture(user, P)
for(var/turf/the_turf as anything in turfs)
mob_descriptions = get_mob_descriptions(the_turf, mob_descriptions)
var/datum/picture/the_picture = createpicture(target, user, turfs, mob_descriptions, flag)

/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
if(QDELETED(user))
return

printpicture(user, the_picture)

/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, description, flag)
var/icon/photoimage = get_icon(turfs, target)

if(!description)
description = "A very scenic photo"

var/icon/small_img = icon(photoimage)
var/icon/tiny_img = icon(photoimage)
var/icon/ic = icon('icons/obj/items/items.dmi',"photo")
var/icon/pc = icon('icons/obj/items/paper.dmi', "photo")
var/icon/item_icon = icon('icons/obj/items/items.dmi',"photo")
var/icon/paper_icon = icon('icons/obj/items/paper.dmi', "photo")
small_img.Scale(8, 8)
tiny_img.Scale(4, 4)
ic.Blend(small_img,ICON_OVERLAY, 10, 13)
pc.Blend(tiny_img,ICON_OVERLAY, 12, 19)

var/datum/picture/P = new()
P.fields["author"] = user
P.fields["icon"] = ic
P.fields["tiny"] = pc
P.fields["img"] = photoimage
P.fields["desc"] = mobs
P.fields["pixel_x"] = rand(-10, 10)
P.fields["pixel_y"] = rand(-10, 10)
P.fields["size"] = size

return P
item_icon.Blend(small_img, ICON_OVERLAY, 10, 13)
CHECK_TICK
paper_icon.Blend(tiny_img, ICON_OVERLAY, 12, 19)
CHECK_TICK

var/datum/picture/the_picture = new()
the_picture.fields["author"] = user
the_picture.fields["icon"] = item_icon
the_picture.fields["tiny"] = paper_icon
the_picture.fields["img"] = photoimage
the_picture.fields["desc"] = description
the_picture.fields["pixel_x"] = rand(-10, 10)
the_picture.fields["pixel_y"] = rand(-10, 10)
the_picture.fields["size"] = size

return the_picture

/obj/item/device/camera/proc/printpicture(mob/user, datum/picture/P)
var/obj/item/photo/Photo = new/obj/item/photo()
Expand Down
8 changes: 0 additions & 8 deletions html/changelogs/AutoChangeLog-pr-4540.yml

This file was deleted.

4 changes: 0 additions & 4 deletions html/changelogs/AutoChangeLog-pr-4600.yml

This file was deleted.

4 changes: 0 additions & 4 deletions html/changelogs/AutoChangeLog-pr-4619.yml

This file was deleted.

4 changes: 4 additions & 0 deletions html/changelogs/AutoChangeLog-pr-4636.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
author: "Drathek"
delete-after: True
changes:
- refactor: "Refactored camera code to be less blocking, use typechecks less often, and provide somewhat more fluid descriptions to photos."
15 changes: 15 additions & 0 deletions html/changelogs/archive/2023-10.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,18 @@
- rscdel: Predators can no longer see their or others cross-round honor count.
irRegularGuy646:
- bugfix: fixed new goggle's on helmet sprite
2023-10-12:
QuickLode:
- rscadd: Adds a handheld distress beacon for the Colonial Marshal. They can use
this to signal distress which in turn allows reinforcements in the form of Anchorpoint
Marine QRF or nearby CMB teams. Admins do the final check.
- rscadd: Adds a CMB Patrol Team which responds to "Marshals in Distress" call.
- admin: headset admin response no longer specifies USCM origin(as this is used
for USCM, WY, and now CMB)
- spellcheck: fixes a CMB typo in response message. Also a miniscule change to HG
37-12 desc.
- spellcheck: fixes 2 misc typos in CMB Inspections
harryob:
- rscadd: origin descriptions are now displayed when selecting an origin
mullenpaul:
- ui: tweaked flyby controls to make them in line with other destinations

0 comments on commit 2f3069b

Please sign in to comment.