Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/atom/proc/examine() rework. #4836

Merged
merged 3 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@

/atom/proc/ShiftClick(var/mob/user)
if(user.client && user.client.eye == user)
user.examinate(src)
user.examine_verb(src)
return

/*
Expand Down
4 changes: 2 additions & 2 deletions code/_onclick/ghost.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
AltClickOn(A)
return
if(modifiers["shift"])
examinate(A)
examine_verb(A)
return
A.attack_ghost(src)

Expand All @@ -44,7 +44,7 @@
if(!istype(user))
return
if(user.client && user.client.inquisitive_ghost)
user.examinate(src)
user.examine_verb(src)
return
if(user.client?.holder || user.antagHUD)
storage?.show_to(user)
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/hud/screen/_screen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
/obj/screen/Click(location, control, params)
var/list/paramlist = params2list(params)
if(paramlist["shift"])
return examine(usr, 0)
return examined_by(usr, 0)
if(ismob(usr) && usr.client && usr.canClick() && (!user_incapacitation_flags || !usr.incapacitated(user_incapacitation_flags)))
return handle_click(usr, params)
return FALSE
Expand Down
3 changes: 2 additions & 1 deletion code/_onclick/hud/screen/screen_intent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@
if(. && intent && parent)
parent.set_intent(intent)

/obj/screen/intent_button/examine(mob/user, distance)
/obj/screen/intent_button/examined_by(mob/user, distance, infix, suffix)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/obj/screen/intent_button/examined_by(mob/user, distance, infix, suffix)
/obj/screen/intent_button/get_examine_strings(mob/user, distance, infix, suffix)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per above, kept as examined_by() but fixed return.

SHOULD_CALL_PARENT(FALSE)
if(desc)
to_chat(user, desc)
return TRUE

/obj/screen/intent_button/on_update_icon()
. = ..()
Expand Down
11 changes: 5 additions & 6 deletions code/_onclick/hud/screen/screen_maneuver.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
var/mob/living/user_living = user
user_living.prepare_maneuver()

/obj/screen/maneuver/examine(mob/user, distance)
/obj/screen/maneuver/examined_by(mob/user, distance, infix, suffix)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/obj/screen/maneuver/examined_by(mob/user, distance, infix, suffix)
/obj/screen/maneuver/get_examine_strings(mob/user, distance, infix, suffix)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional, doesn't need the full proc, same for the other screen elem.

Copy link
Member

@out-of-phaze out-of-phaze Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue is the return type, examined_by doesn't return strings, you need a direct to_chat

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept as examined_by() but fixed return.

SHOULD_CALL_PARENT(FALSE)
if(!isliving(user))
return
var/mob/living/user_living = user
if(user_living.prepared_maneuver)
to_chat(src, SPAN_NOTICE("You are prepared to [user_living.prepared_maneuver.name]."))
if(istype(user_living) && user_living.prepared_maneuver)
to_chat(user, SPAN_NOTICE("You are prepared to [user_living.prepared_maneuver.name]."))
else
to_chat(src, SPAN_NOTICE("You are not prepared to perform a maneuver."))
to_chat(user, SPAN_NOTICE("You are not prepared to perform a maneuver."))
return TRUE

/obj/screen/maneuver/on_update_icon()
var/mob/living/owner = owner_ref?.resolve()
Expand Down
6 changes: 3 additions & 3 deletions code/datums/extensions/assembly/assembly_damage.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/datum/extension/assembly/proc/examine(mob/user)
/datum/extension/assembly/proc/examine_assembly(mob/user)
if(damage > broken_damage)
to_chat(user, SPAN_DANGER("It is heavily damaged!"))
return SPAN_DANGER("It is heavily damaged!")
else if(damage)
to_chat(user, "It is damaged.")
return "It is damaged."

/datum/extension/assembly/proc/break_apart()
var/atom/movable/H = holder
Expand Down
8 changes: 4 additions & 4 deletions code/datums/uplink/services.dm
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@
deactivate()
. = ..()

/obj/item/uplink_service/examine(mob/user, distance)
/obj/item/uplink_service/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
if(distance <= 1)
switch(state)
if(AWAITING_ACTIVATION)
to_chat(user, "It is labeled '[service_label]' and appears to be awaiting activation.")
LAZYADD(., "It is labeled '[service_label]' and appears to be awaiting activation.")
if(CURRENTLY_ACTIVE)
to_chat(user, "It is labeled '[service_label]' and appears to be active.")
LAZYADD(., "It is labeled '[service_label]' and appears to be active.")
if(HAS_BEEN_ACTIVATED)
to_chat(user, "It is labeled '[service_label]' and appears to be permanently disabled.")
LAZYADD(., "It is labeled '[service_label]' and appears to be permanently disabled.")

/obj/item/uplink_service/attack_self(var/mob/user)
if(state != AWAITING_ACTIVATION)
Expand Down
4 changes: 2 additions & 2 deletions code/datums/wires/wires.dm
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ var/global/list/wireColourNames = list("darkred" = "dark red")
to_chat(L, "<span class='error'>You need a remote signaller!</span>")
else if(href_list["examine"])
var/colour = href_list["examine"]
to_chat(usr, examine(GetIndex(colour), usr))
to_chat(usr, examine_wire(GetIndex(colour), usr))

// Update Window
Interact(usr)
Expand All @@ -203,7 +203,7 @@ var/global/list/wireColourNames = list("darkred" = "dark red")
/datum/wires/proc/UpdatePulsed(var/index)
return

/datum/wires/proc/examine(index, mob/user)
/datum/wires/proc/examine_wire(index, mob/user)
. = "You aren't sure what this wire does."

var/datum/wire_description/wd = get_description(index)
Expand Down
41 changes: 32 additions & 9 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@
Overrides should either return the result of ..() or `TRUE` if not calling it.
Calls to ..() should generally not supply any arguments and instead rely on
BYOND's automatic argument passing. There is no need to check the return
value of ..(), this is only done by the calling `/examinate()` proc to validate
value of ..(), this is only done by the calling `/examine_verb()` proc to validate
the call chain.

- `user`: The mob examining this atom
Expand All @@ -282,16 +282,36 @@
- Return: `TRUE` when the call chain is valid, otherwise `FALSE`
- Events: `atom_examined`
*/
/atom/proc/examine(mob/user, distance, infix = "", suffix = "")
/atom/proc/examined_by(mob/user, distance, infix, suffix)
var/list/examine_lines
for(var/add_lines in list(get_examine_header(user, distance, infix, suffix), get_examine_strings(user, distance, infix, suffix), get_examine_hints(user, distance, infix, suffix)))
if(islist(add_lines) && LAZYLEN(add_lines))
LAZYADD(examine_lines, add_lines)
if(LAZYLEN(examine_lines))
to_chat(user, jointext(examine_lines, "<br/>"))
RAISE_EVENT(/decl/observ/atom_examined, src, user, distance)
return TRUE

