diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index 5dd0707fcb9..1e62b6a5a9e 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -352,12 +352,12 @@ obj/structure/sign/poster/attackby(obj/item/I, mob/user, params) if(!P.resulting_poster) return var/stuff_on_wall = 0 - for(var/obj/O in contents) //Let's see if it already has a poster on it or too much stuff - if(istype(O,/obj/structure/sign/poster)) + for(var/obj/O in user.loc.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O,/obj/structure/sign)) user << "The wall is far too cluttered to place a poster!" return stuff_on_wall++ - if(stuff_on_wall == 3) + if(stuff_on_wall >= 4) user << "The wall is far too cluttered to place a poster!" return diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 11db68ec671..f90fe9cbb02 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -152,6 +152,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("wooden picture frame", /obj/item/weapon/picture_frame/wooden, 1), \ new/datum/stack_recipe("wooden buckler", /obj/item/weapon/shield/riot/buckler, 20, time = 40), \ ) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 90792b54602..6604649ad4c 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -111,14 +111,16 @@ var/global/list/globalBlankCanvases[AMT_OF_CANVASES] if(thePix != theOriginalPix) //colour changed DrawPixelOn(theOriginalPix,pixX,pixY) qdel(masterpiece) - return + return 1 //Drawing one pixel with a crayon if(istype(I, /obj/item/toy/crayon)) var/obj/item/toy/crayon/C = I - if(masterpiece.GetPixel(pixX, pixY)) // if the located pixel isn't blank (null)) + var/pix = masterpiece.GetPixel(pixX, pixY) + if(pix && pix != C.colour) // if the located pixel isn't blank (null)) DrawPixelOn(C.colour, pixX, pixY) - return + qdel(masterpiece) + return 1 ..() diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm new file mode 100644 index 00000000000..f8592e35c5d --- /dev/null +++ b/code/modules/paperwork/frames.dm @@ -0,0 +1,315 @@ +/obj/item/weapon/picture_frame + name = "picture frame" + desc = "Its patented design allows it to be folded larger or smaller to accommodate standard paper, photo, and poster, and canvas sizes." + icon = 'icons/obj/bureaucracy.dmi' + + var/icon_base + var/obj/displayed + + var/list/wide_posters = list( + "poster22_legit", "poster23", "poster23_legit", "poster24", "poster24_legit", + "poster25", "poster27_legit", "poster28", "poster29") + +/obj/item/weapon/picture_frame/New(loc, obj/item/weapon/D) + ..() + if(D) + insert(D) + update_icon() + +/obj/item/weapon/picture_frame/Destroy() + if(displayed) + displayed = null + for(var/A in contents) + qdel(A) + return ..() + +/obj/item/weapon/picture_frame/update_icon() + overlays.Cut() + + if(displayed) + overlays |= getFlatIcon(displayed) + + if(istype(displayed, /obj/item/weapon/photo)) + icon_state = "[icon_base]-photo" + else if(istype(displayed, /obj/structure/sign/poster)) + icon_state = "[icon_base]-[(displayed.icon_state in wide_posters) ? "wposter" : "poster"]" + else if(istype(displayed, /obj/item/weapon/canvas)) + icon_state = "[icon_base]-canvas-[displayed.icon_state]" + else + icon_state = "[icon_base]-paper" + + overlays |= icon_state + +/obj/item/weapon/picture_frame/proc/insert(obj/D) + if(istype(D, /obj/item/weapon/contraband/poster)) + var/obj/item/weapon/contraband/poster/P = D + displayed = P.resulting_poster + P.resulting_poster = null + else + displayed = D + + name = displayed.name + displayed.pixel_x = 0 + displayed.pixel_y = 0 + displayed.forceMove(src) + if(istype(D, /obj/item/weapon/contraband/poster)) + qdel(D) + +/obj/item/weapon/picture_frame/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + if(displayed) + playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) + user.visible_message("[user] unfastens \the [displayed] out of \the [src].", "You unfasten \the [displayed] out of \the [src].") + + if(istype(displayed, /obj/structure/sign/poster)) + var/obj/structure/sign/poster/P = displayed + P.roll_and_drop(user.loc) + else + displayed.forceMove(user.loc) + displayed = null + name = initial(name) + update_icon() + else + user << "There is nothing to remove from \the [src]." + else if(istype(I, /obj/item/weapon/crowbar)) + playsound(src, 'sound/items/Crowbar.ogg', 100, 1) + user.visible_message("[user] breaks down \the [src].", "You break down \the [src].") + for(var/A in contents) + if(istype(A, /obj/structure/sign/poster)) + var/obj/structure/sign/poster/P = A + P.roll_and_drop(user.loc) + else + var/obj/O = A + O.forceMove(user.loc) + displayed = null + qdel(src) + else if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/contraband/poster) || istype(I, /obj/item/weapon/canvas)) + if(!displayed) + user.unEquip(I) + insert(I) + update_icon() + else + user << "\The [src] already contains \a [displayed]." + else + return ..() + +/obj/item/weapon/picture_frame/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag && istype(target, /turf/simulated/wall)) + place(target, user) + else + ..() + +/obj/item/weapon/picture_frame/proc/place(turf/T, mob/user) + var/stuff_on_wall = 0 + for(var/obj/O in user.loc.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O, /obj/structure/sign)) + user << "\The [T] is far too cluttered to place \a [src]!" + return + stuff_on_wall++ + if(stuff_on_wall >= 4) + user << "\The [T] is far too cluttered to place \a [src]!" + return + + user << "You start place \the [src] on \the [T]." + + var/px = 0 + var/py = 0 + var/newdir = getRelativeDirection(user, T) + + switch(newdir) + if(NORTH) + py = 32 + if(EAST) + px = 32 + if(SOUTH) + py = -32 + if(WEST) + px = -32 + else + user << "You cannot reach \the [T] from here!" + return + + user.unEquip(src) + var/obj/structure/sign/picture_frame/PF = new(user.loc, src) + PF.dir = newdir + PF.pixel_x = px + PF.pixel_y = py + + playsound(PF.loc, 'sound/items/Deconstruct.ogg', 100, 1) + +/obj/item/weapon/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "") + ..() + if(displayed) + displayed.examine(user, distance, infix, suffix) + +/obj/item/weapon/picture_frame/attack_self(mob/user) + if(displayed) + if(istype(displayed, /obj/item)) + var/obj/item/I = displayed + I.attack_self(user) + else + ..() + + + +/obj/item/weapon/picture_frame/glass + icon_base = "glass" + icon_state = "glass-poster" + materials = list(MAT_METAL = 25, MAT_GLASS = 75) + +/obj/item/weapon/picture_frame/wooden + icon_base = "wood" + icon_state = "wood-poster" + +/obj/item/weapon/picture_frame/wooden/New() + ..() + new /obj/item/stack/sheet/wood(src, 1) + + + +/obj/structure/sign/picture_frame + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "glass-poster" + + var/obj/item/weapon/picture_frame/frame + var/obj/item/weapon/explosive + + var/tilted = 0 + var/tilt_transform = null + +/obj/structure/sign/picture_frame/New(loc, F) + ..() + frame = F + frame.pixel_x = 0 + frame.pixel_y = 0 + frame.forceMove(src) + name = frame.name + update_icon() + + if(!tilt_transform) + tilt_transform = turn(matrix(), -10) + + if(tilted) + transform = tilt_transform + verbs |= /obj/structure/sign/picture_frame/proc/untilt + else + verbs |= /obj/structure/sign/picture_frame/proc/tilt + +/obj/structure/sign/picture_frame/Destroy() + if(frame) + qdel(frame) + frame = null + return ..() + +/obj/structure/sign/picture_frame/update_icon() + overlays.Cut() + if(frame) + icon = null + icon_state = null + overlays |= getFlatIcon(frame) + else + icon = initial(icon) + icon_state = initial(icon_state) + +/obj/structure/sign/picture_frame/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) + user.visible_message("[user] begins to unfasten \the [src] from the wall.", "You begin to unfasten \the [src] from the wall.") + if(do_after(user, 100, target = src)) + playsound(src, 'sound/items/Deconstruct.ogg', 100, 1) + user.visible_message("[user] unfastens \the [src] from the wall.", "You unfasten \the [src] from the wall.") + frame.forceMove(user.loc) + frame = null + if(explosive) + explosive.forceMove(user.loc) + explosive = null + qdel(src) + if(istype(I, /obj/item/weapon/grenade) || istype(I, /obj/item/weapon/c4)) + if(explosive) + user << "There is already a device attached behind \the [src], remove it first." + return 1 + if(!tilted) + user << "\The [src] needs to be already tilted before being rigged with \the [I]." + return 1 + user.visible_message("[user] is fiddling around behind \the [src].", "You begin to secure \the [I] behind \the [src].") + if(do_after(user, 150, target = src)) + if(explosive || !tilted) + return + playsound(src, 'sound/weapons/handcuffs.ogg', 50, 1) + user.unEquip(I) + explosive = I + I.forceMove(src) + user.visible_message("[user] fiddles with the back of \the [src].", "You secure \the [I] behind \the [src].") + + message_admins("[key_name_admin(user)] attached [I] to a picture frame.") + log_game("[key_name_admin(user)] attached [I] to a picture frame.") + return 1 + else + return ..() + +/obj/structure/sign/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "") + if(frame) + frame.examine(user, distance, infix, suffix) + else + ..() + +/obj/structure/sign/picture_frame/attack_hand(mob/user) + if(frame) + frame.attack_self(user) + else + ..() + +/obj/structure/sign/picture_frame/ex_act(severity) + explode() + ..(severity) + +/obj/structure/sign/picture_frame/proc/explode() + if(istype(explosive, /obj/item/weapon/grenade)) + var/obj/item/weapon/grenade/G = explosive + explosive = null + G.prime() + else if(istype(explosive, /obj/item/weapon/c4)) + var/obj/item/weapon/c4/C = explosive + explosive = null + C.target = get_step(get_turf(src), dir) + C.explode(get_turf(loc)) + +/obj/structure/sign/picture_frame/proc/toggle_tilt(mob/user) + if(!isliving(usr) || usr.stat) + return + + tilted = !tilted + + if(tilted) + animate(src, transform = tilt_transform, time = 10, easing = BOUNCE_EASING) + verbs -= /obj/structure/sign/picture_frame/proc/tilt + verbs |= /obj/structure/sign/picture_frame/proc/untilt + else + animate(src, transform = matrix(), time = 10, easing = CUBIC_EASING | EASE_IN) + verbs -= /obj/structure/sign/picture_frame/proc/untilt + verbs |= /obj/structure/sign/picture_frame/proc/tilt + explode() + +/obj/structure/sign/picture_frame/proc/tilt() + set name = "Tilt Picture" + set category = "Object" + set src in oview(1) + + toggle_tilt(usr) + +/obj/structure/sign/picture_frame/proc/untilt() + set name = "Straighten Picture" + set category = "Object" + set src in oview(1) + + toggle_tilt(usr) + +/obj/structure/sign/picture_frame/hear_talk(mob/living/M as mob, msg) + ..() + for(var/obj/O in contents) + O.hear_talk(M, msg) + +/obj/structure/sign/picture_frame/hear_message(mob/living/M as mob, msg) + ..() + for(var/obj/O in contents) + O.hear_message(M, msg) \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 6e5bcf0389b..68b0090e317 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -273,6 +273,14 @@ materials = list(MAT_METAL = 100) build_path = /obj/item/weapon/canvas/twentythreeXtwentythree category = list("initial", "Miscellaneous") + +/datum/design/glass_picture_frame + name = "Glass Picture Frame" + id = "glass_picture_frame" + build_type = AUTOLATHE + materials = list(MAT_METAL = 25, MAT_GLASS = 75) + build_path = /obj/item/weapon/picture_frame/glass + category = list("initial", "Miscellaneous") /datum/design/camera_assembly name = "Camera Assembly" diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 159d2f572f2..1bd8373670c 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi index 4a187225cd3..91432c14d1a 100644 Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ diff --git a/paradise.dme b/paradise.dme index 4c6959933ec..b611994a112 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1585,6 +1585,7 @@ #include "code\modules\paperwork\faxmachine.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" +#include "code\modules\paperwork\frames.dm" #include "code\modules\paperwork\handlabeler.dm" #include "code\modules\paperwork\paper.dm" #include "code\modules\paperwork\paper_bundle.dm"