Modular Code Compatible Posters (#17703)

* poster modularity

* access control, documentation

* properly exclude lewd

* unittest too

* fix

* poster test fix
This commit is contained in:
Will
2025-05-15 16:20:20 -04:00
committed by GitHub
parent 6ba4e11f01
commit 05e75a2614
5 changed files with 111 additions and 73 deletions
@@ -5,6 +5,7 @@
var/name = "PSA: Unlucky Space Explorer"
var/desc = "This grim PSA depicts a skeletal form within a space suit. Thousands die every year as a result of failing to follow EVA safety guidelines."
var/listing_name = "PSA - EVA Accidents"
var/icon_override = null // If set to an icon path, replaces the icon upon wall placement. Used for modular posters downstream that should not edit upstream dmis
/decl/poster/bay_2
icon_state="bsposter2"
@@ -1,9 +1,14 @@
/proc/get_poster_decl(var/path = null, var/exact = TRUE)
/// Returns a randomly picked poster decl of the subtype specified by the path argument. If the exact argument is true, it will return the decl from the decls_repository of the exact path specified.
/proc/get_poster_decl(var/path = null, var/exact = TRUE, var/forbid_types)
if(ispath(path))
if(exact)
return decls_repository.get_decl(path)
else
var/list/L = decls_repository.get_decls_of_subtype(path) // Use get_decls_of_subtype instead of get_decls_of_type, or it will get the map placing icon_state
// Get the list of decals and Remove some forbidden types. These two base types don't have proper icon_states so they're illegal.
var/list/L = decls_repository.get_decls_of_type(path)
L -= decls_repository.get_decl(/decl/poster/lewd)
if(forbid_types)
L -= decls_repository.get_decls_of_type(forbid_types)
return L[pick(L)]
return null
@@ -15,24 +20,28 @@
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
force = 0
var/decl/poster/poster_decl = null
var/poster_type = /obj/structure/sign/poster
VAR_PROTECTED/decl/poster/poster_decl = null
VAR_PROTECTED/poster_type = /obj/structure/sign/poster
/obj/item/poster/Initialize(mapload, var/decl/poster/poster_decl = null)
if(ispath(src.poster_decl))
src.poster_decl = get_poster_decl(src.poster_decl, TRUE)
else if(istype(poster_decl))
src.poster_decl = poster_decl
else if(ispath(poster_decl))
src.poster_decl = get_poster_decl(poster_decl, TRUE)
/obj/item/poster/Initialize(mapload, var/decl/poster/P = null)
if(ispath(poster_decl))
poster_decl = get_poster_decl(poster_decl, TRUE, null)
else if(istype(P))
poster_decl = P
else if(ispath(P))
poster_decl = get_poster_decl(P, TRUE, null)
else
src.poster_decl = get_poster_decl(/decl/poster, FALSE)
while (istype(src.poster_decl, /decl/poster/lewd))
src.poster_decl = get_poster_decl(/decl/poster, FALSE)
poster_decl = get_poster_decl(/decl/poster, FALSE, /decl/poster/lewd)
name += " - [src.poster_decl.name]"
name += " - [poster_decl.name]"
return ..()
/// Get the current poster_decl
/obj/item/poster/proc/get_decl()
RETURN_TYPE(/decl/poster)
SHOULD_NOT_OVERRIDE(TRUE)
return poster_decl
//Places the poster on a wall
/obj/item/poster/afterattack(var/atom/A, var/mob/user, var/adjacent, var/clickparams)
if(!adjacent)
@@ -78,41 +87,6 @@
qdel(src)
return FALSE
//NT subtype
/obj/item/poster/nanotrasen
icon_state = "rolled_poster_nt"
poster_type = /obj/structure/sign/poster/nanotrasen
/obj/item/poster/nanotrasen/Initialize(mapload, var/decl/poster/P = null)
if(!ispath(src.poster_decl) && !ispath(P) && !istype(P))
src.poster_decl = get_poster_decl(/decl/poster/nanotrasen, FALSE)
return ..()
//Selectable subtype
/obj/item/poster/custom
name = "rolled-up poly-poster"
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. This one is made from some kind of e-paper, and could display almost anything!"
poster_type = /obj/structure/sign/poster/custom
/obj/item/poster/custom/verb/select_poster()
set name = "Set Poster type"
set category = "Object"
set desc = "Click to choose a poster to display."
var/mob/M = usr
var/list/options = list()
var/list/decl/poster/posters = decls_repository.get_decls_of_type(/decl/poster)
for(var/option in posters)
options[posters[option].name] = posters[option]
var/choice = tgui_input_list(M, "Choose a poster!", "Customize Poster", options)
if(src && choice && !M.stat && in_range(M,src))
poster_decl = options[choice]
name = "rolled-up poly-poster - [src.poster_decl.name]"
to_chat(M, "The poster is now: [choice].")
//############################## THE ACTUAL DECALS ###########################
/obj/structure/sign/poster
@@ -121,28 +95,27 @@
icon = 'icons/obj/contraband_vr.dmi' //VOREStation Edit
icon_state = "poster" //VOREStation Edit
anchored = TRUE
var/decl/poster/poster_decl = null
var/target_poster_decl_path = /decl/poster
var/roll_type = /obj/item/poster
var/ruined = FALSE
VAR_PROTECTED/decl/poster/poster_decl = null // Assigned by Initialize() to a random poster decl. If this is mapset to a path, it will be used to locate the decl specified by that path.
VAR_PROTECTED/roll_type = /obj/item/poster
VAR_PRIVATE/ruined = FALSE
/obj/structure/sign/poster/Initialize(mapload, var/placement_dir = null, var/obj/item/poster/P = null)
. = ..()
if(ispath(src.poster_decl))
src.poster_decl = get_poster_decl(src.poster_decl, TRUE)
if(ispath(poster_decl))
poster_decl = get_poster_decl(poster_decl, TRUE, null)
else if(istype(P))
src.poster_decl = P.poster_decl
poster_decl = P.get_decl()
roll_type = P.type
else if(ispath(P))
src.poster_decl = get_poster_decl(P, TRUE)
poster_decl = get_poster_decl(P, TRUE, null)
else
src.poster_decl = get_poster_decl(/decl/poster, FALSE)
while (istype(src.poster_decl, /decl/poster/lewd))
src.poster_decl = get_poster_decl(/decl/poster, FALSE)
poster_decl = get_poster_decl(/decl/poster, FALSE, /decl/poster/lewd)
name = "[initial(name)] - [poster_decl.name]"
desc = "[initial(desc)] [poster_decl.desc]"
if(poster_decl.icon_override)
icon = poster_decl.icon_override
icon_state = poster_decl.icon_state
if(placement_dir)
@@ -162,7 +135,7 @@
pixel_x = -32
pixel_y = 0
flick("poster_being_set", src)
flick("poster_being_set", src) // If you don't see this animation, check that the decl/poster's icon_override dmi file has the icon states for poster_being_set and poster_ripped in it.
/obj/structure/sign/poster/attackby(obj/item/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_WIRECUTTER))
@@ -176,12 +149,10 @@
return
/obj/structure/sign/poster/attack_hand(mob/user as mob)
if(ruined)
return
if(tgui_alert(user, "Do I want to rip the poster from the wall?","You think...",list("Yes","No")) == "Yes")
if(ruined || !user.Adjacent(src))
return
@@ -193,16 +164,9 @@
desc = "You can't make out anything from the poster's original print. It's ruined."
add_fingerprint(user)
/// Creates a poster item using roll_type as the path, and qdels the wall poster
/obj/structure/sign/poster/proc/roll_and_drop(turf/newloc)
SHOULD_NOT_OVERRIDE(TRUE)
var/obj/item/poster/P = new roll_type(newloc, poster_decl)
P.loc = newloc
qdel(src)
// NT poster subtype.
/obj/structure/sign/poster/nanotrasen
roll_type = /obj/item/poster/nanotrasen
target_poster_decl_path = /decl/poster/nanotrasen
// Non-Random Posters
/obj/structure/sign/poster/custom
roll_type = /obj/item/poster/custom
@@ -0,0 +1,47 @@
/////////////////////////////////////////////////////////////////////////////////
// NT subtype
/////////////////////////////////////////////////////////////////////////////////
/obj/item/poster/nanotrasen // held object
icon_state = "rolled_poster_nt"
poster_type = /obj/structure/sign/poster/nanotrasen
/obj/item/poster/nanotrasen/Initialize(mapload, var/decl/poster/P = null)
if(!ispath(poster_decl) && !ispath(P) && !istype(P))
poster_decl = get_poster_decl(/decl/poster/nanotrasen, FALSE, null)
return ..()
/obj/structure/sign/poster/nanotrasen // placed wall object
roll_type = /obj/item/poster/nanotrasen
/////////////////////////////////////////////////////////////////////////////////
// Selectable "custom" subtype
/////////////////////////////////////////////////////////////////////////////////
/obj/item/poster/custom // held object
name = "rolled-up poly-poster"
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. This one is made from some kind of e-paper, and could display almost anything!"
poster_type = /obj/structure/sign/poster/custom
/// Verb to change a custom poster's design
/obj/item/poster/custom/verb/select_poster()
PRIVATE_PROC(TRUE)
SHOULD_NOT_OVERRIDE(TRUE)
set name = "Set Poster type"
set category = "Object"
set desc = "Click to choose a poster to display."
var/mob/M = usr
var/list/options = list()
var/list/decl/poster/posters = decls_repository.get_decls_of_type(/decl/poster)
for(var/option in posters)
options[posters[option].name] = posters[option]
var/choice = tgui_input_list(M, "Choose a poster!", "Customize Poster", options)
if(src && choice && !M.stat && in_range(M,src))
poster_decl = options[choice]
name = "rolled-up poly-poster - [poster_decl.name]"
to_chat(M, "The poster is now: [choice].")
// Wall object
/obj/structure/sign/poster/custom // placed wall object
roll_type = /obj/item/poster/custom