// Name, displayed at the top.
/atom/proc/get_examine_header(mob/user, distance, infix, suffix)
SHOULD_CALL_PARENT(TRUE)
//This reformats names to get a/an properly working on item descriptions when they are bloody or coated in reagents.
var/examine_prefix = get_examine_prefix()
if(examine_prefix)
examine_prefix += " " // add a space to the end to be polite
var/composed_name = ADD_ARTICLE_GENDER("[examine_prefix][name]", gender)
return list("[html_icon(src)] That's [ADD_ARTICLE_GENDER("[examine_prefix][name]", gender)][infix][get_examine_punctuation()] [suffix]")

// Main body of examine, displayed after the header and before hints.
/atom/proc/get_examine_strings(mob/user, distance, infix, suffix)
SHOULD_CALL_PARENT(TRUE)
. = list()
if(desc)
. += desc

to_chat(user, "[html_icon(src)] That's [composed_name][infix][get_examine_punctuation()] [suffix]")
to_chat(user, desc)
// Addendum to examine, displayed at the bottom
/atom/proc/get_examine_hints(mob/user, distance, infix, suffix)

SHOULD_CALL_PARENT(TRUE)

var/list/alt_interactions = get_alt_interactions(user)
if(LAZYLEN(alt_interactions))
Expand All @@ -301,11 +321,14 @@
if(interaction.examine_desc && (interaction.always_show_on_examine || interaction.is_possible(src, user, user?.get_active_held_item())))
interaction_strings += emote_replace_target_tokens(interaction.examine_desc, src)
if(length(interaction_strings))
to_chat(user, SPAN_INFO("Alt-click on \the [src] to [english_list(interaction_strings, and_text = " or ")]."))
LAZYADD(., SPAN_INFO("Alt-click on \the [src] to [english_list(interaction_strings, and_text = " or ")]."))

RAISE_EVENT(/decl/observ/atom_examined, src, user, distance)
return TRUE
var/decl/interaction_handler/handler = get_quick_interaction_handler(user)
if(handler)
LAZYADD(., SPAN_NOTICE("<b>Ctrl-click</b> \the [src] while in your inventory to [lowertext(handler.name)]."))

if(user?.get_preference_value(/datum/client_preference/inquisitive_examine) == PREF_ON && user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user)))
LAZYADD(., SPAN_NOTICE("The codex has <b><a href='byond://?src=\ref[SScodex];show_examined_info=\ref[src];show_to=\ref[user]'>relevant information</a></b> available."))

