Files
SyncIt21 f7bc204bf7 Replacing objects with their mapping directional helpers Part 1 (#94059)
## About The Pull Request
Improving upon #93662 where i noticed a lot of objects don't have
directional helpers

Replaces the following mapped in objects with their directional
counterpart

- `/obj/structure/sign/nanotrasen ->
/obj/structure/sign/nanotrasen/directional`

less var edits & also more realistic interaction with fire/acid etc if
the turf on which they are placed on is attacked which isn't the case if
they are directly mounted on walls

## Changelog
🆑
qol: adds mapping directional helper for nanotrasen sign & replaces all
var edited instances
/🆑
2025-12-02 23:44:30 +00:00

263 lines
10 KiB
Plaintext

/obj/structure/sign
icon = 'icons/obj/signs.dmi'
anchored = TRUE
opacity = FALSE
density = FALSE
layer = SIGN_LAYER
custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT)
max_integrity = 100
armor_type = /datum/armor/structure_sign
resistance_flags = FLAMMABLE
///Determines if a sign is unwrenchable.
var/buildable_sign = TRUE
///This determines if you can select this sign type when using a pen on a sign backing. False by default, set to true per sign type to override.
var/is_editable = FALSE
///sign_change_name is used to make nice looking, alphabetized and categorized names when you use a pen on any sign item or structure which is_editable.
var/sign_change_name
/datum/armor/structure_sign
melee = 50
fire = 50
acid = 50
/obj/structure/sign/Initialize(mapload)
. = ..()
register_context()
if(mapload && !find_and_mount_on_atom(mark_for_late_init = TRUE))
return INITIALIZE_HINT_LATELOAD
/obj/structure/sign/LateInitialize()
find_and_mount_on_atom(late_init = TRUE)
/obj/structure/sign/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
switch (held_item?.tool_behaviour)
if (TOOL_WELDER)
context[SCREENTIP_CONTEXT_LMB] = "Repair"
return CONTEXTUAL_SCREENTIP_SET
if (TOOL_WRENCH)
if(!buildable_sign)
return ///Cannot be unfastened regardless.
context[SCREENTIP_CONTEXT_LMB] = "Unfasten"
return CONTEXTUAL_SCREENTIP_SET
return NONE
/obj/structure/sign/attack_hand(mob/user, list/modifiers)
. = ..()
if(. || user.is_blind())
return
user.examinate(src)
/obj/structure/sign/wrench_act(mob/living/user, obj/item/wrench/I)
. = ..()
if(!buildable_sign)
return ITEM_INTERACT_FAILURE
user.visible_message(span_notice("[user] starts removing [src]..."), \
span_notice("You start unfastening [src]."))
I.play_tool_sound(src)
if(!I.use_tool(src, user, 4 SECONDS))
return ITEM_INTERACT_FAILURE
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
user.visible_message(span_notice("[user] unfastens [src]."), \
span_notice("You unfasten [src]."))
deconstruct(TRUE)
return ITEM_INTERACT_SUCCESS
/obj/structure/sign/welder_act(mob/living/user, obj/item/I)
. = ..()
if(user.combat_mode)
return FALSE
if(atom_integrity == max_integrity)
to_chat(user, span_warning("This sign is already in perfect condition."))
return TRUE
if(!I.tool_start_check(user, amount=1))
return TRUE
user.visible_message(span_notice("[user] starts repairing [src]..."), \
span_notice("You start repairing [src]."))
if(!I.use_tool(src, user, 4 SECONDS, volume =50 ))
return TRUE
user.visible_message(span_notice("[user] finishes repairing [src]."), \
span_notice("You finish repairing [src]."))
atom_integrity = max_integrity
return TRUE
/obj/structure/sign/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(is_editable && IS_WRITING_UTENSIL(I))
if(!length(GLOB.editable_sign_types))
CRASH("GLOB.editable_sign_types failed to populate")
var/choice = tgui_input_list(user, "Select a sign type", "Sign Customization", GLOB.editable_sign_types)
if(isnull(choice))
return
if(!Adjacent(user)) //Make sure user is adjacent still.
to_chat(user, span_warning("You need to stand next to the sign to change it!"))
return
user.visible_message(span_notice("[user] begins changing [src]."), \
span_notice("You begin changing [src]."))
if(!do_after(user, 4 SECONDS, target = src)) //Small delay for changing signs instead of it being instant, so somebody could be shoved or stunned to prevent them from doing so.
return
var/sign_type = GLOB.editable_sign_types[choice]
//It's import to clone the pixel layout information.
//Otherwise signs revert to being on the turf and
//move jarringly.
var/obj/structure/sign/changedsign = new sign_type(get_turf(src))
changedsign.pixel_x = pixel_x
changedsign.pixel_y = pixel_y
changedsign.atom_integrity = atom_integrity
qdel(src)
user.visible_message(span_notice("[user] finishes changing the sign."), \
span_notice("You finish changing the sign."))
return
return ..()
/obj/structure/sign/atom_deconstruct(disassembled)
var/turf/drop_turf = drop_location()
var/obj/item/sign/unwrenched_sign = new (drop_turf)
if(type != /obj/structure/sign/blank) //If it's still just a basic sign backing, we can (and should) skip some of the below variable transfers.
unwrenched_sign.name = name //Copy over the sign structure variables to the sign item we're creating when we unwrench a sign.
unwrenched_sign.desc = "[desc] It can be placed on a wall."
unwrenched_sign.icon = icon
unwrenched_sign.icon_state = icon_state
unwrenched_sign.sign_path = type
unwrenched_sign.set_custom_materials(custom_materials) //This is here so picture frames and wooden things don't get messed up.
unwrenched_sign.is_editable = is_editable
unwrenched_sign.setDir(dir)
/obj/structure/sign/blank //This subtype is necessary for now because some other things (posters, picture frames, paintings) inherit from the parent type.
icon_state = "backing"
name = "sign backing"
desc = "A plastic sign backing, use a pen to change the decal. It can be detached from the wall with a wrench."
is_editable = TRUE
sign_change_name = "Blank Sign"
/obj/item/sign
name = "sign backing"
desc = "A plastic sign backing, use a pen to change the decal. It can be placed on a wall."
icon = 'icons/obj/signs.dmi'
icon_state = "backing"
inhand_icon_state = "backing"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT)
armor_type = /datum/armor/item_sign
resistance_flags = FLAMMABLE
max_integrity = 100
///The type of sign structure that will be created when placed on a turf, the default looks just like a sign backing item.
var/sign_path = /obj/structure/sign/blank
///This determines if you can select this sign type when using a pen on a sign backing. False by default, set to true per sign type to override.
var/is_editable = TRUE
/datum/armor/item_sign
melee = 50
fire = 50
acid = 50
/obj/item/sign/Initialize(mapload) //Signs not attached to walls are always rotated so they look like they're laying horizontal.
. = ..()
var/matrix/M = matrix()
M.Turn(90)
transform = M
register_context()
/obj/item/sign/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(is_editable && IS_WRITING_UTENSIL(held_item))
context[SCREENTIP_CONTEXT_LMB] = "Change design"
return CONTEXTUAL_SCREENTIP_SET
/obj/item/sign/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!is_editable || !IS_WRITING_UTENSIL(tool))
return ..()
if(!length(GLOB.editable_sign_types))
CRASH("GLOB.editable_sign_types failed to populate")
var/choice = tgui_input_list(user, "Select a sign type", "Sign Customization", GLOB.editable_sign_types)
if(isnull(choice))
return ITEM_INTERACT_BLOCKING
if(!Adjacent(user)) //Make sure user is adjacent still.
to_chat(user, span_warning("You need to stand next to the sign to change it!"))
return ITEM_INTERACT_BLOCKING
user.visible_message(span_notice("You begin changing [src]."))
if(!do_after(user, 4 SECONDS, target = src))
return ITEM_INTERACT_BLOCKING
set_sign_type(GLOB.editable_sign_types[choice])
user.visible_message(span_notice("You finish changing the sign."))
return ITEM_INTERACT_SUCCESS
/obj/item/sign/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!iswallturf(interacting_with) && !istype(interacting_with, /obj/structure/tram))
return NONE
var/turf/target_turf = interacting_with
var/turf/user_turf = get_turf(user)
var/dir = get_dir(user_turf, target_turf)
if(!(dir in GLOB.cardinals))
balloon_alert(user, "stand in line with wall!")
return ITEM_INTERACT_BLOCKING
var/obj/structure/sign/placed_sign = new sign_path(user_turf) //We place the sign on the turf the user is standing, and pixel shift it to the target wall, as below.
//This is to mimic how signs and other wall objects are usually placed by mappers, and so they're only visible from one side of a wall.
if(dir & NORTH)
placed_sign.pixel_y = 32
else if(dir & SOUTH)
placed_sign.pixel_y = -32
if(dir & EAST)
placed_sign.pixel_x = 32
else if(dir & WEST)
placed_sign.pixel_x = -32
user.visible_message(span_notice("[user] fastens [src] to [target_turf]."), \
span_notice("You attach the sign to [target_turf]."))
playsound(target_turf, 'sound/items/deconstruct.ogg', 50, TRUE)
placed_sign.update_integrity(get_integrity())
placed_sign.setDir(dir)
placed_sign.find_and_mount_on_atom()
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/item/sign/welder_act(mob/living/user, obj/item/I)
. = ..()
if(user.combat_mode)
return FALSE
if(atom_integrity == max_integrity)
to_chat(user, span_warning("This sign is already in perfect condition."))
return TRUE
if(!I.tool_start_check(user, amount=1))
return TRUE
user.visible_message(span_notice("[user] starts repairing [src]..."), \
span_notice("You start repairing [src]."))
if(!I.use_tool(src, user, 4 SECONDS, volume =50 ))
return TRUE
user.visible_message(span_notice("[user] finishes repairing [src]."), \
span_notice("You finish repairing [src]."))
atom_integrity = max_integrity
return TRUE
/obj/item/sign/proc/set_sign_type(obj/structure/sign/fake_type)
name = initial(fake_type.name)
if(fake_type != /obj/structure/sign/blank)
desc = "[initial(fake_type.desc)] It can be placed on a wall."
else
desc = initial(desc)
icon_state = initial(fake_type.icon_state)
sign_path = fake_type
/obj/item/sign/random/Initialize(mapload)
. = ..()
set_sign_type(GLOB.editable_sign_types[pick(GLOB.editable_sign_types)])
/**
* This proc populates GLOBAL_LIST_EMPTY(editable_sign_types)
*
* The first time a pen is used on any sign, this populates GLOBAL_LIST_EMPTY(editable_sign_types), creating a global list of all the signs that you can set a sign backing to with a pen.
*/
/proc/populate_editable_sign_types()
var/list/output = list()
for(var/s in subtypesof(/obj/structure/sign))
var/obj/structure/sign/potential_sign = s
if(!initial(potential_sign.is_editable))
continue
var/shown_name = initial(potential_sign.sign_change_name) || capitalize(format_text(initial(potential_sign.name)))
if(output[shown_name])
if(!ispath(potential_sign, output[shown_name]))
stack_trace("Two signs share the same sign_change_name: [output[shown_name]] and [potential_sign]")
continue
output[shown_name] = potential_sign
output = sort_list(output) //Alphabetizes the results.
return output