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

Screentips #11938

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b73fb0e
Screentips framework
PowerfulBacon Aug 26, 2024
1d9d6b4
Update screentip_hud.dm
PowerfulBacon Aug 26, 2024
042dae1
Adds colouring and fixes line height
PowerfulBacon Aug 27, 2024
5d43445
Merge remote-tracking branch 'upstream/master' into screen-tips
PowerfulBacon Nov 23, 2024
3d3d9e3
Fixes screentips and makes them look nice
PowerfulBacon Nov 23, 2024
f5f37ad
Adds some extra context actions and tool actions
PowerfulBacon Nov 24, 2024
3215ed9
Puts tool icons last
PowerfulBacon Nov 24, 2024
c124d24
Fixes multiple left mouse actions showing when the correct tool is held
PowerfulBacon Nov 24, 2024
ea99c7d
Fixes things not calling the parent
PowerfulBacon Nov 24, 2024
7515236
Changes the ordering slightly
PowerfulBacon Nov 24, 2024
e7f81ed
Adds hints for knives and rolling pints
PowerfulBacon Nov 24, 2024
5992225
Adds a signal for adding contexts
PowerfulBacon Nov 24, 2024
4f132fe
Adds some more contexts
PowerfulBacon Nov 24, 2024
ea10dc1
Update PDApainter.dm
PowerfulBacon Nov 24, 2024
899b040
Add reinforced wall hints, add better left click tool icons
PowerfulBacon Nov 24, 2024
8ceac13
processing screentips
Tsar-Salat Nov 24, 2024
8d1b4e4
that too
Tsar-Salat Nov 24, 2024
ad808d2
Update code/datums/elements/food/processable.dm
Tsar-Salat Nov 24, 2024
2a4c78f
add more verbs
Tsar-Salat Nov 24, 2024
6610374
Re-orders tool hint icons
PowerfulBacon Nov 25, 2024
413e342
Review request
PowerfulBacon Nov 25, 2024
7adb323
Merge branch 'screen-tips' into screentips-bacon-rkz
PowerfulBacon Nov 25, 2024
1725870
Merge pull request #21 from Tsar-Salat/screentips-bacon-rkz
PowerfulBacon Nov 25, 2024
aa1d1d5
Removes item from the add context signal (it's not needed due to bein…
PowerfulBacon Nov 25, 2024
0720469
Fixes proc never called parent complaint
PowerfulBacon Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
#include "code\__DEFINES\roundend.dm"
#include "code\__DEFINES\rust_g.dm"
#include "code\__DEFINES\say.dm"
#include "code\__DEFINES\screentips.dm"
#include "code\__DEFINES\SDQL.dm"
#include "code\__DEFINES\security.dm"
#include "code\__DEFINES\shuttles.dm"
Expand Down Expand Up @@ -479,6 +480,7 @@
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\research.dm"
#include "code\controllers\subsystem\runechat.dm"
#include "code\controllers\subsystem\screentip.dm"
#include "code\controllers\subsystem\security_level.dm"
#include "code\controllers\subsystem\server_maint.dm"
#include "code\controllers\subsystem\shuttle.dm"
Expand Down Expand Up @@ -3859,6 +3861,13 @@
#include "code\modules\ruins\spaceruin_code\spacehotel.dm"
#include "code\modules\ruins\spaceruin_code\TheDerelict.dm"
#include "code\modules\ruins\spaceruin_code\whiteshipruin_box.dm"
#include "code\modules\screentips\atom_extensions.dm"
#include "code\modules\screentips\client_extensions.dm"
#include "code\modules\screentips\debug_verbs.dm"
#include "code\modules\screentips\hud_extensions.dm"
#include "code\modules\screentips\screentip_cache.dm"
#include "code\modules\screentips\screentip_context.dm"
#include "code\modules\screentips\screentip_hud.dm"
#include "code\modules\security\genpop.dm"
#include "code\modules\security\prison_scanner.dm"
#include "code\modules\security\workshop.dm"
Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,10 @@

#define COMSIG_ATOM_JAMMED "become_jammed" //! Relayed to atoms when they become jammed if they have the jam_receiver components.
#define COMSIG_ATOM_UNJAMMED "become_unjammed" //! Relayed to atoms when they become unjammed if they have the jam_receiver components.

/////////////////
/// Screentip signals
/////////////////

/// proc/add_context(datum/source, datum/screentip_context/context, mob/user)
#define COMSIG_ATOM_ADD_CONTEXT "add_screentip_context"
2 changes: 2 additions & 0 deletions code/__DEFINES/layers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
#define HUD_PLANE 1000
#define HUD_LAYER 25
#define HUD_RENDER_TARGET "HUD_PLANE"
/// Layer for screentips
#define SCREENTIP_LAYER 26

#define ABOVE_HUD_PLANE 1100
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
Expand Down
53 changes: 53 additions & 0 deletions code/__DEFINES/screentips.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

#define HINT_ICON_FILE 'icons/ui_icons/screentips/cursor_hints.dmi'
#define HINT_TOOL_ICON_FILE 'icons/ui_icons/screentips/tool_hints.dmi'

/// Stores the cursor hint icons for screentip context.
GLOBAL_LIST_INIT_TYPED(screentip_context_icons, /image, prepare_screentip_context_icons())

// These invisible tokens are added to fix a byond rendering bug where icons don't properly position themselves if they are the first thing on a new line
GLOBAL_VAR_INIT(lmb_icon, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["LMB"]]")
GLOBAL_VAR_INIT(rmb_icon, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["RMB"]]")
GLOBAL_VAR_INIT(hint_screwdriver, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["screwdriver"]]")
GLOBAL_VAR_INIT(hint_wrench, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["wrench"]]")
GLOBAL_VAR_INIT(hint_crowbar, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["crowbar"]]")
GLOBAL_VAR_INIT(hint_wirecutters, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["wirecutters"]]")
GLOBAL_VAR_INIT(hint_welder, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["welder"]]")
GLOBAL_VAR_INIT(hint_multitool, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["multitool"]]")
GLOBAL_VAR_INIT(hint_knife, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["knife"]]")
GLOBAL_VAR_INIT(hint_rolling_pin, "<span style='font-size: 1px'>.</span>\icon[GLOB.screentip_context_icons["rolling_pin"]]")

/proc/prepare_screentip_context_icons()
var/list/output = list()
for(var/state in icon_states(HINT_ICON_FILE))
output[state] = image(HINT_ICON_FILE, icon_state = state)
for(var/state in icon_states(HINT_TOOL_ICON_FILE))
output[state] = image(HINT_TOOL_ICON_FILE, icon_state = state)
return output

#define SCREEN_TIP_ALLOWED "#a9f59d"
#define SCREEN_TIP_REJECTED "#e39191"
#define SCREEN_TIP_NORMAL "#daf3f2"
#define SCREEN_TIP_INACCESSIBLE "#a1b6b5"

// ============================
// Auto-tips: Developer QOL
// ============================

GLOBAL_LIST_INIT(screentips_cache, init_autotips())

#define SCREENTIP_ATTACK_HAND(type, message) /datum/screentip_cache##type/attack_hand = "\n" + "<span class='maptext'><span style='line-height: 0.35; color:" + SCREEN_TIP_NORMAL + "'><center>%LMB% " + message + "</center></span></span>"

/proc/init_autotips()
. = list()
for (var/datum/screentip_cache/type as anything in subtypesof(/datum/screentip_cache))
// Parent type, not a real type
if (!initial(type.attack_hand))
continue
var/path = text2path(copytext("[type]", 23))
var/datum/screentip_cache/cache = new type
cache.attack_hand = replacetext(cache.attack_hand, "%LMB%", GLOB.lmb_icon)
.["[path]"] = cache
for (var/subtype in subtypesof(path))
if (!.["[subtype]"])
.["[subtype]"] = cache
1 change: 1 addition & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
#define FIRE_PRIORITY_RESEARCH 10
#define FIRE_PRIORITY_VIS 10
#define FIRE_PRIORITY_ZCOPY 10
#define FIRE_PRIORITY_SCREENTIPS 10 // Don't spend a lot of time on this
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_DATABASE 16
#define FIRE_PRIORITY_PARALLAX 18
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/hud/action_button.dm
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@
. += hidden ? show_appearance : hide_appearance

/atom/movable/screen/movable/action_button/MouseEntered(location,control,params)
..()
if(!QDELETED(src))
openToolTip(usr,src,params,title = name,content = desc,theme = actiontooltipstyle)


/atom/movable/screen/movable/action_button/MouseExited()
closeToolTip(usr)

Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/hud/alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@
var/obj/master

/atom/movable/screen/alert/MouseEntered(location,control,params)
..()
if(!QDELETED(src))
openToolTip(usr,src,params,title = name,content = desc,theme = alerttooltipstyle)


/atom/movable/screen/alert/MouseExited()
closeToolTip(usr)

Expand Down
1 change: 1 addition & 0 deletions code/_onclick/hud/blob_overmind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
icon = 'icons/hud/actions/actions_blob.dmi'

/atom/movable/screen/blob/MouseEntered(location,control,params)
..()
openToolTip(usr,src,params,title = name,content = desc, theme = "blob")

/atom/movable/screen/blob/MouseExited()
Expand Down
1 change: 1 addition & 0 deletions code/_onclick/hud/ghost.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
icon = 'icons/hud/screen_ghost.dmi'

/atom/movable/screen/ghost/MouseEntered()
..()
flick(icon_state + "_anim", src)

/atom/movable/screen/ghost/jumptomob
Expand Down
1 change: 1 addition & 0 deletions code/_onclick/hud/holoparasite.dm
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ CREATION_TEST_IGNORE_SUBTYPES(/atom/movable/screen/holoparasite)
return ..()

/atom/movable/screen/holoparasite/MouseEntered(location, control, params)
..()
if(QDELETED(src))
return
if(usr == owner)
Expand Down
2 changes: 2 additions & 0 deletions code/_onclick/hud/screen_objects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
name = ""
icon = 'icons/hud/screen_gen.dmi'
plane = HUD_PLANE
layer = HUD_LAYER
animate_movement = SLIDE_STEPS
speech_span = SPAN_ROBOT
vis_flags = VIS_INHERIT_PLANE
Expand Down Expand Up @@ -491,6 +492,7 @@ CREATION_TEST_IGNORE_SUBTYPES(/atom/movable/screen/storage)
return set_selected_zone(choice, usr)

/atom/movable/screen/zone_sel/MouseEntered(location, control, params)
..()
MouseMove(location, control, params)

/atom/movable/screen/zone_sel/MouseMove(location, control, params)
Expand Down
1 change: 1 addition & 0 deletions code/_onclick/telekinesis.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
w_class = WEIGHT_CLASS_GIGANTIC

plane = ABOVE_HUD_PLANE
layer = HUD_LAYER

var/atom/movable/focus = null
var/mob/living/carbon/tk_user = null
Expand Down
33 changes: 33 additions & 0 deletions code/controllers/subsystem/screentip.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
SUBSYSTEM_DEF(screentips)
name = "screentips"
wait = 1
// Allocated a relatively small amount of processing time
priority = FIRE_PRIORITY_SCREENTIPS
flags = SS_NO_INIT | SS_TICKER
// Head of the scanning loop
var/client/head = null

/datum/controller/subsystem/screentips/fire(resumed)
while (head != null && !MC_TICK_CHECK)
if (QDELETED(head.hovered_atom) || head.screentip_last_process == times_fired)
head.hovered_atom = null
head = head.screentip_next
continue
head.hovered_atom.on_mouse_enter(head)
head.hovered_atom = null
head.screentip_last_process = times_fired
head = head.screentip_next

/datum/controller/subsystem/screentips/proc/on_client_disconnected(client/target)
SHOULD_NOT_SLEEP(TRUE)
var/client/current = head
if (current == target)
head = current.screentip_next
return
while (current != null)
var/client/next = current.screentip_next
if (next != target)
current = next
continue
current.screentip_next = next.screentip_next
return
13 changes: 13 additions & 0 deletions code/datums/ai/dog/dog_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
RegisterSignal(new_pawn, COMSIG_PARENT_EXAMINE, PROC_REF(on_examined))
RegisterSignal(new_pawn, COMSIG_CLICK_ALT, PROC_REF(check_altclicked))
RegisterSignals(new_pawn, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), PROC_REF(on_death))
RegisterSignal(new_pawn, COMSIG_ATOM_ADD_CONTEXT, PROC_REF(add_context))
RegisterSignal(SSdcs, COMSIG_GLOB_CARBON_THROW_THING, PROC_REF(listened_throw))
return ..() //Run parent at end