/**
Relay movement to this atom.
Expand Down Expand Up @@ -842,7 +865,7 @@
if(href_list["look_at_me"] && istype(user))
var/turf/T = get_turf(src)
if(T.CanUseTopic(user, global.view_topic_state) != STATUS_CLOSE)
user.examinate(src)
user.examine_verb(src)
return TOPIC_HANDLED
. = ..()

Expand Down
2 changes: 1 addition & 1 deletion code/game/atoms_movable_interactions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
examine_desc = "examine $TARGET_THEM$"

/decl/interaction_handler/look/invoked(atom/target, mob/user, obj/item/prop)
target.examine(user, get_dist(user, target))
target.examined_by(user, get_dist(user, target))

/decl/interaction_handler/grab
name = "Grab"
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@
/obj/effect/bluegoast/proc/mirror_dir(var/atom/movable/am, var/old_dir, var/new_dir)
set_dir(global.reverse_dir[new_dir])

/obj/effect/bluegoast/examine()
/obj/effect/bluegoast/examined_by(mob/user, distance, infix, suffix)
SHOULD_CALL_PARENT(FALSE)
return daddy.examine(arglist(args))
return daddy.examined_by(user, distance, infix, suffix)

/obj/effect/bluegoast/proc/blueswitch()
var/mob/living/human/H
Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/CableLayer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
return TRUE
return ..()

/obj/machinery/cablelayer/examine(mob/user)
/obj/machinery/cablelayer/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
to_chat(user, "\The [src]'s cable reel has [cable.amount] length\s left.")
. += "\The [src]'s cable reel has [cable.amount] length\s left."

/obj/machinery/cablelayer/proc/load_cable(var/obj/item/stack/cable_coil/CC)
if(istype(CC) && CC.amount)
Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/OpTable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
computer.table = src
break

/obj/machinery/optable/examine(mob/user)
/obj/machinery/optable/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
to_chat(user, SPAN_NOTICE("The neural suppressors are switched [suppressing ? "on" : "off"]."))
. += SPAN_NOTICE("The neural suppressors are switched [suppressing ? "on" : "off"].")

/obj/machinery/optable/grab_attack(obj/item/grab/grab, mob/user)
if(isliving(grab.affecting) && check_table(grab.affecting))
Expand Down
14 changes: 7 additions & 7 deletions code/game/machinery/Sleeper.dm
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,21 @@
beaker = new /obj/item/chems/glass/beaker/large(src)
update_icon()

/obj/machinery/sleeper/examine(mob/user, distance)
/obj/machinery/sleeper/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
if (distance <= 1)
if(beaker)
to_chat(user, SPAN_NOTICE("It is loaded with a beaker."))
. += SPAN_NOTICE("It is loaded with \a [beaker].")
if(occupant)
occupant.examine(arglist(args))
. += occupant.get_examine_strings(user, distance, infix, suffix)
if(emagged && user.skill_check(SKILL_MEDICAL, SKILL_EXPERT))
to_chat(user, SPAN_NOTICE("The chemical input system looks like it has been tampered with."))
. += SPAN_NOTICE("The chemical input system looks like it has been tampered with.")
if(length(loaded_canisters))
to_chat(user, SPAN_NOTICE("There are [length(loaded_canisters)] chemical canister\s loaded:"))
. += SPAN_NOTICE("There are [length(loaded_canisters)] chemical canister\s loaded:")
for(var/thing in loaded_canisters)
to_chat(user, SPAN_NOTICE("- \The [thing]"))
. += SPAN_NOTICE("- \The [thing]")
else
to_chat(user, SPAN_NOTICE("There are no chemical canisters loaded."))
. += SPAN_NOTICE("There are no chemical canisters loaded.")

/obj/machinery/sleeper/proc/has_room_in_beaker()
return beaker && beaker.reagents.total_volume < beaker.reagents.maximum_volume
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
var/obj/item/part_replacer/replacer = I
if(replacer.remote_interaction)
machine.part_replacement(user, replacer)
machine.display_parts(user)
for(var/line in machine.get_part_info_strings(user))
to_chat(user, line)
return TRUE
return FALSE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
var/obj/item/part_replacer/replacer = I
if(replacer.remote_interaction)
machine.part_replacement(user, replacer)
machine.display_parts(user)
for(var/line in machine.get_part_info_strings(user))
to_chat(user, line)
return TRUE
return FALSE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
var/obj/item/part_replacer/replacer = I
if(replacer.remote_interaction)
machine.part_replacement(user, replacer)
machine.display_parts(user)
for(var/line in machine.get_part_info_strings(user))
to_chat(user, line)
return TRUE
return down_interaction(I, user, machine)

Expand Down
38 changes: 21 additions & 17 deletions code/game/machinery/_machines_base/machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -403,45 +403,49 @@ Class Procs:
/datum/proc/remove_visual(mob/M)
return

/obj/machinery/proc/display_parts(mob/user)
to_chat(user, "<span class='notice'>Following parts detected in the machine:</span>")
/obj/machinery/proc/get_part_info_strings(mob/user)
. = list()
. += SPAN_NOTICE("The following parts are detected in \the [src]:")
for(var/obj/item/C in component_parts)
var/line = "<span class='notice'> [C.name]</span>"
var/line = SPAN_NOTICE(" [C.name]")
if(!C.current_health)
line = "<span class='warning'> [C.name] (destroyed)</span>"
line = SPAN_WARNING(" [C.name] (destroyed)")
else if(C.get_percent_health() < 75)
line = "<span class='notice'> [C.name] (damaged)</span>"
to_chat(user, line)
line = SPAN_NOTICE(" [C.name] (damaged)")
. += line
for(var/path in uncreated_component_parts)
var/obj/item/thing = path
to_chat(user, "<span class='notice'> [initial(thing.name)] ([uncreated_component_parts[path] || 1])</span>")
. += SPAN_NOTICE(" [initial(thing.name)] ([uncreated_component_parts[path] || 1])")

/obj/machinery/examine(mob/user)
/obj/machinery/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
if(component_parts && (hasHUD(user, HUD_SCIENCE) || (construct_state && construct_state.visible_components)))
display_parts(user)
. += get_part_info_strings(user)
if(stat & NOSCREEN)
to_chat(user, "It is missing a screen, making it hard to interact with.")
. += SPAN_WARNING("It is missing a screen, making it hard to interact with.")
else if(stat & NOINPUT)
to_chat(user, "It is missing any input device.")
. += SPAN_WARNING("It is missing any input device.")

if((stat & NOPOWER))
if(interact_offline)
to_chat(user, "It is not receiving <a href='byond://?src=\ref[src];power_text=1'>power</a>.")
. += SPAN_WARNING("It is not receiving <a href='byond://?src=\ref[src];power_text=1'>power</a>.")
else
to_chat(user, "It is not receiving <a href='byond://?src=\ref[src];power_text=1'>power</a>, making it hard to interact with.")
. += SPAN_WARNING("It is not receiving <a href='byond://?src=\ref[src];power_text=1'>power</a>, making it hard to interact with.")

if(construct_state?.mechanics_info())
. += SPAN_NOTICE("It can be <a href='byond://?src=\ref[src];mechanics_text=1'>manipulated</a> using tools.")

if(construct_state && construct_state.mechanics_info())
to_chat(user, "It can be <a href='byond://?src=\ref[src];mechanics_text=1'>manipulated</a> using tools.")
var/list/missing = missing_parts()
if(missing)
var/list/parts = list()
for(var/type in missing)
var/obj/item/fake_thing = type
parts += "[num2text(missing[type])] [initial(fake_thing.name)]"
to_chat(user, "\The [src] is missing [english_list(parts)], rendering it inoperable.")
. += SPAN_WARNING("\The [src] is missing [english_list(parts)], rendering it inoperable.")
for(var/obj/item/stock_parts/part in component_parts)
part.on_machine_examined(user)
var/part_strings = part.on_machine_examined(user)
if(LAZYLEN(part_strings))
. += part_strings

// This is really pretty crap and should be overridden for specific machines.
/obj/machinery/fluid_act(var/datum/reagents/fluids)
Expand Down
13 changes: 7 additions & 6 deletions code/game/machinery/_machines_base/stock_parts/_stock_parts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,17 @@
/obj/item/stock_parts/proc/is_functional()
return (!can_take_damage()) || (current_health > 0)

/obj/item/stock_parts/examine(mob/user)
/obj/item/stock_parts/get_examine_strings(mob/user, distance, infix, suffix)
. = ..()
if(can_take_damage())
if(!is_functional())
to_chat(user, SPAN_WARNING("It is completely broken."))
. += SPAN_WARNING("It is completely broken.")
else if(get_percent_health() < 50)
to_chat(user, SPAN_WARNING("It is heavily damaged."))
. += SPAN_WARNING("It is heavily damaged.")
else if(get_percent_health() < 75)
to_chat(user, SPAN_NOTICE("It is showing signs of damage."))
. += SPAN_NOTICE("It is showing signs of damage.")
else if(is_damaged())
to_chat(user, SPAN_NOTICE("It is showing some wear and tear."))
. += SPAN_NOTICE("It is showing some wear and tear.")

//Machines handle damaging for us, so don't do it twice
/obj/item/stock_parts/explosion_act(severity)
Expand All @@ -118,4 +118,5 @@
. = list()

/// A stub for showing messages based on part status when a machine is examined.
/obj/item/stock_parts/proc/on_machine_examined(mob/user)
/obj/item/stock_parts/proc/on_machine_examined(mob/user)
SHOULD_CALL_PARENT(TRUE)
Loading
Loading