diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index e13fc820f97..51afa5dc30e 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -1,3 +1,5 @@
+#define MAX_NOTICES 5
+
/obj/structure/noticeboard
name = "notice board"
desc = "A board for pinning important notices upon."
@@ -6,6 +8,7 @@
density = FALSE
anchored = TRUE
max_integrity = 150
+ /// Current number of a pinned notices
var/notices = 0
/obj/structure/noticeboard/directional/north
@@ -31,7 +34,7 @@
return
for(var/obj/item/I in loc)
- if(notices > 4)
+ if(notices >= MAX_NOTICES)
break
if(istype(I, /obj/item/paper))
I.forceMove(src)
@@ -44,7 +47,7 @@
if(!allowed(user))
to_chat(user, "You are not authorized to add notices!")
return
- if(notices < 5)
+ if(notices < MAX_NOTICES)
if(!user.transferItemToLoc(O, src))
return
notices++
@@ -55,54 +58,71 @@
else
return ..()
-/obj/structure/noticeboard/interact(mob/user)
- ui_interact(user)
+/obj/structure/noticeboard/ui_state(mob/user)
+ return GLOB.physical_state
-/obj/structure/noticeboard/ui_interact(mob/user)
+/obj/structure/noticeboard/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "NoticeBoard", name)
+ ui.open()
+
+/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)
. = ..()
- var/auth = allowed(user)
- var/dat = "[name]
"
- for(var/obj/item/P in src)
- if(istype(P, /obj/item/paper))
- dat += "[P.name] [auth ? "Write Remove" : ""]
"
- else
- dat += "[P.name] [auth ? "Remove" : ""]
"
- user << browse("
Notices[dat]","window=noticeboard")
- onclose(user, "noticeboard")
+ if(.)
+ return
-/obj/structure/noticeboard/Topic(href, href_list)
- ..()
- usr.set_machine(src)
- if(href_list["remove"])
- if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
- return
- var/obj/item/I = locate(href_list["remove"]) in contents
- if(istype(I) && I.loc == src)
- I.forceMove(usr.loc)
- usr.put_in_hands(I)
- notices--
- icon_state = "nboard0[notices]"
+ var/obj/item/item = locate(params["ref"]) in contents
+ if(!istype(item) || item.loc != src)
+ return
- if(href_list["write"])
- if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
- return
- var/obj/item/P = locate(href_list["write"]) in contents
- if(istype(P) && P.loc == src)
- var/obj/item/I = usr.is_holding_item_of_type(/obj/item/pen)
- if(I)
- add_fingerprint(usr)
- P.attackby(I, usr)
+ var/mob/user = usr
+
+ switch(action)
+ if("examine")
+ if(istype(item, /obj/item/paper))
+ item.ui_interact(user)
else
- to_chat(usr, "You'll need something to write with!")
+ user.examinate(item)
+ return TRUE
+ if("remove")
+ if(!allowed(user))
+ return
+ remove_item(item, user)
+ return TRUE
- if(href_list["read"])
- var/obj/item/I = locate(href_list["read"]) in contents
- if(istype(I) && I.loc == src)
- usr.examinate(I)
+/**
+ * Removes an item from the notice board
+ *
+ * Arguments:
+ * * item - The item that is to be removed
+ * * user - The mob that is trying to get the item removed, if there is one
+ */
+/obj/structure/noticeboard/proc/remove_item(obj/item/item, mob/user)
+ item.forceMove(drop_location())
+ if(user)
+ user.put_in_hands(item)
+ balloon_alert(user, "removed from board")
+ notices--
+ icon_state = "nboard0[notices]"
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/iron (loc, 1)
+ for(var/obj/item/content in contents)
+ remove_item(content)
qdel(src)
// Notice boards for the heads of staff (plus the qm)
@@ -146,3 +166,5 @@
name = "Staff Notice Board"
desc = "Important notices from the heads of staff."
req_access = list(ACCESS_HEADS)
+
+#undef MAX_NOTICES
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 0675632a750..66d281636f2 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -288,6 +288,10 @@
data["is_crayon"] = FALSE
data["stamp_icon_state"] = "FAKE"
data["stamp_class"] = "FAKE"
+ if(istype(loc, /obj/structure/noticeboard))
+ var/obj/structure/noticeboard/noticeboard = loc
+ if(!noticeboard.allowed(user))
+ data["edit_mode"] = MODE_READING
data["field_counter"] = field_counter
data["form_fields"] = form_fields
@@ -351,6 +355,11 @@
update_appearance()
. = TRUE
+/obj/item/paper/ui_host(mob/user)
+ if(istype(loc, /obj/structure/noticeboard))
+ return loc
+ return ..()
+
/**
* Construction paper
*/
diff --git a/tgui/packages/tgui/interfaces/NoticeBoard.js b/tgui/packages/tgui/interfaces/NoticeBoard.js
new file mode 100644
index 00000000000..3008fcd38a4
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/NoticeBoard.js
@@ -0,0 +1,52 @@
+import { useBackend } from "../backend";
+import { Box, Button, Flex, Section } from "../components";
+import { Window } from "../layouts";
+
+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, index) => (
+
+
+
+ {item.name}
+
+
+
+
+
+ )))}
+
+
+ );
+};