diff --git a/code/game/objects/items/tools/misc_tools.dm b/code/game/objects/items/tools/misc_tools.dm index 44aaab771db8..f868c6d5ab24 100644 --- a/code/game/objects/items/tools/misc_tools.dm +++ b/code/game/objects/items/tools/misc_tools.dm @@ -415,6 +415,10 @@ name = "\improper DENIED rubber stamp" icon_state = "stamp-deny" +/obj/item/tool/stamp/approved + name = "\improper APPROVED rubber stamp" + icon_state = "stamp-approve" + /obj/item/tool/stamp/clown name = "clown's rubber stamp" icon_state = "stamp-clown" diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 9d007a0c8c80..0c763378ede1 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -1,80 +1,111 @@ +#define MAX_NOTICES 8 + /obj/structure/noticeboard name = "notice board" desc = "A board for pinning important notices upon." icon = 'icons/obj/structures/props/stationobjs.dmi' - icon_state = "nboard00" + icon_state = "noticeboard" density = FALSE anchored = TRUE var/notices = 0 -/obj/structure/noticeboard/Initialize() +/obj/structure/noticeboard/Initialize(mapload) . = ..() + if(!mapload) + return + for(var/obj/item/I in loc) - if(notices > 4) break + if(notices >= MAX_NOTICES) + break if(istype(I, /obj/item/paper)) I.forceMove(src) notices++ - icon_state = "nboard0[notices]" + update_overlays() //attaching papers!! -/obj/structure/noticeboard/attackby(obj/item/O as obj, mob/user as mob) - if(istype(O, /obj/item/paper)) - if(notices < 5) - O.add_fingerprint(user) - add_fingerprint(user) - user.drop_held_item() - O.forceMove(src) +/obj/structure/noticeboard/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo)) + if(!allowed(user)) + to_chat(user, SPAN_WARNING("You are not authorized to add notices!")) + return + if(notices < MAX_NOTICES) + if(!user.drop_inv_item_to_loc(O, src)) + return notices++ - icon_state = "nboard0[notices]" //update sprite - to_chat(user, SPAN_NOTICE("You pin the paper to the noticeboard.")) + update_overlays() + to_chat(user, SPAN_NOTICE("You pin the [O] to the noticeboard.")) else - to_chat(user, SPAN_NOTICE("You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.")) + to_chat(user, SPAN_WARNING("The notice board is full!")) + else if(istype(O, /obj/item/tool/pen)) + user.set_interaction(src) + tgui_interact(user) + else + return ..() -/obj/structure/noticeboard/attack_hand(user as mob) - var/dat = "Noticeboard
" - for(var/obj/item/paper/P in src) - dat += "[P.name] Write Remove
" - user << browse("Notices[dat]","window=noticeboard") - onclose(user, "noticeboard") +/obj/structure/noticeboard/attack_hand(mob/user) + . = ..() + user.set_interaction(src) + tgui_interact(user) +/obj/structure/noticeboard/ui_state(mob/user) + return GLOB.physical_state -/obj/structure/noticeboard/Topic(href, href_list) - ..() - usr.set_interaction(src) - if(href_list["remove"]) - if((usr.stat || usr.is_mob_restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["remove"]) - if((P && P.loc == src)) - P.forceMove(get_turf(src) )//dump paper on the floor because you're a clumsy fuck - P.add_fingerprint(usr) - add_fingerprint(usr) - notices-- - icon_state = "nboard0[notices]" +/obj/structure/noticeboard/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NoticeBoard", name) + ui.open() - if(href_list["write"]) - if((usr.stat || usr.is_mob_restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["write"]) +/obj/structure/noticeboard/ui_data(mob/user) + var/list/data = list() + data["allowed"] = allowed(user) + data["items"] = list() + for(var/obj/item/content in contents) + var/list/content_data = list( + name = content.name, + ref = REF(content) + ) + data["items"] += list(content_data) + return data + +/obj/structure/noticeboard/ui_act(action, params) + . = ..() + if(.) + return + + var/obj/item/item = locate(params["ref"]) in contents + if(!istype(item) || item.loc != src) + return + + var/mob/user = usr + + switch(action) + if("examine") + user.examinate(item) + return TRUE + if("write") + var/obj/item/writing_tool = user.get_held_item() + if(!istype(writing_tool, /obj/item/tool/pen)) + balloon_alert(user, "you need a pen for that!") + return + item.attackby(writing_tool, user) + return TRUE + if("remove") + if(!allowed(user)) + return + remove_item(item, user) + return TRUE + +/obj/structure/noticeboard/proc/update_overlays() + if(overlays) overlays.Cut() + if(notices) + overlays += image(icon, "notices_[notices]") - if((P && P.loc == src)) //ifthe paper's on the board - if(HAS_TRAIT(usr.r_hand, TRAIT_TOOL_PEN)) - add_fingerprint(usr) - P.attackby(usr.r_hand, usr) //then do ittttt - else - if(HAS_TRAIT(usr.l_hand, TRAIT_TOOL_PEN)) //check other hand for pen - add_fingerprint(usr) - P.attackby(usr.l_hand, usr) - else - to_chat(usr, SPAN_NOTICE("You'll need something to write with!")) +/obj/structure/noticeboard/proc/remove_item(obj/item/item, mob/user) + item.forceMove(loc) + if(user) + user.put_in_hands(item) + balloon_alert(user, "removed from board") + notices-- + update_overlays() - if(href_list["read"]) - var/obj/item/paper/P = locate(href_list["read"]) - if((P && P.loc == src)) - if(!( istype(usr, /mob/living/carbon/human) )) - usr << browse("[P.name][stars(P.info)]", "window=[P.name]") - onclose(usr, "[P.name]") - else - usr << browse("[P.name][P.info]", "window=[P.name]") - onclose(usr, "[P.name]") - return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 8220f60e77ed..2adfa1bde4c9 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -361,8 +361,8 @@ iscrayon = 1 - // if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr - if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/clipboard) || istype(src.loc, /obj/item/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) ) + // if paper is not in usr, then it must be near them, or in a clipboard, noticeboard or folder, which must be in or near usr + if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/clipboard) || istype(src.loc, /obj/structure/noticeboard) || istype(src.loc, /obj/item/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) ) return t = replacetext(t, "\n", "
") diff --git a/icons/obj/items/paper.dmi b/icons/obj/items/paper.dmi index c39fede23679..fa8858e8a17b 100644 Binary files a/icons/obj/items/paper.dmi and b/icons/obj/items/paper.dmi differ diff --git a/icons/obj/structures/props/stationobjs.dmi b/icons/obj/structures/props/stationobjs.dmi index 66c396f41d12..8d0bf3b9377d 100644 Binary files a/icons/obj/structures/props/stationobjs.dmi and b/icons/obj/structures/props/stationobjs.dmi differ diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index 26c9816ca0c3..f047ade15661 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -17731,11 +17731,9 @@ }, /area/almayer/squads/req) "bEt" = ( -/obj/structure/machinery/light{ - dir = 1 - }, -/obj/structure/sign/safety/commline_connection{ - pixel_y = 32 +/obj/structure/noticeboard{ + pixel_x = -10; + pixel_y = 31 }, /turf/open/floor/almayer{ dir = 5; @@ -34821,6 +34819,7 @@ /obj/structure/surface/table/almayer, /obj/item/storage/firstaid/regular, /obj/item/clipboard, +/obj/item/tool/pen, /turf/open/floor/almayer{ icon_state = "plate" }, @@ -41181,6 +41180,10 @@ /obj/structure/machinery/prop/almayer/computer/PC{ dir = 4 }, +/obj/item/tool/stamp/approved{ + pixel_y = -11; + pixel_x = -3 + }, /turf/open/floor/almayer, /area/almayer/squads/req) "iVo" = ( @@ -48294,6 +48297,7 @@ /obj/structure/surface/table/almayer, /obj/effect/spawner/random/toolbox, /obj/item/clipboard, +/obj/item/tool/pen, /turf/open/floor/almayer{ dir = 8; icon_state = "green" @@ -59729,8 +59733,8 @@ "pWA" = ( /obj/structure/machinery/disposal, /obj/structure/disposalpipe/trunk, -/obj/structure/sign/safety/storage{ - pixel_x = -17 +/obj/structure/machinery/light{ + dir = 8 }, /turf/open/floor/almayer{ dir = 8; @@ -65349,6 +65353,14 @@ /obj/structure/pipes/vents/scrubber{ dir = 4 }, +/obj/structure/sign/safety/storage{ + pixel_y = 7; + pixel_x = -17 + }, +/obj/structure/sign/safety/commline_connection{ + pixel_x = -17; + pixel_y = -7 + }, /turf/open/floor/almayer{ dir = 8; icon_state = "green" @@ -123626,7 +123638,7 @@ bdl lOr lOr iwI -lOr +bdl bdl bEt bNP diff --git a/tgui/packages/tgui/interfaces/NoticeBoard.tsx b/tgui/packages/tgui/interfaces/NoticeBoard.tsx new file mode 100644 index 000000000000..6cc761c0fb6f --- /dev/null +++ b/tgui/packages/tgui/interfaces/NoticeBoard.tsx @@ -0,0 +1,56 @@ +import { BooleanLike } from 'common/react'; + +import { useBackend } from '../backend'; +import { Box, Button, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type Data = { + allowed: BooleanLike; + items: { ref: string; name: string }[]; +}; + +export const NoticeBoard = (props, context) => { + const { act, data } = useBackend(context); + const { allowed, items = [] } = data; + + return ( + + + {!items.length ? ( +
+ + The notice board is empty! + +
+ ) : ( + items.map((item) => ( + + + {item.name} + + +