Expand Down Expand Up @@ -273,3 +274,15 @@
if(living_pawn.buckled)
queue_behavior(/datum/ai_behavior/resist)//in case they are in bed or something
queue_behavior(/datum/ai_behavior/harass)

/**
* Arguments:
* * source -
* * context -
* * user - refers to user who will see the screentip when the proper context is there
*/
/datum/ai_controller/dog/proc/add_context(datum/source, datum/screentip_context/context, mob/user)
if (user.a_intent == INTENT_HARM)
context.add_attack_hand_action("Punch")
else
context.add_attack_hand_action("Pet")
4 changes: 4 additions & 0 deletions code/datums/brain_damage/special.dm
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@
user.visible_message("<span class='warning'>[user] [slip_in_message].</span>", null, null, null, user)
user.visible_message("<span class='warning'>[user] [slip_out_message].</span>", "<span class='notice'>...and find your way to the other side.</span>")

/obj/effect/hallucination/simple/bluespace_stream/add_context_self(datum/screentip_context/context, mob/user, obj/item/item)
context.use_cache()
context.add_attack_hand_action("Teleport")

/datum/brain_trauma/special/tenacity
name = "Tenacity"
desc = "Patient is psychologically unaffected by pain and injuries, and can remain standing far longer than a normal person."
Expand Down
1 change: 0 additions & 1 deletion code/datums/elements/climbable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
structure_climber.Paralyze(40)
structure_climber.visible_message("<span class='warning'>[structure_climber] is knocked off [climbed_thing].</span>", "<span class='warning'>You're knocked off [climbed_thing]!</span>", "<span class='hear'>You hear a cry from [structure_climber], followed by a slam.</span>")


