Object Examine Text Overhaul (#20923)

Extends and reworks how various extended information text (desc_info,
desc_build, desc_upgrades) are handled to make object interactions and
mechanics A.) much more clearly documented in-game and B.) much easier
to support from the back-end.

Almost certainly a candidate for test merge.

Assembly/Disassembly instructions are noticeably sporadic, largely due
to our current lack of a unified framework. That's a future thing I'd
like to attack so that it can be handled programmatically, but for now I
only targeted the biggest culprits as I came across them.

---------

Signed-off-by: Batrachophreno <Batrochophreno@gmail.com>
This commit is contained in:
Batrachophreno
2025-07-21 15:35:14 +00:00
committed by GitHub
parent 827985ea9f
commit 387cee9243
391 changed files with 4203 additions and 2828 deletions
@@ -29,11 +29,8 @@
update_icon()
starting_maxhealth = maxhealth
/obj/structure/barricade/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
. += SPAN_INFO("It is recommended to stand flush to a barricade or one tile away for maximum efficiency.")
if(is_wired)
. += SPAN_INFO("There is a length of wire strewn across the top of this barricade.")
/obj/structure/barricade/condition_hints(mob/user, distance, is_adjacent)
. += ..()
switch(damage_state)
if(BARRICADE_DMG_NONE)
. += SPAN_INFO("It appears to be in good shape.")
@@ -44,6 +41,17 @@
if(BARRICADE_DMG_HEAVY)
. += SPAN_WARNING("It's crumbling apart, just a few more blows will tear it apart!")
/obj/structure/barricade/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
if(!is_wired)
. += "Use a length of barbed wire on this barricade to restrict enemies from climbing it and damage them on attacking it at close range."
/obj/structure/barricade/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += SPAN_INFO("It is recommended to stand flush to a barricade or one tile away for maximum efficiency.")
if(is_wired)
. += SPAN_INFO("There is a length of barbed wire strewn across the top of this barricade, preventing it from being climbed and making it hazardous to attack at close range.")
/obj/structure/barricade/update_icon()
CutOverlays()
@@ -14,15 +14,15 @@
can_wire = TRUE
var/build_state = BARRICADE_BSTATE_SECURED //Look at __game.dm for barricade defines
/obj/structure/barricade/metal/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/barricade/metal/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
switch(build_state)
if(BARRICADE_BSTATE_SECURED)
. += SPAN_INFO("The protection panel is still tighly screwed in place.")
. += "The protection panel is still tighly <b>screwed</b> in place."
if(BARRICADE_BSTATE_UNSECURED)
. += SPAN_INFO("The protection panel has been removed, you can see the anchor bolts.")
. += "The protection panel has been removed, you can see the <b>anchor bolts</b>."
if(BARRICADE_BSTATE_MOVABLE)
. += SPAN_INFO("The protection panel has been removed and the anchor bolts loosened. It's ready to be taken apart.")
. += "The protection panel has been removed and the anchor bolts loosened. It's ready to be <b>pried</b> apart."
/obj/structure/barricade/metal/attackby(obj/item/attacking_item, mob/user)
if(attacking_item.iswelder())
+14 -3
View File
@@ -7,7 +7,6 @@ LINEN BINS
/obj/item/bedsheet
name = "bedsheet"
desc = "A surprisingly soft linen bedsheet."
desc_info = "Click to roll and unroll. Alt-click to fold and unfold. Drag and drop to pick up. You can equip it in your backpack slot."
icon = 'icons/obj/bedsheets.dmi'
icon_state = "sheetwhite"
item_state = "sheetwhite"
@@ -30,6 +29,15 @@ LINEN BINS
var/inuse = FALSE
var/inside_storage_item = FALSE
/obj/item/bedsheet/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Click to roll and unroll."
. += "Alt-click to fold and unfold."
. += "Drag and drop to pick up."
. += "You can equip it in your backpack slot."
. += "It could be cut up into sheets of cloth."
. += "Holes could be poked in it to make a ghost costume... if you really wanted to."
/obj/item/bedsheet/Initialize()
. = ..()
var/static/list/loc_connections = list(
@@ -388,9 +396,12 @@ LINEN BINS
var/list/sheets = list()
var/obj/item/hidden = null
/obj/structure/bedsheetbin/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "You could hide things in here, so long as there are also some sheets to conceal it."
/obj/structure/bedsheetbin/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/bedsheetbin/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(amount < 1)
. += "There are no bed sheets in the bin."
return
+17 -17
View File
@@ -23,6 +23,23 @@ GLOBAL_LIST_EMPTY(total_active_bonfires)
var/last_ambient_message
var/burn_out = TRUE //Whether or not it deletes itself when fuel is depleted
/obj/structure/bonfire/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance > 2)
return
if(on_fire)
switch(fuel)
if(0 to 200)
. += "\The [src] is burning weakly."
if(200 to 600)
. += "\The [src] is gently burning."
if(600 to 900)
. += "\The [src] is burning steadily."
if(900 to 1300)
. += "The flames are dancing wildly!"
if(1300 to 2000)
. += "The fire is roaring!"
/obj/structure/bonfire/Initialize()
. = ..()
fuel = rand(1000, 2000)
@@ -39,23 +56,6 @@ GLOBAL_LIST_EMPTY(total_active_bonfires)
GLOB.total_active_bonfires -= src
. = ..()
/obj/structure/bonfire/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance > 2)
return
if(on_fire)
switch(fuel)
if(0 to 200)
. += "\The [src] is burning weakly."
if(200 to 600)
. += "\The [src] is gently burning."
if(600 to 900)
. += "\The [src] is burning steadily."
if(900 to 1300)
. += "The flames are dancing wildly!"
if(1300 to 2000)
. += "The fire is roaring!"
/obj/structure/bonfire/update_icon()
if(on_fire)
if(fuel < 200)
@@ -76,6 +76,45 @@
/// Set to 0 to make the door not animate at all
var/door_anim_time = 2.5
/// Used by body bags and air bubbles.
var/contains_body = FALSE
/obj/structure/closet/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "When closed, a <b>welder</b> could be used to weld the closet shut."
/obj/structure/closet/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "When opened, a <b>welder</b> could be used to cut the closet back into steel sheets."
/obj/structure/closet/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Using a Closet Teleporter (Stealth & Camouflage uplink item) on this can turn it into a quick transportation method- just don't get caught!"
/obj/structure/closet/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(!src.opened && isghost(user))
. += "It contains: [counting_english_list(contents)]"
if(distance <= 1 && !src.opened)
var/content_size = 0
for(var/obj/item/I in contents)
if(!I.anchored)
content_size += Ceiling(I.w_class/2)
if(!content_size)
. += "\The [src] is empty."
else if(storage_capacity > content_size*4)
. += "\The [src] is barely filled."
else if(storage_capacity > content_size*2)
. += "\The [src] is less than half full."
else if(storage_capacity > content_size)
. += "\The [src] still has some free space."
else
. += "\The [src] is full."
if(src.opened && linked_teleporter && is_adjacent)
. += SPAN_WARNING("There appears to be a device <b>screwed</b> onto the interior backplate of \the [src]...")
/obj/structure/closet/Initialize(mapload, var/no_fill)
. = ..()
@@ -115,33 +154,6 @@
/obj/structure/closet/proc/fill()
return
/obj/structure/closet/proc/content_info(mob/user, content_size)
if(!content_size)
. = "\The [src] is empty."
else if(storage_capacity > content_size*4)
. = "\The [src] is barely filled."
else if(storage_capacity > content_size*2)
. = "\The [src] is less than half full."
else if(storage_capacity > content_size)
. = "\The [src] still has some free space."
else
. = "\The [src] is full."
/obj/structure/closet/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance <= 1 && !src.opened)
var/content_size = 0
for(var/obj/item/I in contents)
if(!I.anchored)
content_size += Ceiling(I.w_class/2)
. += content_info(user, content_size)
if(!src.opened && isghost(user))
. += "It contains: [counting_english_list(contents)]"
if(src.opened && linked_teleporter && is_adjacent)
. += FONT_SMALL(SPAN_NOTICE("There appears to be a device attached to the interior backplate of \the [src]..."))
/obj/structure/closet/proc/stored_weight()
var/content_size = 0
for(var/obj/item/I in contents)
@@ -73,9 +73,6 @@
STOP_PROCESSING(SSprocessing, src)
qdel(src)
/obj/structure/closet/statue/content_info()
return
/obj/structure/closet/statue/proc/create_icon(var/mob/living/L)
appearance = L
appearance_flags |= KEEP_TOGETHER
@@ -15,6 +15,9 @@
anchored = TRUE
wall_mounted = TRUE
/obj/structure/closet/walllocker/antagonist_hints(mob/user, distance, is_adjacent)
. = list()
/obj/structure/closet/walllocker/secure
name = "secure wall locker"
icon_door = "walllocker_secure"
@@ -28,6 +28,13 @@
var/radius_2 = 1.35
var/static/list/animation_math //assoc list with pre calculated values
/obj/structure/closet/crate/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Crates can be placed on top of tables by clicking and dragging the crate onto the target table."
/obj/structure/closet/crate/antagonist_hints(mob/user, distance, is_adjacent)
. = list()
/obj/structure/closet/crate/can_open()
if(tablestatus == UNDER_TABLE)//Can't be opened while under a table
return 0
+17 -16
View File
@@ -12,6 +12,19 @@
var/obj/machinery/power/crystal_agitator/creator // used to re-add dense turfs to agitation list when destroyed
/obj/structure/reagent_crystal/condition_hints(mob/user, distance, is_adjacent)
. += ..()
var/current_damage = health / initial(health)
switch(current_damage)
if(0 to 0.2)
. += SPAN_DANGER("The crystal is barely holding together!")
if(0.2 to 0.4)
. += SPAN_WARNING("The crystal has various cracks visible!")
if(0.4 to 0.8)
. += SPAN_WARNING("The crystal has scratches and deeper grooves on its surface.")
if(0.8 to 1)
. += SPAN_NOTICE("The crystal looks structurally sound.")
/obj/structure/reagent_crystal/Initialize(mapload, var/reagent_i = null, var/our_creator = null)
. = ..()
if(!reagent_i)
@@ -26,21 +39,6 @@
if(our_creator)
creator = our_creator
/obj/structure/reagent_crystal/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
var/state
var/current_damage = health / initial(health)
switch(current_damage)
if(0 to 0.2)
state = SPAN_DANGER("The crystal is barely holding together!")
if(0.2 to 0.4)
state = SPAN_WARNING("The crystal has various cracks visible!")
if(0.4 to 0.8)
state = SPAN_WARNING("The crystal has scratches and deeper grooves on its surface.")
if(0.8 to 1)
state = SPAN_NOTICE("The crystal looks structurally sound.")
. += state
/obj/structure/reagent_crystal/proc/take_damage(var/damage)
health -= damage
if(health <= 0)
@@ -162,9 +160,12 @@
var/singleton/reagent/R = GET_SINGLETON(reagent_i)
name = "[lowertext(R.name)] crystal"
desc = "A [lowertext(R.name)] crystal. It looks rough, unprocessed."
desc_info = "This crystal can be ground to obtain the chemical material locked within."
color = reagents.get_color()
/obj/item/reagent_crystal/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "This crystal can be ground to obtain the chemical material locked within."
/obj/item/storage/bag/crystal
name = "crystal satchel"
desc = "This big boy can store a vast amount of crystals."
+37 -5
View File
@@ -5,7 +5,6 @@
/obj/structure/door_assembly
name = "airlock assembly"
desc = "An airlock assembly."
desc_info = "To create a glass airlock, add two reinforced glass sheets."
icon = 'icons/obj/doors/basic/single/generic/door.dmi'
icon_state = "construction"
anchored = FALSE
@@ -27,14 +26,47 @@
var/created_name
var/width = 1
/obj/structure/door_assembly/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use a pen on \the [src] to name it."
if(anchored && !glass)
. += "Windows could be installed with some <b>reinforced glass</b>."
switch(state)
if(STATE_UNWIRED)
if(!anchored)
. += "\the [src] should first be anchored to the floor with some <b>bolts</b>."
else
. += "\the [src] will need to be fitted with some <b>cables</b>."
if(STATE_WIRED)
. += "Compatible <b>electronics</b> still need to be installed. Remember to configure them first!"
if(STATE_ELECTRONICS_INSTALLED)
. += "The remaining panels can be <b>screwed</b> closed to complete the assembly."
/obj/structure/door_assembly/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
switch(state)
if(STATE_UNWIRED)
if(anchored && glass)
. += "The glass window could be removed with a <b>welder</b>."
else if(anchored)
. += "\the [src] is anchored to the floor with some <b>bolts</b>."
else
. += "\the [src] could be reduced to metal sheets with a <b>welder</b>."
if(STATE_WIRED)
. += "The cables in \the [src] could be <b>cut</b>."
if(STATE_ELECTRONICS_INSTALLED)
. += "The electronics could be <b>pried</b> out."
. += "A <b>chainsaw</b> or equivalent would probably get rid of this thing, but make a real mess."
/obj/structure/door_assembly/feedback_hints(mob/user, distance, is_adjacent)
. = list()
. = ..()
. += "It is currently facing [dir2text(dir)]."
/obj/structure/door_assembly/Initialize(mapload)
. = ..()
update_state()
/obj/structure/door_assembly/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
. += "It is currently facing [dir2text(dir)]."
/obj/structure/door_assembly/door_assembly_generic
base_name = "airlock"
airlock_type = /obj/machinery/door/airlock
+4 -1
View File
@@ -1,7 +1,6 @@
/obj/structure/extinguisher_cabinet
name = "extinguisher cabinet"
desc = "A small wall mounted cabinet designed to hold a fire extinguisher."
desc_info = "Alt-click to close the door."
icon = 'icons/obj/wallmounts.dmi'
icon_state = "cabinet"
anchored = 1
@@ -10,6 +9,10 @@
var/obj/item/extinguisher/has_extinguisher
var/opened = 0
/obj/structure/extinguisher_cabinet/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Alt-click to close the door."
/obj/structure/extinguisher_cabinet/north
dir = NORTH
pixel_y = 24
@@ -137,7 +137,6 @@
F2.linked_flag = src
F2.name = name
F2.desc = desc
F2.desc_info = desc_info
F2.desc_extended = desc_extended
F2.flag_item = flag_item
@@ -31,9 +31,23 @@ ABSTRACT_TYPE(/obj/structure/engineer_maintenance)
/// The key-value list of tools that can be used on the panel once it's been opened. The key is the typepath of the item, and the value is a singleton which holds some data to be used
var/list/panel_tools
/// The list of tool names that can be used on the panel once it's open, but in name format, to be used in get_examine_text
/// The list of tool names that can be used on the panel once it's open, but in name format, to be used in mechanics_hints
var/list/panel_tool_names = list()
/obj/structure/engineer_maintenance/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += SPAN_NOTICE("Any wrench, or an impact drill with the wrenchbit selected, can be used to open/close the panel.")
if(panel_open)
. += SPAN_NOTICE("The following tools can be used to interact with the panel:")
for(var/tool_name in panel_tool_names)
. += SPAN_NOTICE("- [tool_name]")
/obj/structure/engineer_maintenance/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(panel_open)
. += SPAN_NOTICE(detailed_desc)
. += SPAN_ITALIC("OOC NOTE: This object is purely a fluff item, and has no mechanical effect.")
/obj/structure/engineer_maintenance/Initialize(mapload)
. = ..()
name = panel_location == PANEL_LOCATION_FLOOR ? "maintenance panel" : "large maintenance panel" // floor panels are smaller than the wall mounted ones
@@ -50,21 +64,6 @@ ABSTRACT_TYPE(/obj/structure/engineer_maintenance)
SIGNAL_HANDLER
qdel(src)
/obj/structure/engineer_maintenance/get_examine_text(mob/user, distance, is_adjacent, infix, suffix, get_extended)
. = ..()
if(panel_open)
. += SPAN_NOTICE("---")
. += SPAN_NOTICE(detailed_desc)
. += SPAN_NOTICE("---")
. += SPAN_NOTICE("Any wrench, or an impact drill with the wrenchbit selected, can be used to open/close the panel.")
if(panel_open)
. += SPAN_NOTICE("---")
. += SPAN_NOTICE("The following tools can be used to interact with the panel:")
for(var/tool_name in panel_tool_names)
. += SPAN_NOTICE("- [tool_name]")
. += SPAN_ITALIC("OOC NOTE: This object is purely a fluff item, and has no mechanical effect.")
/obj/structure/engineer_maintenance/update_icon()
if(!panel_open)
icon_state = initial(icon_state)
@@ -219,15 +218,12 @@ ABSTRACT_TYPE(/obj/structure/engineer_maintenance)
if(finish_sound)
playsound(get_turf(target), finish_sound, 30, TRUE)
/singleton/engineer_maintenance_tool/steam_pipe
finish_sound = /singleton/sound_category/steam_pipe
/singleton/engineer_maintenance_tool/electrical_hum
finish_sound = /singleton/sound_category/electrical_hum
/singleton/engineer_maintenance_tool/electrical_spark
finish_sound = /singleton/sound_category/electrical_spark
+52 -19
View File
@@ -1,9 +1,5 @@
/obj/structure/girder
desc = "The basic building block of all walls."
desc_info = "Use metal sheets on this to build a normal wall.<br>\
A false wall can be made by using a crowbar on this girder, and then adding some material.<br>\
You can dismantle the grider with a wrench, or add support struts with a screwdriver to enable further reinforcement.<br>\
If reinforced, before you can dismantle it, you must first unscrew the support struts, then cut them with wirecutters."
icon_state = "girder"
anchored = 1
density = 1
@@ -19,8 +15,8 @@
var/reinforcing = 0
var/plating = FALSE
/obj/structure/girder/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/girder/condition_hints(mob/user, distance, is_adjacent)
. += ..()
var/state
var/current_damage = health / initial(health)
switch(current_damage)
@@ -34,6 +30,43 @@
state = SPAN_NOTICE("The support struts look completely intact.")
. += state
/obj/structure/girder/mechanics_hints()
. = list()
. += ..()
if (state == 0 && anchored)
. += SPAN_NOTICE("It could be <b>pried</b> to subtly displace it to build a fake wall.")
return .
/obj/structure/girder/assembly_hints()
. = list()
. += ..()
if (health < initial(health))
. += "It could be repaired with a few choice <b>welds</b>."
if (anchored)
if (!reinf_material && !reinforcing)
. += "It could be prepared for reinforcement with some <b>screws</b>."
if (reinforcing)
. += "It could be given reinforced plating with some <b>plasteel sheets</b>."
if (!plating)
. += "It could be given basic plating with some <b>steel sheets</b>."
// Anchor state
. += "It [anchored ? "is" : "could be"] anchored to the floor with some <b>bolts</b>."
return .
/obj/structure/girder/disassembly_hints()
. = list()
. += ..()
// Reinf wall deconstruction.
if (state == 2)
. += "Its support struts have been securely <b>screwed<b/> into place."
else if (state == 1)
. += "Its unsecured support struts could be <b>cut</b> out."
if (!anchored)
. += "It is held together by a couple of <b>bolts</b>; a heavy <b>cutting</b> tool might also take it apart."
/obj/structure/girder/displaced
name = "displaced girder"
icon_state = "displaced"
@@ -200,19 +233,19 @@
return ..()
/obj/structure/girder/proc/construct_wall(obj/item/stack/material/S, mob/user)
if(S.get_amount() < 2)
/obj/structure/girder/proc/construct_wall(obj/item/stack/material/mat_stack, mob/user)
if(mat_stack.get_amount() < 2)
to_chat(user, SPAN_NOTICE("There isn't enough material here to construct a wall."))
return 0
var/material/M = SSmaterials.get_material_by_name(S.default_type)
if(!istype(M))
var/material/material = SSmaterials.get_material_by_name(mat_stack.default_type)
if(!istype(material))
return 0
var/wall_fake
add_hiddenprint(usr)
if(M.integrity < 50)
if(material.integrity < 50)
to_chat(user, SPAN_NOTICE("This material is too soft for use in wall construction."))
return 0
@@ -222,7 +255,7 @@
else
return TRUE
if(!do_after(user,40) || !S.use(2))
if(!do_after(user,40) || !mat_stack.use(2))
plating = FALSE
return 1 //once we've gotten this far don't call parent attackby()
@@ -239,33 +272,33 @@
Tsrc.ChangeTurf(/turf/simulated/wall)
var/turf/simulated/wall/T = Tsrc
T.under_turf = original_type
T.set_material(M, reinf_material)
T.set_material(material, reinf_material)
if(wall_fake)
T.can_open = 1
T.add_hiddenprint(usr)
qdel(src)
return 1
/obj/structure/girder/proc/reinforce_with_material(obj/item/stack/material/S, mob/user) //if the verb is removed this can be renamed.
/obj/structure/girder/proc/reinforce_with_material(obj/item/stack/material/mat_stack, mob/user) //if the verb is removed this can be renamed.
if(reinf_material)
to_chat(user, SPAN_NOTICE("\The [src] is already reinforced."))
return 0
if(S.get_amount() < 2)
if(mat_stack.get_amount() < 2)
to_chat(user, SPAN_NOTICE("There isn't enough material here to reinforce the girder."))
return 0
var/material/M = SSmaterials.get_material_by_name(S.default_type)
if(!istype(M) || M.integrity < 50)
var/material/material = SSmaterials.get_material_by_name(mat_stack.default_type)
if(!istype(material) || material.integrity < 50)
to_chat(user, "You cannot reinforce \the [src] with that; it is too soft.")
return 0
to_chat(user, SPAN_NOTICE("Now reinforcing..."))
if (!do_after(user,40) || !S.use(2))
if (!do_after(user,40) || !mat_stack.use(2))
return 1 //don't call parent attackby() past this point
to_chat(user, SPAN_NOTICE("You added reinforcement!"))
reinf_material = M
reinf_material = material
reinforce_girder()
return 1
+30 -4
View File
@@ -1,9 +1,6 @@
/obj/structure/grille
name = "grille"
desc = "A flimsy lattice of metal rods, with screws to secure it to the floor."
desc_info = "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves.<br>\
Wirecutters will turn the grille into metal rods instantly. Grilles are made with metal rods.<br>\
Can be fixed with a single metal rod if damaged."
desc = "A flimsy lattice of metal rods."
icon = 'icons/obj/structures.dmi'
icon_state = "grille"
density = TRUE
@@ -15,6 +12,35 @@
var/health = 10
var/destroyed = 0
/obj/structure/grille/condition_hints(mob/user, distance, is_adjacent)
. += ..()
if(health < initial(health))
var/state
var/current_damage = health / initial(health)
switch(current_damage)
if(0 to 0.3)
state = SPAN_DANGER("The grille is barely in one piece!")
if(0.3 to 0.8)
state = SPAN_ALERT("The grille has taken some serious damage.")
if(0.8 to 1)
state = SPAN_NOTICE("The grille is in less than perfect condition.")
. += state
/obj/structure/grille/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves."
/obj/structure/grille/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/grille/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "These could be easily <b>cut</b> through."
/obj/structure/grille/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += "\the [src] [anchored ? "is" : "could be"] anchored to the floor with some <b>screws<b/>."
/obj/structure/grille/over
name = "over-frame grille"
icon = 'icons/obj/smooth/window/grille_over.dmi'
+19 -4
View File
@@ -3,11 +3,16 @@
/obj/item/inflatable
name = "inflatable"
desc_info = "Inflate by using it in your hand. The inflatable barrier will inflate on the turf you are standing on. To deflate it, use the 'deflate' verb."
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/item/inflatables.dmi'
var/deploy_path = null
/obj/item/inflatable/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Inflate by using it in your hand. The inflatable barrier will inflate on the turf you are standing on."
. += "To deflate it, use the 'deflate' verb or ctrl-click on it."
. += "<b>When passing through an airlock made of inflatables, GO SLOWLY!</b>"
/obj/item/inflatable/attack_self(mob/user)
if(!deploy_path)
return
@@ -33,7 +38,6 @@
/obj/structure/inflatable
name = "inflatable"
desc = "An inflated membrane. Do not puncture."
desc_info = "To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
icon = 'icons/obj/item/inflatables.dmi'
icon_state = "wall"
@@ -46,6 +50,11 @@
var/torn_path = null
var/health = 15
/obj/structure/inflatable/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "To deflate it safely, use the 'deflate' verb or ctrl-click on it."
. += "Hitting these with any objects will probably puncture and break it forever."
/obj/structure/inflatable/wall
name = "inflatable wall"
undeploy_path = /obj/item/inflatable/wall
@@ -185,8 +194,6 @@
/obj/structure/inflatable/door //Based on mineral door code
name = "inflatable door"
desc_info = "Click the door to open or close it. It only stops air while closed.<br>\
To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
density = TRUE
anchored = TRUE
opacity = FALSE
@@ -198,6 +205,14 @@
var/state = STATE_CLOSED
var/isSwitchingStates = FALSE
/obj/structure/inflatable/door/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Click the door to open or close it. It only stops air while closed."
. += "<b>When passing through an airlock made of inflatables, GO SLOWLY!</b>"
. += "To deflate it safely, use the 'deflate' verb or ctrl-click on it."
. += "Hitting these with any objects will probably puncture and break it forever."
. += "<b>FOR THE SECOND TIME: GO SLOWLY TO MAKE SURE THE DOORS ARE FULLY CLOSED!</b>"
/obj/structure/inflatable/door/attack_ai(mob/user)
if(isAI(user)) //so the AI can't open it
return
+21 -18
View File
@@ -1,10 +1,6 @@
/obj/structure/janitorialcart
name = "custodial cart"
desc = "The ultimate in custodial carts. Has space for water, mops, signs, trash bags, and more."
desc_info = "Click and drag a mop bucket onto the cart to mount it\
</br>Alt+Click with a mop to put it away, a normal click will wet it in the bucket.\
</br>Alt+Click with a container, such as a bucket, to pour its contents into the mounted bucket. A normal click will toss it into the trash\
</br>You can also use a lightreplacer, spraybottle (of spacecleaner) and four wet-floor signs on the cart to store them"
icon = 'icons/obj/janitor.dmi'
icon_state = "cart"
anchored = FALSE
@@ -25,6 +21,27 @@
var/driving
var/mob/living/pulling
/obj/structure/janitorialcart/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Click and drag a mop bucket onto the cart to mount it."
. += "ALT-Click with a mop to put it away; a normal click will wet it in the bucket."
. += "ALT-Click with a container, such as a bucket, to pour its contents into the mounted bucket. A normal click will toss it into the trash."
. += "You can use a light replacer, spraybottle (of space cleaner) and four wet-floor signs on the cart to store them."
/obj/structure/janitorialcart/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "An empty custodial cart can be taken apart with a <b>wrench</b> or a <b>welder</b>. Or a <b>plasma cutter</b>, if you're that hardcore."
/obj/structure/janitorialcart/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance <= 1)
if (mybucket)
var/contains = mybucket.reagents.total_volume
. += "[icon2html(src, user)] The bucket contains <b>[contains] unit\s</b> of liquid!"
else
. += "[icon2html(src, user)] There is no bucket mounted on it!"
//everything else is visible, so doesn't need to be mentioned
// Regular Variant
// No trashbag and no light replacer, this is inside the custodian's locker.
/obj/structure/janitorialcart/Initialize()
@@ -90,17 +107,6 @@
/obj/structure/janitorialcart/proc/get_short_status()
return "Contents: [english_list(contents)]"
/obj/structure/janitorialcart/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance <= 1)
if (mybucket)
var/contains = mybucket.reagents.total_volume
. += "[icon2html(src, user)] The bucket contains [contains] unit\s of liquid!"
else
. += "[icon2html(src, user)] There is no bucket mounted on it!"
//everything else is visible, so doesn't need to be mentioned
/obj/structure/janitorialcart/mouse_drop_receive(atom/dropped, mob/user, params)
var/atom/movable/O = dropped
if (istype(O, /obj/structure/mopbucket) && !mybucket)
@@ -135,7 +141,6 @@
if (LR.store_broken)
return mybag.attackby(I, usr)
/obj/structure/janitorialcart/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/mop) || istype(attacking_item, /obj/item/reagent_containers/glass/rag) || istype(attacking_item, /obj/item/soap))
if (mybucket)
@@ -262,8 +267,6 @@
update_icon()
/obj/structure/janitorialcart/attack_hand(mob/user)
ui_interact(user)
return
+6 -2
View File
@@ -1,8 +1,6 @@
/obj/structure/lattice
name = "lattice"
desc = "A lightweight support lattice."
desc_info = "Add a metal floor tile to build a floor on top of the lattice.<br>\
Lattices can be made by applying metal rods to a space tile."
icon = 'icons/obj/smooth/lattice.dmi'
icon_state = "lattice"
density = FALSE
@@ -23,6 +21,12 @@
)
footstep_sound = /singleton/sound_category/catwalk_footstep
/obj/structure/lattice/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
if(name == "lattice")
. += "Add a <b>metal floor tile</b> to build a floor on top of the lattice."
. += "Lattices can be made by applying <b>metal rods</b> to a space tile."
/obj/structure/lattice/Initialize()
. = ..()
for(var/obj/structure/lattice/LAT in loc)
+5 -5
View File
@@ -9,6 +9,11 @@
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
var/bucketsize = 600 //about 2x the size relative to a regular bucket.
/obj/structure/mopbucket/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(distance <= 1)
. += "It contains <b>[reagents.total_volume] unit\s</b> of water."
/obj/structure/mopbucket/Initialize()
. = ..()
create_reagents(bucketsize)
@@ -21,11 +26,6 @@
GLOB.janitorial_supplies -= src
return ..()
/obj/structure/mopbucket/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance <= 1)
. += "It contains [reagents.total_volume] unit\s of water."
/obj/structure/mopbucket/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/mop))
if(reagents.total_volume < 1)
+24 -13
View File
@@ -20,6 +20,30 @@
can_astar_pass = CANASTARPASS_ALWAYS_PROC
/obj/structure/railing/condition_hints(mob/user, distance, is_adjacent)
. += ..()
if (health < maxhealth)
switch(health / maxhealth)
if (0.0 to 0.5)
. += SPAN_WARNING("It looks severely damaged!")
if (0.25 to 0.5)
. += SPAN_WARNING("It looks damaged!")
if (0.5 to 1.0)
. += SPAN_NOTICE("It has a few scrapes and dents.")
/obj/structure/railing/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
if (anchored)
. += "It could be [density ? "opened" : "closed"] to passage with a wrench."
/obj/structure/railing/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
if (health < maxhealth)
. += "It could be repaired with a few choice <b>welds</b>."
. += "It [anchored ? "is" : "could be"] anchored to the floor with a row of <b>screws</b>."
if (!anchored)
. += "It is held together by a couple of <b>bolts</b>."
/obj/structure/railing/mapped
color = COLOR_GUNMETAL
anchored = TRUE
@@ -73,19 +97,6 @@
R.update_icon()
return ..()
/obj/structure/railing/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(health < maxhealth)
switch(health / maxhealth)
if(0.0 to 0.5)
. += SPAN_WARNING("It looks severely damaged!")
if(0.25 to 0.5)
. += SPAN_WARNING("It looks damaged!")
if(0.5 to 1.0)
. += SPAN_NOTICE("It has a few scrapes and dents.")
. += FONT_SMALL(SPAN_NOTICE("\The [src] is <b>[density ? "closed" : "open"]</b> to passage."))
. += FONT_SMALL(SPAN_NOTICE("\The [src] is <b>[anchored ? "" : "not"] screwed</b> to the floor."))
/obj/structure/railing/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(mover?.movement_type & PHASING)
return TRUE
+8 -8
View File
@@ -30,6 +30,14 @@ FLOOR SAFES
var/drill_x_offset = -4 // The X pixel offset for the drill
var/drill_y_offset = -8 // The Y pixel offset for the drill
/obj/structure/safe/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(broken)
. += SPAN_WARNING("\The [src]'s locking system has been drilled open!")
else if(time_to_drill < 300 SECONDS)
var/time_left = max(round(time_to_drill / 10), 0)
. += SPAN_WARNING("There are only [time_left] second\s of drilling left until \the [src] is broken!")
/obj/structure/safe/Initialize()
. = ..()
tumbler_1_pos = rand(0, 71)
@@ -44,14 +52,6 @@ FLOOR SAFES
space += I.w_class
I.forceMove(src)
/obj/structure/safe/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(broken)
. += SPAN_WARNING("\The [src]'s locking system has been drilled open!")
else if(time_to_drill < 300 SECONDS)
var/time_left = max(round(time_to_drill / 10), 0)
. += SPAN_WARNING("There are only [time_left] second\s of drilling left until \the [src] is broken!")
/obj/structure/safe/Destroy()
if(drill)
drill.soundloop.stop()
+2 -2
View File
@@ -7,8 +7,8 @@
anchored = 0
var/open = FALSE
/obj/structure/sarcophagus/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/sarcophagus/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(!open)
. += "\The [src]'s lid is closed shut."
else
+5 -5
View File
@@ -15,6 +15,11 @@
var/health = 100
var/maxhealth = 100
/obj/structure/simple_door/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(lock)
. += SPAN_NOTICE("It appears to have a lock.")
/obj/structure/simple_door/fire_act(exposed_temperature, exposed_volume)
. = ..()
@@ -60,11 +65,6 @@
lock = null
return ..()
/obj/structure/simple_door/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(lock)
. += SPAN_NOTICE("It appears to have a lock.")
/obj/structure/simple_door/CollidedWith(atom/bumped_atom)
..()
if(!state)
@@ -18,9 +18,6 @@
/obj/structure/bed
name = "bed"
desc = "This is used to lie in, sleep in or strap on."
desc_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.<br>\
Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \
the buckles, instead. \ To unbuckle people as a stationbound, click the bed with an empty gripper."
icon = 'icons/obj/structure/beds.dmi'
icon_state = "bed"
anchored = TRUE
@@ -47,18 +44,36 @@
var/mob/living/pulling = null
var/propelled = 0 // Check for fire-extinguisher-driven chairs
/obj/structure/bed/mechanics_hints()
. = list()
. += ..()
. += "Click and drag yourself (or anyone) to this to buckle in."
. += "Click on this with an empty hand to undo the buckles."
. += "Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \
the buckles instead."
. += "To unbuckle people as a stationbound, click the bed with an empty gripper."
if(held_item)
. += "Click and drag this onto yourself to pick it up."
/obj/structure/bed/assembly_hints()
. = list()
. += ..()
if(!padding_material)
. += "It could be padded with <b>cloth or leather</b>."
/obj/structure/bed/disassembly_hints()
. = list()
. += ..()
if(padding_material)
. += "Its padding has visible seams that could be <b>cut</b>."
. += "It is held together by a couple of <b>bolts</b>."
/obj/structure/bed/Initialize()
. = ..()
LAZYADD(can_buckle, /mob/living)
/obj/structure/bed/New(newloc, new_material = MATERIAL_STEEL, new_padding_material, new_painted_colour)
..(newloc)
if(can_buckle)
desc_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.<br>\
Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \
the buckles instead. "
if(held_item)
desc_info += "Click and drag this onto yourself to pick it up. "
material = SSmaterials.get_material_by_name(new_material)
if(!istype(material))
qdel(src)
@@ -657,6 +672,14 @@
*/
var/initial_beds = 4
/obj/structure/roller_rack/feedback_hints(mob/user, distance, is_adjacent)
. = list()
. += "[initial(desc)] \nIt is holding [LAZYLEN(held)] beds."
/obj/structure/roller_rack/assembly_hints(mob/user, distance, is_adjacent)
. = list()
. += "It [anchored ? "is" : "could be"] anchored to the floor with a couple of <b>screws</b>."
/obj/structure/roller_rack/Initialize()
. = ..()
for(var/_ in 1 to initial_beds)
@@ -678,10 +701,6 @@
beds++
AddOverlays(I)
/obj/structure/roller_rack/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended)
desc = "[initial(desc)] \nIt is holding [LAZYLEN(held)] beds."
. = ..()
/obj/structure/roller_rack/attack_hand(mob/user)
if(!LAZYLEN(held))
to_chat(user, SPAN_NOTICE("The rack is empty."))
@@ -343,7 +343,6 @@
/obj/item/material/stool/chair
name = "chair"
desc = "Bar brawl essential. Now all that's missing is a ragtime piano."
desc_info = "Click it while in-hand to right it."
icon = 'icons/obj/structure/chairs.dmi'
icon_state = "chair_item"
item_state = "chair"
@@ -174,7 +174,6 @@
icon_state = "stool_item_preview"
item_state = "stool"
base_icon = "stool"
desc_info = "Use in-hand or alt-click to right this."
randpixel = 0
center_of_mass = null
force = 15 // Doesn't really matter. Will get overriden by set_material.
@@ -188,6 +187,10 @@
var/deploy_verb = "right"
var/painted_colour
/obj/item/material/stool/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use in-hand or alt-click to right it."
/obj/item/material/stool/New(var/newloc, var/new_material, var/new_padding_material, var/new_painted_colour)
..(newloc, new_material) // new_material handled in material_weapons.dm
if(new_padding_material)
+14 -10
View File
@@ -11,9 +11,6 @@
It has different devices and samplers, as well as internal processing computers, \
to inspect the atmosphere and other properties and qualities of planetary bodies. \
Commonly used by surveyors, explorers, pioneers, all over the Spur, looking to determine the suitability of planets for settlement. "
desc_info = "\
The probe has to be deployed first before it is used. Wrench it to deploy, then click with empty hand to activate.\
"
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "surveying_probe"
density = FALSE
@@ -31,11 +28,22 @@
var/desc_extra = "This probe was manufactured by Orion Express, but it is based on on older model designed by Hephaestus Industries."
var/survey_type = SURVEY_TYPE_ATMOSPHERIC
/obj/structure/survey_probe/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "The probe has to be deployed first before it is used: wrench it to deploy, then click with empty hand to activate."
/obj/structure/survey_probe/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += "This probe was manufactured by Orion Express, but it is based on on older model designed by Hephaestus Industries."
if(survey_type == SURVEY_TYPE_ATMOSPHERIC)
desc += "When deployed, this probe will read and relay weather data to compatible devices."
if(survey_type == SURVEY_TYPE_GROUND)
desc += "When deployed, this probe will read and relay seismic data to compatible devices."
if(survey_type == SURVEY_TYPE_GEOMAGNETIC)
desc += "When deployed, this probe will read and relay geomagnetic data to compatible devices."
/obj/structure/survey_probe/Initialize(mapload)
. = ..()
desc_extended += desc_extra
if(survey_type == SURVEY_TYPE_ATMOSPHERIC)
desc += " When deployed, this probe will read and relay weather data to compatible devices."
if(start_deployed)
deploy()
@@ -224,8 +232,6 @@
It has different devices and drill bits, as well as internal processing computers, \
to inspect the ground, soil and crust of planetary bodies. \
Commonly used by surveyors, explorers, pioneers, all over the Spur, looking to determine the mineral value of planets for settlement. "
desc_info = "\
The probe has to be deployed first before it is used. Wrench it to deploy, then click with empty hand to activate."
icon_state = "ground_probe"
survey_type = SURVEY_TYPE_GROUND
@@ -268,8 +274,6 @@
It has different devices and instruments bits, as well as internal processing computers, \
to inspect the magnetic field and magnetosphere of planetary bodies. \
Commonly used by surveyors, explorers, pioneers, all over the Spur, looking to determine the sefety and comfort of planets for settlement. "
desc_info = "\
The probe has to be deployed first before it is used. Wrench it to deploy, then click with empty hand to activate."
icon_state = "magnet_probe"
survey_type = SURVEY_TYPE_GEOMAGNETIC
@@ -8,8 +8,8 @@
///Whether this nuke will explode if caught in an explosion.
var/can_explode = TRUE
/obj/structure/undetonated_nuke/get_examine_text(mob/user, distance)
. = ..()
/obj/structure/undetonated_nuke/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(GLOB.all_languages[LANGUAGE_AZAZIBA] in user.languages)
. += SPAN_NOTICE("The inscription reads \"WARNING: FISSILE MATERIAL. HANDLE WITH CARE.\" Underneath are a few words, scratched into the metal. They read \"IF FOUND, RETURN TO SKALAMAR AT HIGH VELOCITY\"")
+4 -1
View File
@@ -770,7 +770,6 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
/obj/structure/cash_register
name = "cash register machine"
desc = "A retail nightmare object."
desc_info = "Drag this onto yourself to open the cash compartment."
icon = 'icons/obj/structure/urban/infrastructure.dmi'
icon_state = "cashier"
layer = 2.99
@@ -779,6 +778,10 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
var/storage_type = /obj/item/storage/toolbox/cash_register_storage
var/obj/item/storage/storage_compartment
/obj/structure/cash_register/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Drag this onto yourself to open the cash compartment."
/obj/structure/cash_register/Initialize(mapload)
. = ..()
if(storage_type)
+10 -2
View File
@@ -144,6 +144,11 @@
var/list/temperature_settings = list("normal" = 310, "boiling" = T0C+100, "freezing" = T0C)
var/datum/looping_sound/showering/soundloop
/obj/structure/shower/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Left-click \the [src] to toggle it on and off."
. += "Use a wrench on \the [src] to adjust the temperature."
/obj/machinery/shower/Initialize()
. = ..()
create_reagents(2)
@@ -311,13 +316,16 @@
icon = 'icons/obj/watercloset.dmi'
icon_state = "sink"
desc = "A sink used for washing one's hands and face."
desc_info = "Use HELP intent to fill a container in your hand from this. Use DISARM intent to rinse an empty container. Use any other intent to empty the container into this. \
You can right-click this and change the amount transferred per use."
anchored = 1
var/busy = 0 //Something's being washed at the moment
var/amount_per_transfer_from_this = 300
var/possible_transfer_amounts = list(5,10,15,25,30,50,60,100,120,250,300)
/obj/structure/sink/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use Help intent to fill a container in your hand from this, and use any other intent to empty the container into this."
. += "Right-click \the [src] to change the amount transferred per use."
/obj/structure/sink/verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
set category = "Object"
+11 -11
View File
@@ -17,6 +17,17 @@
VAR_PRIVATE/obj/effect/visual_holder
/obj/structure/weapons_rack/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
if(locate(/obj/item/gun) in src)
. += "<br/>It contains:<br/>"
for(var/obj/item/gun/G in src.contents)
. += "\A [G.name]"
if(locked)
. += SPAN_WARNING("It is locked.")
/obj/structure/weapons_rack/Initialize(mapload)
..()
visual_holder = new()
@@ -159,17 +170,6 @@
#undef BASE_OFFSET_RIFLE_SLOT
#undef INTER_OFFSET_RIFLE_SLOT
/obj/structure/weapons_rack/get_examine_text(mob/user, distance, is_adjacent, infix, suffix, get_extended)
. = ..()
if(locate(/obj/item/gun) in src)
. += "<br/>It contains:<br/>"
for(var/obj/item/gun/G in src.contents)
. += "\A [G.name]"
if(locked)
. += SPAN_WARNING("It is locked.")
/obj/structure/weapons_rack/emag_act(remaining_charges, mob/user, emag_source)
. = ..()
+2 -3
View File
@@ -34,9 +34,8 @@
atmos_canpass = CANPASS_PROC
/obj/structure/window/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
/obj/structure/window/condition_hints(mob/user, distance, is_adjacent)
. += ..()
if(health == maxhealth)
. += SPAN_NOTICE("It looks fully intact.")
else