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 b572b5d9e87b..4c06545c53b2 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -362,8 +362,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 1c56dc0400ee..321a575854dd 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -19428,11 +19428,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;
@@ -43397,6 +43395,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" = (
@@ -60739,8 +60741,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;
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}
+
+
+
+
+ ))
+ )}
+
+
+ );
+};