mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-15 00:55:49 +01:00
## About PR Sprites made by @KingOfThePing! Adds whiteboards to following areas: - CE and RD office (portable) - Expedition EVA storage (portable) - Intrepid flight deck (portable) - Xenoarcheology presentation room - Engineering breakroom - Kitchen (as an alternative to holo-menu) Whiteboards are also available in cargo console in the recreation tab As an addition whiteboards can be mapped in with preset overlays and written contents This PR also changes sign selection list menu for barsigns and its subtypes with a tgui image menu ## Images <img width="699" height="534" alt="image" src="https://github.com/user-attachments/assets/7b3de94c-76e4-491d-802c-ae9a31501805" /> <details><summary>video sample</summary> <p> https://github.com/user-attachments/assets/24de419c-e155-4623-9d08-0ff6c0b7d228 </p> </details> ### Asset Licenses The following assets that **have not** been created by myself are included in this PR: | Path | Original Author | License | | --- | --- | --- | | icons/obj/whiteboard.dmi & icons/obj/whiteboard_portable.dmi | KingOfThePing | CC BY-SA 3.0 | | sound/effects/whiteboard_scribble_1.ogg, sound/effects/whiteboard_scribble_2.ogg, sound/effects/whiteboard_scribble_3.ogg | freesound_community (https://pixabay.com/sound-effects/film-special-effects-marker-whiteboard-squeak03-83059/) | Pixabay Licence |
294 lines
8.9 KiB
Plaintext
294 lines
8.9 KiB
Plaintext
/// List of data passed over to tgui, obtained from whiteboard singletons. List contains lists of: "display_name", "icon", "icon_name", "singleton_path"
|
|
GLOBAL_LIST_EMPTY(whiteboard_overlay_cache)
|
|
|
|
// ---- large whiteboard, 64x32
|
|
/obj/structure/whiteboard
|
|
name = "whiteboard"
|
|
desc = "A whiteboard in classic design. Often associated with its sibling glassboard, perfect material to draw incomprehensible equations."
|
|
icon = 'icons/obj/whiteboard.dmi'
|
|
icon_state = "whiteboard"
|
|
layer = OBJ_LAYER
|
|
/// Singleton path to whiteboard overlays.
|
|
var/overlay_choices_singleton = /singleton/whiteboard
|
|
/// Written things on the whiteboard.
|
|
var/written_contents
|
|
/// Is someone currently drawing things on the whiteboard?
|
|
var/busy = FALSE
|
|
/// Used to prevent pixel-shift mechanic spam.
|
|
var/currently_pixel_shifting = FALSE
|
|
/// For mapping purposes. Define this as one of the overlay icon_state's name (e.g. overlay_1).
|
|
var/preset_overlay
|
|
|
|
/obj/structure/whiteboard/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "You can write or edit things on [src] with a <b>pen</b>."
|
|
. += "You can <b>ALT Click</b> to pixel-shift [src] to the wall. Only works for north direction when wheel brakes are locked!"
|
|
. += "You can engage/release wheel brakes with the help of a <b>wrench</b>."
|
|
|
|
/obj/structure/whiteboard/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
|
|
. = ..()
|
|
if(written_contents)
|
|
to_chat(user, EXAMINE_BLOCK("It reads: \"[written_contents]\"."))
|
|
|
|
/obj/structure/whiteboard/Initialize()
|
|
. = ..()
|
|
if(!length(GLOB.whiteboard_overlay_cache))
|
|
var/list/singleton_instances = GET_SINGLETON_SUBTYPE_MAP(overlay_choices_singleton)
|
|
for(var/i in singleton_instances)
|
|
var/singleton/whiteboard/S = GET_SINGLETON(i)
|
|
var/overlay_image = image(icon = icon, icon_state = S.icon_state)
|
|
|
|
GLOB.whiteboard_overlay_cache.Add(list(list(
|
|
"display_name" = S.name,
|
|
"icon" = icon2base64(getFlatIcon(overlay_image)), // expensive but we only do it once
|
|
"icon_name" = S.icon_state,
|
|
"singleton_path" = "[S.type]"
|
|
)))
|
|
|
|
if(preset_overlay)
|
|
AddOverlays(preset_overlay)
|
|
|
|
/obj/structure/whiteboard/Move()
|
|
. = ..()
|
|
if(has_gravity())
|
|
playsound(src, 'sound/effects/roll.ogg', 50, 1)
|
|
|
|
/obj/structure/whiteboard/AltClick(mob/user)
|
|
if(!anchored)
|
|
to_chat(user, SPAN_WARNING("You need the wheels locked first in order to secure [src] to a wall!"))
|
|
return
|
|
|
|
if(currently_pixel_shifting)
|
|
return
|
|
|
|
currently_pixel_shifting = TRUE
|
|
if(!do_after(user, 0.5 SECOND))
|
|
currently_pixel_shifting = FALSE
|
|
return
|
|
currently_pixel_shifting = FALSE
|
|
animate(src, pixel_y = pixel_y == 0 ? 12 : 0, time = 0.2 SECOND)
|
|
balloon_alert(user, "shifted")
|
|
|
|
/obj/structure/whiteboard/attackby(obj/item/attacking_item, mob/user)
|
|
if(busy)
|
|
to_chat(user, SPAN_WARNING("Someone is already drawing things on this board!"))
|
|
return
|
|
|
|
var/obj/item/pen/P = attacking_item
|
|
if(istype(P))
|
|
to_chat(user, SPAN_NOTICE("You start contemplating what to draw."))
|
|
handle_drawing(user)
|
|
|
|
else if(attacking_item.tool_behaviour == TOOL_WRENCH)
|
|
animate(src, pixel_y = 0, time = 0.2 SECOND) // if we were pixel-shifted, return to our original state
|
|
anchored = !anchored
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
balloon_alert(user, "[anchored ? "secure" : "unsecure"]")
|
|
user.visible_message("[user] [anchored ? "locks" : "unlocks"] [src]'s wheels.", \
|
|
"You [anchored ? "locked" : "unlocked"] [src]'s wheels.", \
|
|
"You hear a click.")
|
|
|
|
else
|
|
to_chat(user, SPAN_WARNING("This is the wrong tool to manifest your inland empire, maybe a pen would be more fitting?"))
|
|
|
|
/obj/structure/whiteboard/proc/handle_drawing(mob/user)
|
|
busy = TRUE
|
|
// Text input
|
|
var/new_written_contents = tgui_input_text(user, "Write your text here", "Whiteboard Contents", default = written_contents, multiline = TRUE)
|
|
if(new_written_contents == written_contents) // if untouched, cancel it
|
|
to_chat(user, SPAN_WARNING("You withdraw your pen in thought, [src] remains untouched."))
|
|
busy = FALSE
|
|
return
|
|
|
|
if(!new_written_contents) //if empty, erase the board
|
|
to_chat(user, SPAN_NOTICE("You erase the contents on [src]."))
|
|
ClearOverlays()
|
|
desc = initial(desc)
|
|
written_contents = null
|
|
busy = FALSE
|
|
return
|
|
|
|
written_contents = new_written_contents
|
|
ui_interact(user)
|
|
|
|
/obj/structure/whiteboard/proc/finalize_drawing(mob/user, choice)
|
|
playsound(get_turf(src), SFX_WHITEBOARD_SCRIBBLE, 60, FALSE)
|
|
if(do_after(user, 2 SECONDS))
|
|
update_icon(choice)
|
|
else
|
|
ClearOverlays()
|
|
written_contents = null
|
|
|
|
/obj/structure/whiteboard/update_icon(choice)
|
|
ClearOverlays()
|
|
AddOverlays(choice)
|
|
|
|
// ---- UI code
|
|
|
|
/obj/structure/whiteboard/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "OverlayChoice", capitalize_first_letters(name))
|
|
ui.open()
|
|
|
|
/obj/structure/whiteboard/ui_static_data(mob/user)
|
|
var/list/data = list()
|
|
data["contents"] = GLOB.whiteboard_overlay_cache
|
|
return data
|
|
|
|
/obj/structure/whiteboard/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
var/mob/user = ui.user
|
|
add_fingerprint(user)
|
|
switch(action)
|
|
if("select_overlay")
|
|
var/choice = params["choice"]
|
|
INVOKE_ASYNC(src, PROC_REF(finalize_drawing), user, choice)
|
|
busy = FALSE
|
|
|
|
SStgui.close_uis(src)
|
|
|
|
. = TRUE
|
|
|
|
/obj/structure/whiteboard/ui_close(mob/user, datum/tgui/ui)
|
|
. = ..()
|
|
|
|
if(busy) // if the ui was closed while we were still busy, it means no overlay were chosen
|
|
busy = FALSE
|
|
written_contents = null
|
|
ClearOverlays()
|
|
to_chat(user, SPAN_WARNING("You withdraw your pen in thought, [src] remains untouched."))
|
|
|
|
// ---- Portable whiteboard, 32x32
|
|
/obj/item/portable_whiteboard
|
|
name = "portable whiteboard"
|
|
desc = "A compact whiteboard folded into a portable frame, ready to be deployed on any unexpected seminar!"
|
|
icon = 'icons/obj/whiteboard_portable.dmi'
|
|
icon_state = "whiteboard_case"
|
|
item_state = "whiteboard_case"
|
|
contained_sprite = TRUE
|
|
force = 18
|
|
throw_speed = 1
|
|
throw_range = 4
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked")
|
|
drop_sound = 'sound/items/drop/toolbox.ogg'
|
|
pickup_sound = 'sound/items/pickup/toolbox.ogg'
|
|
/// Used to keep track of folding process to prevent spams.
|
|
var/currently_unfolding = FALSE
|
|
|
|
/obj/item/portable_whiteboard/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "You can <b>ALT Click</b> to deploy [src]. It must be on the floor first!"
|
|
|
|
/obj/item/portable_whiteboard/AltClick(mob/user)
|
|
if(loc == user)
|
|
to_chat(user, SPAN_WARNING("[src] needs to be standing on the floor in order to be unfolded!"))
|
|
return
|
|
|
|
if(currently_unfolding)
|
|
return
|
|
|
|
currently_unfolding = TRUE
|
|
if(!do_after(user, 3 SECONDS))
|
|
currently_unfolding = FALSE
|
|
return
|
|
|
|
new /obj/structure/whiteboard/portable(get_turf(src))
|
|
playsound(get_turf(src), 'sound/items/storage/briefcase.ogg', 50)
|
|
qdel(src)
|
|
|
|
/obj/structure/whiteboard/portable
|
|
name = "portable whiteboard"
|
|
desc = "A compact whiteboard folded into a portable frame, ready to be deployed on any unexpected seminar!"
|
|
icon = 'icons/obj/whiteboard_portable.dmi'
|
|
anchored = FALSE
|
|
/// Used to keep track of folding process to prevent spams.
|
|
var/currently_folding = FALSE
|
|
|
|
/obj/structure/whiteboard/portable/AltClick(mob/user)
|
|
if(currently_folding)
|
|
return
|
|
|
|
currently_folding = TRUE
|
|
if(!do_after(user, 3 SECONDS))
|
|
currently_folding = FALSE
|
|
return
|
|
|
|
new /obj/item/portable_whiteboard(get_turf(src))
|
|
playsound(get_turf(src), 'sound/items/storage/briefcase.ogg', 50)
|
|
qdel(src)
|
|
|
|
/obj/structure/whiteboard/portable/update_icon(choice)
|
|
ClearOverlays()
|
|
var/image/overlay_image = image(icon = 'icons/obj/whiteboard.dmi', icon_state = choice)
|
|
overlay_image.transform *= 0.5
|
|
overlay_image.pixel_x = -16
|
|
overlay_image.pixel_y = 2
|
|
AddOverlays(overlay_image)
|
|
|
|
// ---- Whiteboard overlay singletons
|
|
|
|
/singleton/whiteboard
|
|
var/name = "placeholder"
|
|
var/icon_state = ""
|
|
|
|
/singleton/whiteboard/bar_chart
|
|
name = "Bar chart"
|
|
icon_state = "overlay_1"
|
|
|
|
/singleton/whiteboard/pie_chart
|
|
name = "Pie chart"
|
|
icon_state = "overlay_2"
|
|
|
|
/singleton/whiteboard/spacetime_diagram
|
|
name = "Spacetime diagram"
|
|
icon_state = "overlay_3"
|
|
|
|
/singleton/whiteboard/geometric_chart
|
|
name = "Geometric chart"
|
|
icon_state = "overlay_4"
|
|
|
|
/singleton/whiteboard/scribbles
|
|
name = "Scribbles"
|
|
icon_state = "overlay_5"
|
|
|
|
/singleton/whiteboard/gun_diagram
|
|
name = "Gun diagram"
|
|
icon_state = "overlay_6"
|
|
|
|
/singleton/whiteboard/circle_chart
|
|
name = "Circle chart"
|
|
icon_state = "overlay_7"
|
|
|
|
/singleton/whiteboard/display_chart
|
|
name = "Display chart"
|
|
icon_state = "overlay_8"
|
|
|
|
/singleton/whiteboard/todays_menu
|
|
name = "Today's menu"
|
|
icon_state = "overlay_9"
|
|
|
|
/singleton/whiteboard/calculations
|
|
name = "Calculations"
|
|
icon_state = "overlay_10"
|
|
|
|
/singleton/whiteboard/erased_board
|
|
name = "Erased board"
|
|
icon_state = "overlay_11"
|
|
|
|
/singleton/whiteboard/wavelenghth
|
|
name = "Wavelength"
|
|
icon_state = "overlay_12"
|
|
|
|
/singleton/whiteboard/grafitti
|
|
name = "Grafitti"
|
|
icon_state = "overlay_13"
|
|
|
|
/singleton/whiteboard/archeological
|
|
name = "Archeological"
|
|
icon_state = "overlay_14"
|