Refactor, improve, and rename canUseTopic to be can_perform_action (#73434)

This builds on what #69790 did and improved the code even further.
Notable things:
- `Topic()` is a deprecated proc in our codebase (replaced with
Javascript tgui) so it makes sense to rename `canUseTopic` to
`can_perform_action` which is more straightforward in what it does.
- Positional and named arguments have been converted into a easier to
use `action_bitflag`
- The bitflags adds some new checks you can use like: `NEED_GRAVITY |
NEED_LITERACY | NEED_LIGHT` when you want to perform an action.
- Redundant, duplicate, or dead code has been removed.
- Fixes several runtimes where `canUseTopic` was being called without a
proper target (IV drips, gibber, food processor)
- Better documentation for the proc and bitflags with examples
This commit is contained in:
Tim
2023-02-16 20:22:14 -05:00
committed by GitHub
parent 3c22292ce1
commit a1ada2c9ef
181 changed files with 353 additions and 294 deletions
+17
View File
@@ -775,6 +775,23 @@ GLOBAL_LIST_INIT(layers_to_offset, list(
/// The layer above mutant body parts
#define ABOVE_BODY_FRONT_LAYER (BODY_FRONT_LAYER-1)
/// If gravity must be present to perform action (can't use pens without gravity)
#define NEED_GRAVITY (1<<0)
/// If reading is required to perform action (can't read a book if you are illiterate)
#define NEED_LITERACY (1<<1)
/// If lighting must be present to perform action (can't heal someone in the dark)
#define NEED_LIGHT (1<<2)
/// If other mobs (monkeys, aliens, etc) can perform action (can't use computers if you are a monkey)
#define NEED_DEXTERITY (1<<3)
/// If hands are required to perform action (can't use objects that require hands if you are a cyborg)
#define NEED_HANDS (1<<4)
/// If telekinesis is forbidden to perform action from a distance (ex. canisters are blacklisted from telekinesis manipulation)
#define FORBID_TELEKINESIS_REACH (1<<5)
/// If silicons are allowed to perform action from a distance (silicons can operate airlocks from far away)
#define ALLOW_SILICON_REACH (1<<6)
/// If resting on the floor is allowed to perform action (pAIs can play music while resting)
#define ALLOW_RESTING (1<<7)
/// The default mob sprite size (used for shrinking or enlarging the mob sprite to regular size)
#define RESIZE_DEFAULT_SIZE 1
+1 -1
View File
@@ -91,7 +91,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
///Toggles the tracking for the gps
/datum/component/gps/item/proc/toggletracking(mob/user)
if(!user.canUseTopic(parent, be_close = TRUE))
if(!user.can_perform_action(parent))
return //user not valid to use gps
if(emped)
to_chat(user, span_warning("It's busted!"))
+2 -2
View File
@@ -122,7 +122,7 @@
if(user.mind.holy_role != HOLY_ROLE_HIGHPRIEST)
to_chat(user, "<span class='warning'>You are not the high priest, and therefore cannot select a religious sect.")
return
if(!user.canUseTopic(parent, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(parent, FORBID_TELEKINESIS_REACH))
to_chat(user,span_warning("You cannot select a sect at this time."))
return
if(GLOB.religious_sect)
@@ -152,7 +152,7 @@
if(performing_rite)
to_chat(user, "<span class='notice'>There is a rite currently being performed here already.")
return
if(!user.canUseTopic(parent, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(parent, FORBID_TELEKINESIS_REACH))
to_chat(user,span_warning("You are not close enough to perform the rite."))
return
performing_rite = new path(parent)
+1 -1
View File
@@ -102,7 +102,7 @@
AfterRotation.Invoke(user, degrees)
/datum/component/simple_rotation/proc/CanUserRotate(mob/user, degrees)
if(isliving(user) && user.canUseTopic(parent, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(isliving(user) && user.can_perform_action(parent, NEED_DEXTERITY))
return TRUE
if((rotation_flags & ROTATION_GHOSTS_ALLOWED) && isobserver(user) && CONFIG_GET(flag/ghost_interaction))
return TRUE
+1 -1
View File
@@ -91,7 +91,7 @@
var/mob/living/living = movee
//Check if we can interact with stuff (checks for alive, arms, stun, etc)
if(!living.canUseTopic(living, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE, need_hands = TRUE))
if(!living.can_perform_action(living, FORBID_TELEKINESIS_REACH|NEED_HANDS))
return NOT_HOLDING_ON
if(living.buckled)
@@ -18,7 +18,7 @@
return
var/safety = tgui_alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [to_insert.name]?", list("Proceed", "Abort"))
if(safety != "Proceed" || QDELETED(to_insert) || QDELETED(resolve_parent) || QDELETED(user) || !user.canUseTopic(resolve_parent, be_close = TRUE, no_dexterity = iscarbon(user)))
if(safety != "Proceed" || QDELETED(to_insert) || QDELETED(resolve_parent) || QDELETED(user) || !iscarbon(user) || !user.can_perform_action(resolve_parent, NEED_DEXTERITY))
return
var/turf/loccheck = get_turf(resolve_parent)
+1 -1
View File
@@ -683,7 +683,7 @@
..()
if(!can_interact(usr))
return TRUE
if(!usr.canUseTopic(src))
if(!usr.can_perform_action(src))
return TRUE
add_fingerprint(usr)
update_last_used(usr)
+4 -4
View File
@@ -124,7 +124,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
. = ..()
if(.)
return
if(!usr.canUseTopic(src, !issilicon(usr)))
if(!usr.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(machine_stat & BROKEN)
visible_message(span_warning("[src] buzzes."), span_hear("You hear a faint buzz."))
@@ -133,14 +133,14 @@ GLOBAL_LIST_EMPTY(announcement_systems)
switch(action)
if("ArrivalText")
var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN)
if(!usr.canUseTopic(src, !issilicon(usr)))
if(!usr.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(NewMessage)
arrival = NewMessage
usr.log_message("updated the arrivals announcement to: [NewMessage]", LOG_GAME)
if("NewheadText")
var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN)
if(!usr.canUseTopic(src, !issilicon(usr)))
if(!usr.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(NewMessage)
newhead = NewMessage
@@ -157,7 +157,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
. = attack_ai(user)
/obj/machinery/announcement_system/attack_ai(mob/user)
if(!user.canUseTopic(src, !issilicon(user)))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(machine_stat & BROKEN)
to_chat(user, span_warning("[src]'s firmware appears to be malfunctioning!"))
+1 -1
View File
@@ -250,7 +250,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
var/obj/item/choice = tgui_input_list(user, "Select a part to remove", "Part Removal", sort_names(droppable_parts))
if(isnull(choice))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
to_chat(user, span_notice("You remove [choice] from [src]."))
if(choice == assembly.xray_module)
@@ -203,7 +203,7 @@
var/obj/item/choice = tgui_input_list(user, "Select a part to remove", "Part Removal", sort_names(droppable_parts))
if(isnull(choice))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
to_chat(user, span_notice("You remove [choice] from [src]."))
drop_upgrade(choice)
+1 -1
View File
@@ -175,7 +175,7 @@
return
if(!pad_ref?.resolve())
return
if(!usr.canUseTopic(src, be_close = TRUE) || (machine_stat & (NOPOWER|BROKEN)))
if(!usr.can_perform_action(src) || (machine_stat & (NOPOWER|BROKEN)))
return
switch(action)
if("recalc")
+1 -1
View File
@@ -131,7 +131,7 @@
. = ..()
if(!can_interact(user))
return
if(!user.canUseTopic(src, be_close = !issilicon(user)) || !is_operational)
if(!user.can_perform_action(src, ALLOW_SILICON_REACH) || !is_operational)
return
/obj/machinery/computer/ui_interact(mob/user, datum/tgui/ui)
@@ -735,7 +735,7 @@
to_chat(user, span_alert("Intercomms recharging. Please stand by."))
return
var/input = tgui_input_text(user, "Message to announce to the station crew", "Announcement")
if(!input || !user.canUseTopic(src, !issilicon(usr)))
if(!input || !user.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(user.try_speak(input))
//Adds slurs and so on. Someone should make this use languages too.
+1 -1
View File
@@ -215,7 +215,7 @@
. = ..()
if(!can_interact(user))
return
if(!user.canUseTopic(src, !issilicon(user)))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH))
return
eject_disk(user)
@@ -129,7 +129,7 @@
/// Inserts a new record into GLOB.manifest.general. Requires a photo to be taken.
/obj/machinery/computer/records/proc/insert_new_record(mob/user, obj/item/photo/mugshot)
if(!mugshot || !is_operational || !user.canUseTopic(src, be_close = !issilicon(user)))
if(!mugshot || !is_operational || !user.can_perform_action(src, ALLOW_SILICON_REACH))
return FALSE
if(!authenticated && !has_auth(user))
@@ -139,7 +139,7 @@
var/trimmed = copytext(mugshot.name, 9, MAX_NAME_LEN) // Remove "photo - "
var/name = tgui_input_text(user, "Enter the name of the new record.", "New Record", trimmed, MAX_NAME_LEN)
if(!name || !is_operational || !user.canUseTopic(src, be_close = !issilicon(user)) || !mugshot || QDELETED(mugshot) || QDELETED(src))
if(!name || !is_operational || !user.can_perform_action(src, ALLOW_SILICON_REACH) || !mugshot || QDELETED(mugshot) || QDELETED(src))
return FALSE
new /datum/record/crew(name = name, character_appearance = mugshot.picture.picture_image)
@@ -153,7 +153,7 @@
/// Secure login
/obj/machinery/computer/records/proc/secure_login(mob/user)
if(!user.canUseTopic(src, be_close = !issilicon(user)) || !is_operational)
if(!user.can_perform_action(src, ALLOW_SILICON_REACH) || !is_operational)
return FALSE
if(!has_auth(user))
+1 -1
View File
@@ -155,7 +155,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
return TRUE
/obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return
if(!defib)
to_chat(user, span_warning("It'd be hard to remove a defib unit from a mount that has none."))
+1 -1
View File
@@ -178,7 +178,7 @@
. += span_notice("Alt-click to toggle modes.")
/obj/item/grenade/barrier/AltClick(mob/living/carbon/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return
toggle_mode(user)
+1 -1
View File
@@ -104,7 +104,7 @@
do_the_dishes(TRUE)
/obj/machinery/dish_drive/AltClick(mob/living/user)
if(user.canUseTopic(src, !issilicon(user)))
if(user.can_perform_action(src, ALLOW_SILICON_REACH))
do_the_dishes(TRUE)
/obj/machinery/dish_drive/proc/do_the_dishes(manual)
+1 -1
View File
@@ -45,7 +45,7 @@
if (deconstruction != BLASTDOOR_FINISHED)
return
var/change_id = tgui_input_number(user, "Set the door controllers ID", "Door Controller ID", id, 100)
if(!change_id || QDELETED(usr) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!change_id || QDELETED(usr) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
id = change_id
to_chat(user, span_notice("You change the ID to [id]."))
+1 -1
View File
@@ -99,7 +99,7 @@
to_chat(user, span_warning("The safety hatch has been disabled!"))
/obj/machinery/fat_sucker/AltClick(mob/living/user)
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
if(user == occupant)
to_chat(user, span_warning("You can't reach the controls from inside!"))
+3 -3
View File
@@ -158,7 +158,7 @@
/obj/machinery/iv_drip/MouseDrop(atom/target)
. = ..()
if(!Adjacent(target) || !usr.canUseTopic(src, be_close = TRUE))
if(!Adjacent(target) || !usr.can_perform_action(src))
return
if(!isliving(usr))
to_chat(usr, span_warning("You can't do that!"))
@@ -325,7 +325,7 @@
if(!isliving(usr))
to_chat(usr, span_warning("You can't do that!"))
return
if (!usr.canUseTopic())
if(!usr.can_perform_action(src))
return
if(usr.incapacitated())
return
@@ -345,7 +345,7 @@
if(!isliving(usr))
to_chat(usr, span_warning("You can't do that!"))
return
if (!usr.canUseTopic())
if(!usr.can_perform_action(src))
return
if(usr.incapacitated())
return
+1 -1
View File
@@ -287,7 +287,7 @@
/obj/machinery/launchpad/briefcase/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr)
if(!briefcase || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!briefcase || !usr.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
usr.visible_message(span_notice("[usr] starts closing [src]..."), span_notice("You start closing [src]..."))
if(do_after(usr, 30, target = usr))
+1 -1
View File
@@ -125,7 +125,7 @@
return ..()
/obj/machinery/medical_kiosk/AltClick(mob/living/carbon/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return
if(!scanner_wand)
to_chat(user, span_warning("The scanner wand is currently removed from the machine."))
+1 -1
View File
@@ -166,7 +166,7 @@
var/s = tgui_input_text(user, "Write something", "Newspaper")
if (!s)
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
scribble_page = curr_page
scribble = s
@@ -182,7 +182,7 @@
var/choice = tgui_input_text(user, "Enter a new turret name", "Turret Classification", finish_name, MAX_NAME_LEN)
if(!choice)
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
finish_name = choice
+1 -1
View File
@@ -166,7 +166,7 @@
/obj/machinery/sleeper/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, !issilicon(user)))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH))
return
if(state_open)
close_machine()
+1 -1
View File
@@ -424,7 +424,7 @@
/obj/machinery/space_heater/improvised_chem_heater/AltClick(mob/living/user)
. = ..()
if(!can_interact(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!can_interact(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
replace_beaker(user)
+1 -1
View File
@@ -39,7 +39,7 @@
. = ..()
if(!can_interact(user))
return
if(world.time >= stasis_can_toggle && user.canUseTopic(src, !issilicon(user)))
if(world.time >= stasis_can_toggle && user.can_perform_action(src, ALLOW_SILICON_REACH))
stasis_enabled = !stasis_enabled
stasis_can_toggle = world.time + STASIS_TOGGLE_COOLDOWN
playsound(src, 'sound/machines/click.ogg', 60, TRUE)
+2 -2
View File
@@ -229,10 +229,10 @@
update_appearance()
/obj/machinery/syndicatebomb/proc/settings(mob/user)
if(!user.canUseTopic(src, !issilicon(user)) || !user.can_interact_with(src))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH) || !user.can_interact_with(src))
return
var/new_timer = tgui_input_number(user, "Set the timer", "Countdown", timer_set, maximum_timer, minimum_timer)
if(!new_timer || QDELETED(user) || QDELETED(src) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!new_timer || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
timer_set = new_timer
loc.visible_message(span_notice("[icon2html(src, viewers(src))] timer set for [timer_set] seconds."))
+1 -1
View File
@@ -389,7 +389,7 @@ GLOBAL_LIST_INIT(dye_registry, list(
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return
if(!user.canUseTopic(src, !issilicon(user)))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH))
return SECONDARY_ATTACK_CONTINUE_CHAIN
if(busy)
to_chat(user, span_warning("[src] is busy!"))
@@ -34,7 +34,7 @@
/obj/item/ai_module/supplied/freeform/attack_self(mob/user)
var/newpos = tgui_input_number(user, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority ", lawpos, 50, 15)
if(!newpos || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!newpos || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
lawpos = newpos
var/targName = tgui_input_text(user, "Enter a new law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len), TRUE)
+1 -1
View File
@@ -12,7 +12,7 @@
/obj/item/ai_module/remove/attack_self(mob/user)
lawpos = tgui_input_number(user, "Law to delete", "Law Removal", lawpos, 50)
if(!lawpos || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!lawpos || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
to_chat(user, span_notice("Law [lawpos] selected."))
..()
+1 -1
View File
@@ -29,7 +29,7 @@
/obj/item/areaeditor/Topic(href, href_list)
if(..())
return TRUE
if(!usr.canUseTopic(src) || usr != loc)
if(!usr.can_perform_action(src) || usr != loc)
usr << browse(null, "window=blueprints")
return TRUE
if(href_list["create_area"])
+3 -3
View File
@@ -626,7 +626,7 @@
/obj/item/card/id/proc/alt_click_can_use_id(mob/living/user)
if(!isliving(user))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
return TRUE
@@ -1226,7 +1226,7 @@
to_chat(user, "Restating prisoner ID to default parameters.")
return
var/choice = tgui_input_number(user, "Sentence time in seconds", "Sentencing")
if(!choice || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE) || loc != user)
if(!choice || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH) || loc != user)
return FALSE
time_to_assign = choice
to_chat(user, "You set the sentence time to [time_to_assign] seconds.")
@@ -1552,7 +1552,7 @@
assignment = target_occupation
var/new_age = tgui_input_number(user, "Choose the ID's age", "Agent card age", AGE_MIN, AGE_MAX, AGE_MIN)
if(QDELETED(user) || QDELETED(src) || !user.canUseTopic(user, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE))
if(QDELETED(user) || QDELETED(src) || !user.can_perform_action(user, NEED_DEXTERITY| FORBID_TELEKINESIS_REACH))
return
if(new_age)
registered_age = new_age
+1 -1
View File
@@ -27,7 +27,7 @@
/// Checks if this mob can use the beacon, returns TRUE if so or FALSE otherwise.
/obj/item/choice_beacon/proc/can_use_beacon(mob/living/user)
if(user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, TRUE)
@@ -773,7 +773,7 @@
/obj/item/circuitboard/machine/medical_kiosk/multitool_act(mob/living/user)
. = ..()
var/new_cost = tgui_input_number(user, "New cost for using this medical kiosk", "Pricing", custom_cost, 1000, 10)
if(!new_cost || QDELETED(user) || QDELETED(src) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!new_cost || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
if(loc != user)
to_chat(user, span_warning("You must hold the circuitboard to change its cost!"))
+2 -2
View File
@@ -158,7 +158,7 @@
if (H == user)
to_chat(user, span_warning("You need a mirror to properly style your own facial hair!"))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
var/new_style = tgui_input_list(user, "Select a facial hairstyle", "Grooming", GLOB.facial_hairstyles_list)
if(isnull(new_style))
@@ -209,7 +209,7 @@
if (H == user)
to_chat(user, span_warning("You need a mirror to properly style your own hair!"))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
var/new_style = tgui_input_list(user, "Select a hairstyle", "Grooming", GLOB.hairstyles_list)
if(isnull(new_style))
+1 -1
View File
@@ -162,7 +162,7 @@
ui.open()
/obj/item/toy/crayon/spraycan/AltClick(mob/user)
if(has_cap && user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(has_cap && user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
is_capped = !is_capped
to_chat(user, span_notice("The cap on [src] is now [is_capped ? "on" : "off"]."))
update_appearance()
+2 -2
View File
@@ -99,13 +99,13 @@
qdel(H)
/obj/item/holochip/AltClick(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(!user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
return
if(loc != user)
to_chat(user, span_warning("You must be holding the holochip to continue!"))
return FALSE
var/split_amount = tgui_input_number(user, "How many credits do you want to extract from the holochip? (Max: [credits] cr)", "Holochip", max_value = credits)
if(!split_amount || QDELETED(user) || QDELETED(src) || issilicon(user) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)) || loc != user)
if(!split_amount || QDELETED(user) || QDELETED(src) || issilicon(user) || !usr.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH) || loc != user)
return
var/new_credits = spend(split_amount, TRUE)
var/obj/item/holochip/H = new(user ? user : drop_location(), new_credits)
+1 -1
View File
@@ -34,7 +34,7 @@
/obj/item/beacon/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/pen)) // needed for things that use custom names like the locator
var/new_name = tgui_input_text(user, "What would you like the name to be?", "Beacon", max_length = MAX_NAME_LEN)
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
if(new_name)
name = new_name
@@ -33,10 +33,10 @@
. += span_notice("Can be used again to interrupt the effect early. The recharge time is the same as the time spent in desync.")
/obj/item/desynchronizer/AltClick(mob/living/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!user.can_perform_action(src, NEED_DEXTERITY))
return
var/new_duration = tgui_input_number(user, "Set the duration", "Desynchronizer", duration / 10, max_duration, 5)
if(!new_duration || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!new_duration || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, NEED_DEXTERITY))
return
duration = new_duration
to_chat(user, span_notice("You set the duration to [DisplayTimeText(duration)]."))
@@ -111,7 +111,7 @@
to_chat(user, span_notice("[icon2html(src, user)] [isliving(target) ? "Subject" : "Target"] is free of radioactive contamination."))
/obj/item/geiger_counter/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return ..()
if(!scanning)
to_chat(usr, span_warning("[src] must be on to reset its radiation level!"))
@@ -80,7 +80,7 @@
/obj/item/storage/portable_chem_mixer/AltClick(mob/living/user)
if(!atom_storage.locked)
return ..()
if(!can_interact(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!can_interact(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
replace_beaker(user)
update_appearance()
@@ -41,7 +41,7 @@
. += span_notice("Insert [src] into an active quantum pad to link it.")
/obj/item/quantum_keycard/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY))
return
to_chat(user, span_notice("You start pressing [src]'s unlink button..."))
if(do_after(user, 40, target = src))
@@ -92,7 +92,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
/obj/item/radio/headset/MouseDrop(mob/over, src_location, over_location)
var/mob/headset_user = usr
if((headset_user == over) && headset_user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if((headset_user == over) && headset_user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return attack_self(headset_user)
return ..()
@@ -46,7 +46,7 @@
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
..()
if(!user.canUseTopic(src, be_close = TRUE) || !user.can_read(src))
if(!user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT))
return
if(cooldown)
@@ -447,7 +447,7 @@
/obj/item/healthanalyzer/AltClick(mob/user)
..()
if(!user.canUseTopic(src, be_close = TRUE) || !user.can_read(src) || user.is_blind())
if(!user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT) || user.is_blind())
return
mode = !mode
@@ -80,7 +80,7 @@
var/answer = tgui_input_list(user, "Analyze Potential", "Sequence Analyzer", sort_list(options))
if(isnull(answer))
return
if(!ready || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE) || !user.can_read(src))
if(!ready || !user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT|FORBID_TELEKINESIS_REACH))
return
var/sequence
+1 -1
View File
@@ -67,7 +67,7 @@
. += span_notice("<b>Not Linked.</b> Use on another quantum spin inverter to establish a quantum link.")
/obj/item/swapper/AltClick(mob/living/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!user.can_perform_action(src, NEED_DEXTERITY))
return
to_chat(user, span_notice("You break the current quantum link."))
if(!QDELETED(linked_swapper))
+1 -1
View File
@@ -50,7 +50,7 @@
icon_state = base_icon_state
/obj/item/reagent_containers/cup/blastoff_ampoule/attack_self(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE) || spillable)
if(!user.can_perform_action(src, NEED_DEXTERITY) || spillable)
return ..()
reagent_flags |= OPENCONTAINER
spillable = TRUE
+3 -3
View File
@@ -24,18 +24,18 @@
return
var/mob/living/carbon/human/human_target = target
var/beard_or_hair = tgui_alert(user, "What do you want to dye?", "Character Preference", list("Hair", "Facial Hair"))
if(!beard_or_hair || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE))
if(!beard_or_hair || !user.can_perform_action(src, NEED_DEXTERITY))
return
var/list/choices = beard_or_hair == "Hair" ? GLOB.hair_gradients_list : GLOB.facial_hair_gradients_list
var/new_grad_style = tgui_input_list(user, "Choose a color pattern", "Character Preference", choices)
if(isnull(new_grad_style))
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE))
if(!user.can_perform_action(src, NEED_DEXTERITY))
return
var/new_grad_color = input(user, "Choose a secondary hair color:", "Character Preference",human_target.grad_color) as color|null
if(!new_grad_color || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE) || !user.CanReach(target))
if(!new_grad_color || !user.can_perform_action(src, NEED_DEXTERITY) || !user.CanReach(target))
return
to_chat(user, span_notice("You start applying the hair dye..."))
+1 -1
View File
@@ -261,7 +261,7 @@
source.delay = 3
/obj/item/extinguisher/AltClick(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
if(!user.is_holding(src))
to_chat(user, span_notice("You must be holding the [src] in your hands do this!"))
+1 -1
View File
@@ -153,7 +153,7 @@
toggle_igniter(user)
/obj/item/flamethrower/AltClick(mob/user)
if(ptank && isliving(user) && user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(ptank && isliving(user) && user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
user.put_in_hands(ptank)
ptank = null
to_chat(user, span_notice("You remove the plasma tank from [src]!"))
+1 -1
View File
@@ -202,7 +202,7 @@
var/newtime = tgui_input_list(user, "Please enter a new detonation time", "Detonation Timer", list("Instant", 3, 4, 5))
if (isnull(newtime))
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
if(newtime == "Instant" && change_det_time(0))
to_chat(user, span_notice("You modify the time delay. It's set to be instantaneous."))
@@ -355,7 +355,7 @@
if (active)
return
var/newspread = tgui_input_number(user, "Please enter a new spread amount", "Grenade Spread", 5, 100, 5)
if(!newspread || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!newspread || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
unit_spread = newspread
to_chat(user, span_notice("You set the time release to [unit_spread] units per detonation."))
+1 -1
View File
@@ -77,7 +77,7 @@
/obj/item/grenade/c4/attack_self(mob/user)
var/newtime = tgui_input_number(user, "Please set the timer", "C4 Timer", minimum_timer, maximum_timer, minimum_timer)
if(!newtime || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!newtime || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
det_time = newtime
to_chat(user, "Timer set for [det_time] seconds.")
@@ -28,7 +28,7 @@
if(!user.can_write(used_item))
return
var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN)
if((user.get_active_held_item() != used_item) || !user.canUseTopic(src, be_close = TRUE))
if((user.get_active_held_item() != used_item) || !user.can_perform_action(src))
return
if(new_name)
name = "implant case - '[new_name]'"
@@ -53,7 +53,7 @@
var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN)
if(user.get_active_held_item() != I)
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
if(new_name)
name = "implanter ([new_name])"
@@ -34,7 +34,7 @@
/obj/item/implantpad/AltClick(mob/user)
..()
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
if(!case)
to_chat(user, span_warning("There's no implant to remove from [src]."))
@@ -60,7 +60,7 @@
return ..()
/obj/item/implantpad/ui_interact(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
user.unset_machine(src)
user << browse(null, "window=implantpad")
return
+2 -2
View File
@@ -77,7 +77,7 @@
return ..()
/obj/item/inspector/CtrlClick(mob/living/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands= !iscyborg(user)) || !cell_cover_open || !cell)
if(!user.can_perform_action(src, NEED_DEXTERITY) || !cell_cover_open || !cell)
return ..()
user.visible_message(span_notice("[user] removes \the [cell] from [src]!"), \
span_notice("You remove [cell]."))
@@ -380,7 +380,7 @@
grind_results = list(/datum/reagent/water = 5)
/obj/item/paper/fake_report/water/AltClick(mob/living/user, obj/item/I)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
var/datum/action/innate/origami/origami_action = locate() in user.actions
if(origami_action?.active) //Origami masters can fold water
+7 -6
View File
@@ -52,10 +52,11 @@
. += span_notice("It has [L] inside.")
else
. += span_notice("It has nothing inside.")
if(user.canUseTopic(src))
. += span_notice("Activate it in your hand to [open ? "close" : "open"] its door. Click-drag onto floor to release its occupants.")
if(!open)
. += span_notice("Alt-click to [locked ? "unlock" : "lock"] its door.")
// At some point these need to be converted to contextual screentips
. += span_notice("Activate it in your hand to [open ? "close" : "open"] its door. Click-drag onto floor to release its occupants.")
if(!open)
. += span_notice("Alt-click to [locked ? "unlock" : "lock"] its door.")
/obj/item/pet_carrier/attack_self(mob/living/user)
if(open)
@@ -72,7 +73,7 @@
update_appearance()
/obj/item/pet_carrier/AltClick(mob/living/user)
if(open || !user.canUseTopic(src, be_close = TRUE))
if(open || !user.can_perform_action(src))
return
locked = !locked
to_chat(user, span_notice("You flip the lock switch [locked ? "down" : "up"]."))
@@ -157,7 +158,7 @@
/obj/item/pet_carrier/MouseDrop(atom/over_atom)
. = ..()
if(isopenturf(over_atom) && usr.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(usr)) && usr.Adjacent(over_atom) && open && occupants.len)
if(isopenturf(over_atom) && usr.can_perform_action(src, NEED_DEXTERITY) && usr.Adjacent(over_atom) && open && occupants.len)
usr.visible_message(span_notice("[usr] unloads [src]."), \
span_notice("You unload [src] onto [over_atom]."))
for(var/V in occupants)
+1 -1
View File
@@ -23,7 +23,7 @@
if(!user.can_write(writing_instrument))
return
var/txt = tgui_input_text(user, "What would you like to write on the sign?", "Sign Label", max_length = 30)
if(txt && user.canUseTopic(src, be_close = TRUE))
if(txt && user.can_perform_action(src))
label = txt
name = "[label] sign"
desc = "It reads: [label]"
+1 -1
View File
@@ -147,7 +147,7 @@
. += span_notice("Alt-click to set your war cry.")
/obj/item/spear/explosive/AltClick(mob/user)
if(user.canUseTopic(src, be_close = TRUE))
if(user.can_perform_action(src))
..()
if(istype(user) && loc == user)
var/input = tgui_input_text(user, "What do you want your war cry to be? You will shout it when you hit someone in melee.", "War Cry", max_length = 50)
+2 -2
View File
@@ -657,13 +657,13 @@
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return
if(is_cyborg || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(is_cyborg || !user.can_perform_action(src, NEED_DEXTERITY))
return SECONDARY_ATTACK_CONTINUE_CHAIN
if(is_zero_amount(delete_if_zero = TRUE))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
var/max = get_amount()
var/stackmaterial = tgui_input_number(user, "How many sheets do you wish to take out of this stack?", "Stack Split", max_value = max)
if(!stackmaterial || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(!stackmaterial || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
split_stack(user, stackmaterial)
to_chat(user, span_notice("You take [stackmaterial] sheets out of the stack."))
+1 -1
View File
@@ -39,7 +39,7 @@
/obj/item/stack/wrapping_paper/attack_hand_secondary(mob/user, modifiers)
var/new_base = input(user, "", "Select a base color", color) as color
var/new_ribbon = input(user, "", "Select a ribbon color", color) as color
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
set_greyscale(colors = list(new_base, new_ribbon))
return TRUE
+1 -1
View File
@@ -798,7 +798,7 @@
. += span_notice("Alt-click it to quickly draw the blade.")
/obj/item/storage/belt/sabre/AltClick(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
if(length(contents))
var/obj/item/I = contents[1]
+1 -1
View File
@@ -116,7 +116,7 @@
. += span_notice("Alt-click to [open ? "close":"open"] it.")
/obj/item/storage/lockbox/medal/AltClick(mob/user)
if(user.canUseTopic(src, be_close = TRUE))
if(user.can_perform_action(src))
if(!atom_storage.locked)
open = (open ? FALSE : TRUE)
update_appearance()
+1 -1
View File
@@ -11,7 +11,7 @@
/// Allows carbon to toggle internals via AltClick of the equipped tank.
/obj/item/tank/internals/AltClick(mob/user)
..()
if((loc == user) && user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE, need_hands = TRUE))
if((loc == user) && user.can_perform_action(src, FORBID_TELEKINESIS_REACH|NEED_HANDS))
toggle_internals(user)
/obj/item/tank/internals/examine(mob/user)
+1 -1
View File
@@ -290,7 +290,7 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag)
/obj/AltClick(mob/user)
. = ..()
if(unique_reskin && (!current_skin || infinite_reskin) && user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE))
if(unique_reskin && (!current_skin || infinite_reskin) && user.can_perform_action(src, NEED_DEXTERITY))
reskin_obj(user)
/**
@@ -96,7 +96,7 @@
. = ..()
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(!ishuman(user) || !user.canUseTopic(src, be_close = TRUE))
if(!ishuman(user) || !user.can_perform_action(src))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(has_buckled_mobs())
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -281,7 +281,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0)
if(over_object == usr && Adjacent(usr))
if(!item_chair || has_buckled_mobs() || src.flags_1 & NODECONSTRUCT_1)
return
if(!usr.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!usr.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
usr.visible_message(span_notice("[usr] grabs \the [src.name]."), span_notice("You grab \the [src.name]."))
var/obj/item/C = new item_chair(loc)
@@ -477,7 +477,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
/obj/structure/chair/bronze/AltClick(mob/user)
turns = 0
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!user.can_perform_action(src, NEED_DEXTERITY))
return
if(!(datum_flags & DF_ISPROCESSING))
user.visible_message(span_notice("[user] spins [src] around, and the last vestiges of Ratvarian technology keeps it spinning FOREVER."), \
+1 -1
View File
@@ -138,7 +138,7 @@ LINEN BINS
/obj/item/bedsheet/AltClick(mob/living/user)
// double check the canUseTopic args to make sure it's correct
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY))
return
dir = turn(dir, 180)
@@ -614,7 +614,7 @@
set category = "Object"
set name = "Toggle Open"
if(!usr.canUseTopic(src, be_close = TRUE) || !isturf(loc))
if(!usr.can_perform_action(src) || !isturf(loc))
return
if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
@@ -677,7 +677,7 @@
/obj/structure/closet/attack_hand_secondary(mob/user, modifiers)
. = ..()
if(!user.canUseTopic(src, be_close = TRUE) || !isturf(loc))
if(!user.can_perform_action(src) || !isturf(loc))
return
if(!opened && secure)
@@ -49,7 +49,7 @@
var/t = tgui_input_text(user, "What would you like the label to be?", name, max_length = 53)
if(user.get_active_held_item() != interact_tool)
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
handle_tag("[t ? t : initial(name)]")
return
@@ -315,7 +315,7 @@
open()
/obj/structure/closet/body_bag/environmental/prisoner/attack_hand_secondary(mob/user, modifiers)
if(!user.canUseTopic(src, be_close = TRUE) || !isturf(loc))
if(!user.can_perform_action(src) || !isturf(loc))
return
togglelock(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+2 -2
View File
@@ -516,7 +516,7 @@
if(!payments_acc)
to_chat(usr, span_notice("[src] hasn't been registered yet."))
return TRUE
if(!usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
if(!potential_acc)
to_chat(usr, span_notice("No ID card detected."))
@@ -571,7 +571,7 @@
if(payments_acc != potential_acc.registered_account)
to_chat(usr, span_warning("[src] rejects your new price."))
return
if(!usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
to_chat(usr, span_warning("You need to get closer!"))
return
sale_price = new_price_input
+1 -1
View File
@@ -9,7 +9,7 @@
/obj/structure/sacrificealtar/AltClick(mob/living/user)
..()
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return
if(!has_buckled_mobs())
return
+1 -1
View File
@@ -111,7 +111,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
toggle_cabinet(user)
/obj/structure/extinguisher_cabinet/attack_hand_secondary(mob/living/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return ..()
toggle_cabinet(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+1 -1
View File
@@ -107,7 +107,7 @@
. = ..()
if(.)
return
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
if(obj_flags & IN_USE)
balloon_alert(user, "wait your turn!")
@@ -167,7 +167,7 @@
playsound(src, 'sound/machines/click.ogg', 10, TRUE)
/obj/item/plunger/AltClick(mob/user)
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(src))
return
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", GLOB.plumbing_layers)
+1 -1
View File
@@ -151,7 +151,7 @@ at the cost of risking a vicious bite.**/
switch(altar_result)
if("Change Color")
var/chosen_color = input(user, "", "Choose Color", pants_color) as color|null
if(!isnull(chosen_color) && user.canUseTopic(src, be_close = TRUE))
if(!isnull(chosen_color) && user.can_perform_action(src))
pants_color = chosen_color
if("Create Artefact")
if(!COOLDOWN_FINISHED(src, use_cooldown) || status != ALTAR_INACTIVE)
+11 -11
View File
@@ -31,7 +31,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
var/new_style = tgui_input_list(user, "Select a facial hairstyle", "Grooming", GLOB.facial_hairstyles_list)
if(isnull(new_style))
return TRUE
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE //no tele-grooming
if(HAS_TRAIT(hairdresser, TRAIT_SHAVED))
to_chat(hairdresser, span_notice("If only growing back facial hair were that easy for you..."))
@@ -43,7 +43,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
var/new_style = tgui_input_list(user, "Select a hairstyle", "Grooming", GLOB.hairstyles_list)
if(isnull(new_style))
return TRUE
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE //no tele-grooming
if(HAS_TRAIT(hairdresser, TRAIT_BALD))
to_chat(hairdresser, span_notice("If only growing back hair were that easy for you..."))
@@ -167,7 +167,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
if(isnull(choice))
return TRUE
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
switch(choice)
@@ -175,7 +175,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
var/newname = sanitize_name(tgui_input_text(amazed_human, "Who are we again?", "Name change", amazed_human.name, MAX_NAME_LEN), allow_numbers = TRUE) //It's magic so whatever.
if(!newname)
return TRUE
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
amazed_human.real_name = newname
amazed_human.name = newname
@@ -190,7 +190,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
return TRUE
if(!selectable_races[racechoice])
return TRUE
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
var/datum/species/newrace = selectable_races[racechoice]
@@ -204,7 +204,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
if(MUTCOLORS in amazed_human.dna.species.species_traits)
var/new_mutantcolor = input(user, "Choose your skin color:", "Race change", amazed_human.dna.features["mcolor"]) as color|null
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
if(new_mutantcolor)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
@@ -225,7 +225,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
return TRUE
if(amazed_human.gender == "male")
if(tgui_alert(amazed_human, "Become a Witch?", "Confirmation", list("Yes", "No")) == "Yes")
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
amazed_human.gender = FEMALE
amazed_human.physique = FEMALE
@@ -235,7 +235,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
else
if(tgui_alert(amazed_human, "Become a Warlock?", "Confirmation", list("Yes", "No")) == "Yes")
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
amazed_human.gender = MALE
amazed_human.physique = MALE
@@ -248,13 +248,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
if("hair")
var/hairchoice = tgui_alert(amazed_human, "Hairstyle or hair color?", "Change Hair", list("Style", "Color"))
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
if(hairchoice == "Style") //So you just want to use a mirror then?
return ..()
else
var/new_hair_color = input(amazed_human, "Choose your hair color", "Hair Color",amazed_human.hair_color) as color|null
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
if(new_hair_color)
amazed_human.hair_color = sanitize_hexcolor(new_hair_color)
@@ -268,7 +268,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
if(BODY_ZONE_PRECISE_EYES)
var/new_eye_color = input(amazed_human, "Choose your eye color", "Eye Color", amazed_human.eye_color_left) as color|null
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return TRUE
if(new_eye_color)
amazed_human.eye_color_left = sanitize_hexcolor(new_eye_color)
+2 -2
View File
@@ -90,7 +90,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", name), null)
if (user.get_active_held_item() != P)
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
if (t)
name = text("[]- '[]'", initial(name), t)
@@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/morgue/AltClick(mob/user)
..()
if(!user.canUseTopic(src, !issilicon(user)))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH))
return
beeper = !beeper
to_chat(user, span_notice("You turn the speaker function [beeper ? "on" : "off"]."))
+2 -2
View File
@@ -165,13 +165,13 @@
to_chat(user, span_warning("The rotation is locked!"))
return FALSE
var/new_angle = tgui_input_number(user, "New angle for primary reflection face", "Reflector Angle", rotation_angle, 360)
if(isnull(new_angle) || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(isnull(new_angle) || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return FALSE
set_angle(SIMPLIFY_DEGREES(new_angle))
return TRUE
/obj/structure/reflector/AltClick(mob/user)
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(!user.can_perform_action(src, NEED_DEXTERITY))
return
else if(finished)
rotate(user)
+1 -1
View File
@@ -131,7 +131,7 @@ FLOOR SAFES
if(!ishuman(usr))
return
var/mob/living/carbon/human/user = usr
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
var/canhear = FALSE
@@ -176,7 +176,7 @@
/obj/structure/training_machine/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, floor_okay = TRUE))
if(!user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING))
return
if(has_buckled_mobs())
user_unbuckle_mob(buckled_mobs[1], user)
@@ -43,7 +43,7 @@
var/scramble_response = tgui_alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it?", "Scrambler", list("Yes", "Cancel"))
if(scramble_response != "Yes")
return
if(active || !user.canUseTopic(src, be_close = TRUE))
if(active || !user.can_perform_action(src))
return
toggle_on(user)
update_appearance()
@@ -230,7 +230,7 @@
if(!istype(M))
return ..()
if(!istype(user) || !user.canUseTopic(M, be_close = TRUE))
if(!istype(user) || !user.can_perform_action(M))
return
if(M.stat != DEAD)
+2 -2
View File
@@ -207,7 +207,7 @@
return
var/sniped_amount = painting_metadata.credit_value
var/offer_amount = tgui_input_number(user, "How much do you want to offer?", "Patronage Amount", (painting_metadata.credit_value + 1), account.account_balance, painting_metadata.credit_value)
if(!offer_amount || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!offer_amount || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
if(sniped_amount != painting_metadata.credit_value)
return
@@ -324,7 +324,7 @@
if(painting_metadata.loaded_from_json) // No renaming old paintings
return
var/new_name = tgui_input_text(user, "What do you want to name the painting?", "Title Your Masterpiece")
if(new_name != painting_metadata.title && new_name && user.canUseTopic(src, be_close = TRUE))
if(new_name != painting_metadata.title && new_name && user.can_perform_action(src))
painting_metadata.title = new_name
var/sign_choice = tgui_alert(user, "Do you want to sign it or remain anonymous?", "Sign painting?", list("Yes", "No"))
if(sign_choice != "Yes")
+1 -1
View File
@@ -16,7 +16,7 @@
/obj/item/assembly/control/multitool_act(mob/living/user)
var/change_id = tgui_input_number(user, "Set the door controllers ID", "Door ID", id, 100)
if(!change_id || QDELETED(user) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(!change_id || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
id = change_id
balloon_alert(user, "id changed")
@@ -64,7 +64,7 @@
. = ..()
if(!can_interact(user))
return
if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc))
if(!user.can_perform_action(src, ALLOW_SILICON_REACH) || !isturf(loc))
return
togglelock(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -767,7 +767,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister())
timer_set = min(maximum_timer_set, timer_set + 10)
if("input")
var/user_input = tgui_input_number(usr, "Set time to valve toggle", "Canister Timer", timer_set, maximum_timer_set, minimum_timer_set)
if(isnull(user_input) || QDELETED(usr) || QDELETED(src) || !usr.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE))
if(isnull(user_input) || QDELETED(usr) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
timer_set = user_input
log_admin("[key_name(usr)] has activated a prototype valve timer")
@@ -159,7 +159,7 @@
/obj/machinery/portable_atmospherics/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)) || !can_interact(user))
if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY) || !can_interact(user))
return
if(!holding)
return
+1 -1
View File
@@ -44,7 +44,7 @@
return NONE
/obj/item/toy/cards/cardhand/attack_self(mob/living/user)
if(!isliving(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE))
if(!isliving(user) || !user.can_perform_action(src, NEED_DEXTERITY| FORBID_TELEKINESIS_REACH))
return
var/list/handradial = list()
+1 -1
View File
@@ -111,7 +111,7 @@
* * obj/item/toy/singlecard/card (optional) - The card drawn from the hand
**/
/obj/item/toy/cards/proc/draw(mob/living/user, obj/item/toy/singlecard/card)
if(!isliving(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE))
if(!isliving(user) || !user.can_perform_action(src, NEED_DEXTERITY| FORBID_TELEKINESIS_REACH))
return
if(count_cards() == 0)
+2 -2
View File
@@ -143,7 +143,7 @@
other_players = other_players)
/obj/item/toy/cards/deck/attack_hand(mob/living/user, list/modifiers, flip_card = FALSE)
if(!ishuman(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(!ishuman(user) || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
return
var/obj/item/toy/singlecard/card = draw(user)
@@ -160,7 +160,7 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/item/toy/cards/deck/AltClick(mob/living/user)
if(user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
if(wielded)
shuffle_cards(user)
else
+3 -3
View File
@@ -209,7 +209,7 @@
return
var/cardtext = stripped_input(user, "What do you wish to write on the card?", "Card Writing", "", 50)
if(!cardtext || !user.canUseTopic(src, be_close = TRUE))
if(!cardtext || !user.can_perform_action(src))
return
cardname = cardtext
@@ -230,7 +230,7 @@
attack_self(user)
/obj/item/toy/singlecard/attack_self(mob/living/carbon/human/user)
if(!ishuman(user) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(!ishuman(user) || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
return
Flip()
@@ -238,7 +238,7 @@
user.balloon_alert_to_viewers("flips a card")
/obj/item/toy/singlecard/AltClick(mob/living/carbon/human/user)
if(user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = TRUE, need_hands = !iscyborg(user)))
if(user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
transform = turn(transform, 90)
// use the simple_rotation component to make this turn with Alt+RMB & Alt+LMB at some point in the future - TimT
return ..()
+2 -2
View File
@@ -80,7 +80,7 @@
to_chat(user, span_notice("[src] linked to [C]."))
/obj/item/supplypod_beacon/AltClick(mob/user)
if (!user.canUseTopic(src, !issilicon(user)))
if (!user.can_perform_action(src, ALLOW_SILICON_REACH))
return
if (express_console)
unlink_console()
@@ -93,7 +93,7 @@
var/new_beacon_name = tgui_input_text(user, "What would you like the tag to be?", "Beacon Tag", max_length = MAX_NAME_LEN)
if(isnull(new_beacon_name))
return
if(!user.canUseTopic(src, be_close = TRUE))
if(!user.can_perform_action(src))
return
name += " ([tag])"
+1 -1
View File
@@ -117,7 +117,7 @@
to_chat(user, span_warning("You must be holding \the [src] to continue!"))
return
var/chosen_price = tgui_input_number(user, "Set price", "Price", new_custom_price)
if(!chosen_price || QDELETED(user) || QDELETED(src) || !user.canUseTopic(src, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE) || loc != user)
if(!chosen_price || QDELETED(user) || QDELETED(src) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH) || loc != user)
return
new_custom_price = chosen_price
to_chat(user, span_notice("[src] will now give things a [new_custom_price] cr tag."))
+1 -1
View File
@@ -143,7 +143,7 @@
/obj/item/clothing/head/fedora/det_hat/AltClick(mob/user)
. = ..()
if(loc != user || !user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = TRUE))
if(loc != user || !user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
if(candy_cooldown < world.time)
var/obj/item/food/candy_corn/CC = new /obj/item/food/candy_corn(src)
+1 -1
View File
@@ -25,7 +25,7 @@
/obj/item/clothing/head/soft/AltClick(mob/user)
..()
if(user.canUseTopic(src, be_close = TRUE, no_dexterity = TRUE, no_tk = FALSE, need_hands = !iscyborg(user)))
if(user.can_perform_action(src, NEED_DEXTERITY))
flip(user)

Some files were not shown because too many files have changed in this diff Show More