/datum/element/climbable/proc/climb_structure(atom/climbed_thing, mob/living/user, params)
if(!can_climb(climbed_thing, user))
return
Expand Down
20 changes: 18 additions & 2 deletions code/datums/elements/food/processable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
var/amount_created
///Whether or not the atom being processed has to be on a table or tray to process it
var/table_required
///Verb used in processing food (such as slice, flatten), defaults to process
var/screentip_verb

/datum/element/processable/Attach(datum/target, tool_behaviour, result_atom_type, amount_created = 3, time_to_process = 2 SECONDS, table_required = FALSE)
/datum/element/processable/Attach(datum/target, tool_behaviour, result_atom_type, amount_created = 3, time_to_process = 2 SECONDS, table_required = FALSE, screentip_verb = "Process")
. = ..()
if(!isatom(target))
return ELEMENT_INCOMPATIBLE
Expand All @@ -23,13 +25,17 @@
src.time_to_process = time_to_process
src.result_atom_type = result_atom_type
src.table_required = table_required
src.screentip_verb = screentip_verb

var/atom/atom_target = target

RegisterSignal(atom_target, COMSIG_ATOM_ADD_CONTEXT, PROC_REF(on_requesting_context_from_item))
RegisterSignal(target, COMSIG_ATOM_TOOL_ACT(tool_behaviour), PROC_REF(try_process))
RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(OnExamine))

