diff --git a/aurorastation.dme b/aurorastation.dme index 7228a4c8069..116adf98b06 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -839,6 +839,7 @@ #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\radio_jammer.dm" #include "code\game\objects\items\devices\scanners.dm" +#include "code\game\objects\items\devices\slide_projector.dm" #include "code\game\objects\items\devices\spy_bug.dm" #include "code\game\objects\items\devices\suit_cooling.dm" #include "code\game\objects\items\devices\t_scanner.dm" diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 4b417bd00b2..4163c8b2ef9 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -41,11 +41,6 @@ return copytext(rank, 2+length(prefix)) return rank -/obj/effect/projection - name = "Projection" - desc = "This looks like a projection of something." - anchored = 1.0 - /obj/structure/showcase name = "Showcase" icon = 'icons/obj/stationobjs.dmi' diff --git a/code/game/objects/items/devices/slide_projector.dm b/code/game/objects/items/devices/slide_projector.dm new file mode 100644 index 00000000000..e046d43af88 --- /dev/null +++ b/code/game/objects/items/devices/slide_projector.dm @@ -0,0 +1,205 @@ +/obj/item/storage/slide_projector + name = "slide projector" + desc = "A handy device capable of showing an enlarged projection of whatever you can fit inside." + desc_info = "You can use this in hand to open the interface, click-dragging it to you also works. Click anywhere with it in your hand to project at that location. Click dragging it to that location also works." + icon = 'icons/obj/projector.dmi' + icon_state = "projector0" + max_w_class = ITEMSIZE_SMALL + max_storage_space = 10 + use_sound = 'sound/items/storage/toolbox.ogg' + var/static/list/projection_types = list( + /obj/item/photo = /obj/effect/projection/photo, + /obj/item/paper = /obj/effect/projection/paper, + /obj/item = /obj/effect/projection + ) + var/obj/item/current_slide + var/obj/effect/projection/projection + +/obj/item/storage/slide_projector/Destroy() + QDEL_NULL(current_slide) + QDEL_NULL(projection) + return ..() + +/obj/item/storage/slide_projector/update_icon() + icon_state = "projector[!!projection]" + +/obj/item/storage/slide_projector/remove_from_storage(obj/item/W) + . = ..() + if(. && W == current_slide) + set_slide(length(contents) ? contents[1] : null) + +/obj/item/storage/slide_projector/handle_item_insertion(var/obj/item/W) + . = ..() + if(. && !current_slide) + set_slide(W) + +/obj/item/storage/slide_projector/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(!current_slide) + to_chat(user, SPAN_WARNING("\The [src] does not have a slide loaded.")) + return + project_at(get_turf(target)) + +/obj/item/storage/slide_projector/MouseDrop(atom/over) + if(use_check_and_message(usr)) + return + + if(over == usr) + interact(usr) + return + + var/turf/T = get_turf(over) + if(istype(T)) + afterattack(over, usr) + +/obj/item/storage/slide_projector/proc/set_slide(obj/item/new_slide) + current_slide = new_slide + playsound(loc, 'sound/machines/slide_change.ogg', 50) + if(projection) + project_at(get_turf(projection)) + +/obj/item/storage/slide_projector/proc/check_projections() + if(!projection) + return + if(!(projection in view(7,get_turf(src)))) + stop_projecting() + +/obj/item/storage/slide_projector/proc/stop_projecting() + if(projection) + QDEL_NULL(projection) + moved_event.unregister(src, src, .proc/check_projections) + set_light(0) + update_icon() + +/obj/item/storage/slide_projector/proc/project_at(turf/target) + stop_projecting() + if(!current_slide) + return + var/projection_type + for(var/T in projection_types) + if(istype(current_slide, T)) + projection_type = projection_types[T] + break + projection = new projection_type(target) + projection.set_source(current_slide) + moved_event.register(src, src, .proc/check_projections) + set_light(1.4, 0.1, COLOR_WHITE) //Bit of light + update_icon() + +/obj/item/storage/slide_projector/attack_self(mob/user) + interact(user) + +/obj/item/storage/slide_projector/interact(mob/user) + var/data = list() + if(projection) + data += "Disable Projector" + else + data += "Projector Inactive" + + var/table = list("") + var/i = 1 + for(var/obj/item/I in contents) + table += "" + if(I == current_slide) + table += "" + else + table += "" + table += "" + i++ + table += "
#SLIDESHOW
#[i][I.name]SHOWING[I.name]SHOW
" + data += jointext(table,null) + + var/datum/browser/popup = new(user, "slides\ref[src]", "Slide Projector") + popup.set_content(jointext(data, "
")) + popup.open() + +/obj/item/storage/slide_projector/Topic(href, href_list) + . = ..() + if(.) + return + + if(href_list["stop_projector"]) + if(!projection) + return TRUE + stop_projecting() + . = FALSE + + if(href_list["set_active"]) + var/index = text2num(href_list["set_active"]) + if(index < 1 || index > contents.len) + return TRUE + set_slide(contents[index]) + . = FALSE + + interact(usr) + +/obj/effect/projection + name = "projected slide" + icon = 'icons/effects/effects.dmi' + icon_state = "white" + anchored = TRUE + simulated = FALSE + layer = EFFECTS_ABOVE_LIGHTING_LAYER + alpha = 100 + var/datum/weakref/source + +/obj/effect/projection/Initialize() + . = ..() + set_light(1.4, 0.1, COLOR_WHITE) //Makes turning off the lights not invalidate projection + +/obj/effect/projection/update_icon() + filters = filter(type="drop_shadow", color = COLOR_WHITE, size = 4, offset = 1,x = 0, y = 0) + project_icon() + +/obj/effect/projection/proc/project_icon() + var/obj/item/I = source.resolve() + if(!istype(I)) + qdel(src) + return + cut_overlays() + var/mutable_appearance/MA = new(I) + MA.layer = EFFECTS_ABOVE_LIGHTING_LAYER + MA.appearance_flags = RESET_ALPHA + MA.alpha = 170 + MA.pixel_x = 0 + MA.pixel_y = 0 + overlays |= MA + +/obj/effect/projection/proc/set_source(obj/item/I) + source = WEAKREF(I) + desc = "It's currently showing \the [I]." + update_icon() + +/obj/effect/projection/examine(mob/user, distance) + . = ..() + var/obj/item/slide = source.resolve() + if(!istype(slide)) + qdel(src) + return + return slide.examine(user, 1) + +/obj/effect/projection/photo + alpha = 170 + +/obj/effect/projection/photo/project_icon() + var/obj/item/photo/slide = source.resolve() + if(!istype(slide)) + qdel(src) + return + icon = slide.img + transform = matrix() + transform *= 1 / slide.photo_size + pixel_x = -32 * round(slide.photo_size/2) + pixel_y = -32 * round(slide.photo_size/2) + +/obj/effect/projection/paper + alpha = 140 + blend_mode = BLEND_ADD + +/obj/effect/projection/paper/project_icon() + var/obj/item/paper/P = source.resolve() + if(!istype(P)) + qdel(src) + return + cut_overlays() + if(P.info) + icon_state = "text[rand(1,3)]" \ No newline at end of file diff --git a/html/changelogs/geeves-slide_projector.yml b/html/changelogs/geeves-slide_projector.yml new file mode 100644 index 00000000000..9c07b28005d --- /dev/null +++ b/html/changelogs/geeves-slide_projector.yml @@ -0,0 +1,6 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Added slide projectors, capable of projecting an image of any small item onto any turf." \ No newline at end of file diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 4b0657a6419..939711f7bef 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/obj/projector.dmi b/icons/obj/projector.dmi new file mode 100644 index 00000000000..6e4012c09e7 Binary files /dev/null and b/icons/obj/projector.dmi differ diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm index 6ea4d8e56af..d2a206d3729 100644 --- a/maps/aurora/aurora-4_mainlevel.dmm +++ b/maps/aurora/aurora-4_mainlevel.dmm @@ -5113,6 +5113,7 @@ pixel_y = 9 }, /obj/item/pen, +/obj/item/storage/slide_projector, /turf/simulated/floor/tiled/white, /area/crew_quarters/sleep/research) "aki" = ( @@ -23566,6 +23567,9 @@ "aOS" = ( /obj/structure/table/wood, /obj/item/modular_computer/laptop/preset/security/hos, +/obj/item/storage/slide_projector{ + pixel_y = 12 + }, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hos) "aOT" = ( @@ -24277,6 +24281,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/item/storage/slide_projector, /turf/simulated/floor/carpet, /area/crew_quarters/captain) "aPZ" = ( @@ -25430,6 +25435,9 @@ }, /obj/item/folder/yellow, /obj/item/stamp/ce, +/obj/item/storage/slide_projector{ + pixel_y = 12 + }, /turf/simulated/floor/carpet, /area/crew_quarters/heads/chief) "aRV" = ( @@ -26997,6 +27005,9 @@ /obj/effect/floor_decal/spline/fancy/wood{ dir = 4 }, +/obj/item/storage/slide_projector{ + pixel_y = 16 + }, /turf/simulated/floor/carpet, /area/bridge/meeting_room) "aUD" = ( @@ -28477,6 +28488,9 @@ }, /obj/item/toy/figure/corgi, /obj/item/device/megaphone/command, +/obj/item/storage/slide_projector{ + pixel_y = 12 + }, /turf/simulated/floor/wood, /area/crew_quarters/heads/hop) "aXq" = ( @@ -35419,6 +35433,7 @@ /obj/effect/floor_decal/corner_wide/paleblue/full{ dir = 8 }, +/obj/item/storage/slide_projector, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) "bjo" = ( @@ -44382,6 +44397,9 @@ "bBz" = ( /obj/structure/table/standard, /obj/item/modular_computer/laptop/preset/research/rd, +/obj/item/storage/slide_projector{ + pixel_y = 12 + }, /turf/simulated/floor/carpet/blue, /area/rnd/rdoffice) "bBB" = ( @@ -68370,6 +68388,7 @@ dir = 6 }, /obj/item/book/manual/wiki/security_space_law, +/obj/item/storage/slide_projector, /turf/simulated/floor/tiled/dark, /area/security/forensics_office{ name = "Security - Investigations Office" @@ -69962,6 +69981,11 @@ /obj/effect/decal/cleanable/liquid_fuel, /turf/simulated/floor/carpet/rubber, /area/maintenance/workshop) +"whV" = ( +/obj/structure/table/wood/gamblingtable, +/obj/item/storage/slide_projector, +/turf/simulated/floor/lino/grey, +/area/engineering/foyer) "wil" = ( /obj/effect/floor_decal/corner/grey/diagonal, /obj/structure/closet/secure_closet/freezer/kitchen, @@ -91097,7 +91121,7 @@ aAF aCc aDU aFL -oKJ +whV oKJ aLc aMS diff --git a/maps/aurora/aurora-5_interstitial.dmm b/maps/aurora/aurora-5_interstitial.dmm index 1c91c44b0b2..6dc82f2cad6 100644 --- a/maps/aurora/aurora-5_interstitial.dmm +++ b/maps/aurora/aurora-5_interstitial.dmm @@ -2432,7 +2432,7 @@ /turf/simulated/floor/plating, /area/security/training_theoretical) "fA" = ( -/obj/structure/banner, +/obj/structure/banner/scc, /turf/simulated/floor/wood, /area/security/training_theoretical) "fB" = ( @@ -2442,16 +2442,7 @@ }, /turf/simulated/floor/wood, /area/security/training_theoretical) -"fC" = ( -/obj/structure/sign/double/map/left{ - pixel_y = 32 - }, -/turf/simulated/floor/wood, -/area/security/training_theoretical) "fD" = ( -/obj/structure/sign/double/map/right{ - pixel_y = 32 - }, /obj/effect/landmark/start{ name = "Warden" }, @@ -2473,8 +2464,7 @@ /area/security/training_theoretical) "fF" = ( /obj/structure/bed/chair/comfy/sofa/left{ - dir = 4; - icon_state = "sofaend_left_preview" + dir = 4 }, /turf/simulated/floor/wood, /area/security/break_room) @@ -2515,6 +2505,9 @@ "fX" = ( /obj/structure/table/wood, /obj/item/folder/sec, +/obj/item/storage/slide_projector{ + pixel_x = -16 + }, /turf/simulated/floor/wood, /area/security/training_theoretical) "fY" = ( @@ -2542,22 +2535,19 @@ /area/security/training_theoretical) "gb" = ( /obj/structure/bed/chair/comfy/sofa/corner{ - dir = 4; - icon_state = "sofacorner_preview" + dir = 4 }, /turf/simulated/floor/wood, /area/security/break_room) "gc" = ( /obj/structure/bed/chair/comfy/sofa{ - dir = 1; - icon_state = "sofamiddle_preview" + dir = 1 }, /turf/simulated/floor/wood, /area/security/break_room) "gd" = ( /obj/structure/bed/chair/comfy/sofa/left{ - dir = 1; - icon_state = "sofaend_left_preview" + dir = 1 }, /obj/machinery/light, /turf/simulated/floor/wood, @@ -44847,7 +44837,7 @@ eJ eW fh rp -fC +fZ fY gq gH diff --git a/sound/machines/slide_change.ogg b/sound/machines/slide_change.ogg new file mode 100644 index 00000000000..129af6db727 Binary files /dev/null and b/sound/machines/slide_change.ogg differ