/datum/element/processable/Detach(datum/target)
. = ..()
UnregisterSignal(target, list(COMSIG_ATOM_TOOL_ACT(tool_behaviour), COMSIG_PARENT_EXAMINE))
UnregisterSignal(target, list(COMSIG_ATOM_TOOL_ACT(tool_behaviour), COMSIG_PARENT_EXAMINE, COMSIG_ATOM_ADD_CONTEXT))

/datum/element/processable/proc/try_process(datum/source, mob/living/user, obj/item/I, list/mutable_recipes)
SIGNAL_HANDLER
Expand Down Expand Up @@ -67,3 +73,13 @@
examine_list += "<span class='notice'>It can be turned into some [result_name] with <b>[tool_desc]</b>!</span>"
else
examine_list += "<span class='notice'>It can be turned into \a [result_name] with <b>[tool_desc]</b>!</span>"

/**
* Arguments:
* * source - refers to item that will display its screentip
* * context - refers to, in this case, an item that can be proccessed into another item via add element proccessable
* * user - refers to user who will see the screentip when the proper context and tool are there
*/
/datum/element/processable/proc/on_requesting_context_from_item(datum/source, datum/screentip_context/context, mob/user)
SIGNAL_HANDLER
context.add_left_click_tool_action("[screentip_verb] into [initial(result_atom_type.name)]", tool_behaviour)
12 changes: 12 additions & 0 deletions code/game/machinery/PDApainter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
storedid = null
update_icon()

/obj/machinery/pdapainter/add_context_self(datum/screentip_context/context, mob/user, obj/item/item)
context.use_cache()
if(storedpda || storedid)
context.add_attack_hand_action("Paint Item")
context.add_alt_click_action("Eject Item")
else
context.add_left_click_item_action("Insert", /obj/item/modular_computer/tablet/pda)
context.add_left_click_item_action("Insert", /obj/item/card/id)
if (machine_stat & BROKEN)
context.add_left_click_tool_action("Repair", TOOL_WELDER)
context.add_generic_unfasten_actions(src)

/proc/get_card_style_list(emagged)
var/static/valid_jobs = list(
"----Command----", "Command (Custom)",JOB_NAME_CAPTAIN,"Acting Captain",
Expand Down
9 changes: 5 additions & 4 deletions code/game/machinery/airlock_control.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#define AIRLOCK_CONTROL_RANGE 5

// This code allows for airlocks to be controlled externally by setting an id_tag and comm frequency (disables ID access)
/obj/machinery/door/airlock
var/frequency
var/datum/radio_frequency/radio_connection
smoothing_groups = list(SMOOTH_GROUP_AIRLOCK)
/obj/machinery/door/airlock/var/frequency
/obj/machinery/door/airlock/var/datum/radio_frequency/radio_connection
/obj/machinery/door/airlock/smoothing_groups = list(SMOOTH_GROUP_AIRLOCK)

/obj/machinery/door/airlock/receive_signal(datum/signal/signal)
if(!signal)
Expand Down Expand Up @@ -120,6 +119,8 @@
else
icon_state = "airlock_sensor_off"

SCREENTIP_ATTACK_HAND(/obj/machinery/airlock_sensor, "Use")

/obj/machinery/airlock_sensor/attack_hand(mob/user)
. = ..()
if(.)
Expand Down
3 changes: 1 addition & 2 deletions code/game/machinery/airlock_cycle_control.dm
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,7 @@
new /obj/item/stack/cable_coil(loc, 3)
qdel(src)

/obj/machinery/door/airlock
var/obj/machinery/advanced_airlock_controller/aac
/obj/machinery/door/airlock/var/obj/machinery/advanced_airlock_controller/aac

/obj/machinery/door/airlock/Initialize(mapload)
. = ..()
Expand Down
2 changes: 2 additions & 0 deletions code/game/machinery/aug_manipulator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
else
return ..()

SCREENTIP_ATTACK_HAND(/obj/machinery/aug_manipulator, "Use")

/obj/machinery/aug_manipulator/attack_hand(mob/user)
. = ..()
if(.)
Expand Down
16 changes: 16 additions & 0 deletions code/game/machinery/buttons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,19 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/button/shieldwallgen, 24)

/obj/machinery/button/shieldwallgen/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
id = "[REF(port)][id]"

/obj/machinery/button/add_context_self(datum/screentip_context/context, mob/user)
if (length(req_access) || length(req_one_access) || req_access_txt != "0" || req_one_access_txt != "0")
context.add_access_context("Access Required", allowed(user))
if (context.accept_silicons())
if (!panel_open)
context.add_attack_hand_action("Activate")
return
if (panel_open)
if(device || board)
context.add_attack_hand_action("Remove Electronics")
else
context.add_attack_hand_action("Change Appearance")
else
context.add_attack_hand_action("Push")
context.add_left_click_item_action("Hack", /obj/item/card/emag)
9 changes: 9 additions & 0 deletions code/game/machinery/cell_charger.dm
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,12 @@
charging.give(charge_rate * delta_time) //this is 2558, efficient batteries exist

update_icon()

/obj/machinery/cell_charger/add_context_self(datum/screentip_context/context, mob/user)
if (charging)
context.add_attack_hand_action("Take Item")
if (!panel_open)
context.add_left_click_item_action("Charge Item", /obj/item/stock_parts/cell)
if (!charging)
context.add_generic_deconstruction_actions(src)
context.add_generic_unfasten_actions(src, TRUE)
Loading
Loading