From 0fd4dba15b423f8a9f3d08a04c19a8acaa3378da Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sun, 11 Aug 2024 14:10:35 -0300 Subject: [PATCH] push --- code/_onclick/hud/action_button.dm | 40 +++-- code/datums/action.dm | 165 +++++++++++------- code/datums/elements/polychromic.dm | 8 +- .../machinery/computer/camera_advanced.dm | 115 ++++++------ code/modules/antagonists/cult/cult.dm | 2 +- code/modules/antagonists/cult/cult_comms.dm | 4 +- code/modules/clothing/chameleon.dm | 16 +- code/modules/surgery/dental_implant.dm | 9 +- 8 files changed, 215 insertions(+), 144 deletions(-) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 5ce1d3130d..b347a5c55a 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -29,25 +29,31 @@ return ..() /atom/movable/screen/movable/action_button/proc/can_use(mob/user) - if (linked_action) + if(isobserver(user)) + var/mob/dead/observer/dead_mob = user + if(dead_mob.observetarget) // Observers can only click on action buttons if they're not observing something + return FALSE + + if(linked_action) if(linked_action.viewers[user.hud_used]) return TRUE return FALSE - else if (isobserver(user)) - var/mob/dead/observer/O = user - return !O.observetarget - else - return TRUE + + return TRUE /atom/movable/screen/movable/action_button/Click(location,control,params) if (!can_use(usr)) return var/list/modifiers = params2list(params) - if(modifiers["shift"]) + if(LAZYACCESS(modifiers, SHIFT_CLICK)) var/datum/hud/our_hud = usr.hud_used our_hud.position_action(src, SCRN_OBJ_DEFAULT) return TRUE + var/mob/clicker = usr + if(!clicker.CheckActionCooldown()) + return + clicker.DelayNextAction(1) linked_action.Trigger() return TRUE @@ -82,7 +88,7 @@ closeToolTip(usr) return ..() -/atom/movable/screen/movable/action_button/MouseDrop(over_object) +/atom/movable/screen/movable/action_button/MouseDrop(atom/over_object, mob/user, src_location, over_location, params) last_hovored_ref = null if(!can_use(usr)) return @@ -107,7 +113,6 @@ our_hud.position_action_relative(src, button) save_position() return - . = ..() our_hud.position_action(src, screen_loc) save_position() @@ -141,6 +146,12 @@ user.client.prefs.action_buttons_screen_locs -= "[name]_[id]" user.client.prefs.queue_save_pref(1 SECONDS, TRUE) +/** + * This is a silly proc used in hud code code to determine what icon and icon state we should be using + * for hud elements (such as action buttons) that don't have their own icon and icon state set. + * + * It returns a list, which is pretty much just a struct of info + */ /datum/hud/proc/get_action_buttons_icons() . = list() .["bg_icon"] = ui_style @@ -153,8 +164,15 @@ var/datum/action/A = X A.UpdateButtons(status_only) -//This is the proc used to update all the action buttons. -/mob/proc/update_action_buttons(reload_screen) +/** + * This proc handles adding all of the mob's actions to their screen + * + * If you just need to update existing buttons, use [/mob/proc/update_mob_action_buttons]! + * + * Arguments: + * * update_flags - reload_screen - bool, if TRUE, this proc will add the button to the screen of the passed mob as well + */ +/mob/proc/update_action_buttons(reload_screen = FALSE) if(!hud_used || !client) return diff --git a/code/datums/action.dm b/code/datums/action.dm index 4c9099fc72..f7093b1ff6 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -5,32 +5,50 @@ #define AB_CHECK_ALIVE 16 /datum/action + /// The name of the action var/name = "Generic Action" + /// The description of what the action does, shown in button tooltips var/desc = null - var/atom/target = null - var/check_flags = 0 - var/required_mobility_flags = MOBILITY_USE - var/processing = FALSE - var/buttontooltipstyle = "" - var/transparent_when_unavailable = TRUE + /// The target the action is attached to. If the target datum is deleted, the action is as well. + /// Set in New() via the proc link_to(). PLEASE set a target if you're making an action + var/datum/target = null /// Where any buttons we create should be by default. Accepts screen_loc and location defines var/default_button_position = SCRN_OBJ_IN_LIST - - var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon - var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon - - var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon - var/button_icon_state = "default" //And this is the state for the action icon + /// This is who currently owns the action, and most often, this is who is using the action if it is triggered + /// This can be the same as "target" but is not ALWAYS the same - this is set and unset with Grant() and Remove() var/mob/owner + /// Flags that will determine of the owner / user of the action can... use the action + var/check_flags = NONE + var/required_mobility_flags = MOBILITY_USE + var/processing = FALSE + /// Whether the button becomes transparent when it can't be used, or just reddened + var/transparent_when_unavailable = TRUE ///List of all mobs that are viewing our action button -> A unique movable for them to view. var/list/viewers = list() + /// The style the button's tooltips appear to be + var/buttontooltipstyle = "" + + /// This is the file for the BACKGROUND underlay icon of the button + var/button_icon = 'icons/mob/actions/backgrounds.dmi' + /// This is the icon state state for the BACKGROUND underlay icon of the button + /// (If set to ACTION_BUTTON_DEFAULT_BACKGROUND, uses the hud's default background) + var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND + + /// This is the file for the icon that appears on the button + var/icon_icon = 'icons/mob/actions.dmi' + /// This is the icon state for the icon that appears on the button + var/button_icon_state = "default" + /datum/action/New(Target) link_to(Target) /datum/action/proc/link_to(Target) target = Target - RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon)) + RegisterSignal(Target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE) + + if(isatom(Target)) + RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon)) /datum/action/Destroy() if(owner) @@ -39,23 +57,8 @@ QDEL_LIST_ASSOC_VAL(viewers) // Qdel the buttons in the viewers list **NOT THE HUDS** return ..() -/datum/action/proc/Grant(mob/M) - if(!M) - Remove(owner) - return - if(owner) - if(owner == M) - return - Remove(owner) - owner = M - RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE) - // Register some signals based on our check_flags - // so that our button icon updates when relevant - if(check_flags & AB_CHECK_CONSCIOUS) - RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal)) - - GiveAction(M) - +/// Signal proc that clears any references based on the owner or target deleting +/// If the owner's deleted, we will simply remove from them, but if the target's deleted, we will self-delete /datum/action/proc/clear_ref(datum/ref) SIGNAL_HANDLER if(ref == owner) @@ -63,23 +66,51 @@ if(ref == target) qdel(src) -/datum/action/proc/Remove(mob/M) +/datum/action/proc/Grant(mob/grant_to) + if(isnull(grant_to)) + Remove(owner) + return + if(grant_to == owner) + return // We already have it + var/mob/previous_owner = owner + owner = grant_to + if(!isnull(previous_owner)) + Remove(previous_owner) + RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE) + + // Register some signals based on our check_flags + // so that our button icon updates when relevant + if(check_flags & AB_CHECK_CONSCIOUS) + RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal)) + + GiveAction(grant_to) + +/datum/action/proc/Remove(mob/remove_from) + SHOULD_CALL_PARENT(TRUE) + for(var/datum/hud/hud in viewers) if(!hud.mymob) continue HideFrom(hud.mymob) - LAZYREMOVE(M.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared + LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared viewers = list() - if(owner) - UnregisterSignal(owner, list( - COMSIG_PARENT_QDELETING, - COMSIG_MOB_STATCHANGE - )) - if(target == owner) - RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref)) + if(isnull(owner)) + return + UnregisterSignal(owner, COMSIG_PARENT_QDELETING) + + // Clean up our check_flag signals + UnregisterSignal(owner, list( + COMSIG_MOB_STATCHANGE + )) + + if(target == owner) + RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref)) + if(owner == remove_from) owner = null +/// Actually triggers the effects of the action. +/// Called when the on-screen button is clicked, for example. /datum/action/proc/Trigger() if(!IsAvailable()) return FALSE @@ -90,6 +121,10 @@ /datum/action/proc/Process() return +/** + * Whether our action is currently available to use or not + * * silent - If false this is being called to check if we have any messages to show to the owner + */ /datum/action/proc/IsAvailable(silent = FALSE) if(!owner) return FALSE @@ -104,9 +139,13 @@ return FALSE if(check_flags & AB_CHECK_LYING) if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_STAND)) + if (!silent) + owner.balloon_alert(owner, "must stand up!") return FALSE if(check_flags & AB_CHECK_CONSCIOUS) if(owner.stat) + if (!silent) + owner.balloon_alert(owner, "unconscious!") return FALSE if(check_flags & AB_CHECK_ALIVE) if(owner.stat == DEAD) @@ -166,7 +205,8 @@ SIGNAL_HANDLER UpdateButtons(force = TRUE) -//Give our action button to the player +/// Gives our action to the passed viewer. +/// Puts our action in their actions list and shows them the button. /datum/action/proc/GiveAction(mob/viewer) var/datum/hud/our_hud = viewer.hud_used if(viewers[our_hud]) // Already have a copy of us? go away @@ -175,7 +215,7 @@ LAZYOR(viewer.actions, src) // Move this in ShowTo(viewer) -//Adds our action button to the screen of a player +/// Adds our action button to the screen of the passed viewer. /datum/action/proc/ShowTo(mob/viewer) var/datum/hud/our_hud = viewer.hud_used if(!our_hud || viewers[our_hud]) // There's no point in this if you have no hud in the first place @@ -192,7 +232,7 @@ button.load_position(viewer) viewer.update_action_buttons() -//Removes our action button from the screen of a player +/// Removes our action from the passed viewer. /datum/action/proc/HideFrom(mob/viewer) var/datum/hud/our_hud = viewer.hud_used var/atom/movable/screen/movable/action_button/button = viewers[our_hud] @@ -445,7 +485,8 @@ /datum/action/item_action/toggle/New(Target) ..() - name = "Toggle [target.name]" + var/obj/item/item_target = target + name = "Toggle [item_target.name]" /datum/action/item_action/halt name = "HALT!" @@ -473,7 +514,9 @@ /datum/action/item_action/adjust/New(Target) ..() - name = "Adjust [target.name]" + var/obj/item/item_target = target + name = "Adjust [item_target.name]" + /datum/action/item_action/switch_hud name = "Switch HUD" @@ -548,21 +591,31 @@ return ..() /datum/action/item_action/organ_action + name = "Organ Action" check_flags = AB_CHECK_CONSCIOUS /datum/action/item_action/organ_action/IsAvailable(silent = FALSE) - var/obj/item/organ/I = target - if(!I.owner) + var/obj/item/organ/attached_organ = target + if(!attached_organ.owner) return FALSE return ..() +/datum/action/item_action/organ_action/toggle + name = "Toggle Organ" + /datum/action/item_action/organ_action/toggle/New(Target) ..() - name = "Toggle [target.name]" + var/obj/item/organ/organ_target = target + name = "Toggle [organ_target.name]" + +/datum/action/item_action/organ_action/use + name = "Use Organ" /datum/action/item_action/organ_action/use/New(Target) ..() - name = "Use [target.name]" + var/obj/item/organ/organ_target = target + name = "Use [organ_target.name]" + /datum/action/item_action/cult_dagger name = "Draw Blood Rune" @@ -956,20 +1009,8 @@ /datum/action/item_action/storage_gather_mode name = "Switch gathering mode" desc = "Switches the gathering mode of a storage object." - icon_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "storage_gather_switch" - -/datum/action/item_action/storage_gather_mode/ApplyIcon(atom/movable/screen/movable/action_button/current_button) - . = ..() - var/old_layer = target.layer - var/old_plane = target.plane - target.layer = FLOAT_LAYER //AAAH - target.plane = FLOAT_PLANE //^ what that guy said - current_button.cut_overlays() - current_button.add_overlay(target) - target.layer = old_layer - target.plane = old_plane - current_button.appearance_cache = target.appearance + button_icon = 'icons/mob/actions/actions_items.dmi' + background_icon_state = "storage_gather_switch" /proc/get_action_of_type(mob/M, action_type) if(!M.actions || !ispath(action_type, /datum/action)) diff --git a/code/datums/elements/polychromic.dm b/code/datums/elements/polychromic.dm index 79e186ffe9..bc6a6dd1da 100644 --- a/code/datums/elements/polychromic.dm +++ b/code/datums/elements/polychromic.dm @@ -204,7 +204,9 @@ check_flags = NONE /datum/action/item_action/polychromic/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force) - var/matrix/save_matrix = target.transform - target.transform = matrix(0.8, 0, 0, 0, 0.8, 0) + var/atom/polychromic_thing = target + + var/matrix/save_matrix = polychromic_thing.transform + polychromic_thing.transform = matrix(0.8, 0, 0, 0, 0.8, 0) . = ..() - target.transform = save_matrix + polychromic_thing.transform = save_matrix diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 95c4a089f3..af69ec7911 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -3,18 +3,23 @@ desc = "Used to access the various cameras on the station." icon_screen = "cameras" icon_keyboard = "security_key" + light_color = LIGHT_COLOR_RED + var/list/z_lock = list() // Lock use to these z levels var/lock_override = NONE var/mob/camera/aiEye/remote/eyeobj var/mob/living/current_user = null var/list/networks = list("ss13") - var/datum/action/innate/camera_off/off_action = new - var/datum/action/innate/camera_jump/jump_action = new - var/list/actions = list() - /// Should we suppress the user's view? - var/should_supress_view_changes = TRUE + /// Typepath of the action button we use as "off" + /// It's a typepath so subtypes can give it fun new names + var/datum/action/innate/camera_off/off_action = /datum/action/innate/camera_off + /// Typepath for jumping + var/datum/action/innate/camera_jump/jump_action = /datum/action/innate/camera_jump - light_color = LIGHT_COLOR_RED + /// List of all actions to give to a user when they're well, granted actions + var/list/actions = list() + ///Should we supress any view changes? + var/should_supress_view_changes = TRUE /obj/machinery/computer/camera_advanced/Initialize(mapload) . = ..() @@ -31,6 +36,11 @@ if(lock_override & CAMERA_LOCK_REEBE) z_lock |= SSmapping.levels_by_trait(ZTRAIT_REEBE) + if(off_action) + actions += new off_action(src) + if(jump_action) + actions += new jump_action(src) + /obj/machinery/computer/camera_advanced/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) for(var/i in networks) networks -= i @@ -47,40 +57,30 @@ eyeobj.origin = src /obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user) - if(off_action) - off_action.target = user - off_action.Grant(user) - actions += off_action - - if(jump_action) - jump_action.target = user - jump_action.Grant(user) - actions += jump_action + for(var/datum/action/to_grant as anything in actions) + to_grant.Grant(user) /obj/machinery/proc/remove_eye_control(mob/living/user) CRASH("[type] does not implement ai eye handling") /obj/machinery/computer/camera_advanced/remove_eye_control(mob/living/user) - if(!user) + if(isnull(user?.client)) return - for(var/V in actions) - var/datum/action/A = V - A.Remove(user) - actions.Cut() - for(var/V in eyeobj.visibleCameraChunks) - var/datum/camerachunk/C = V - C.remove(eyeobj) - if(user.client) - user.reset_perspective(null) - if(eyeobj.visible_icon && user.client) - user.client.images -= eyeobj.user_image + + for(var/datum/action/actions_removed as anything in actions) + actions_removed.Remove(user) + for(var/datum/camerachunk/camerachunks_gone as anything in eyeobj.visibleCameraChunks) + camerachunks_gone.remove(eyeobj) + + user.reset_perspective(null) + if(eyeobj.visible_icon) + user.client.images -= eyeobj.user_image + user.client.view_size.unsupress() + eyeobj.eye_user = null user.remote_control = null - current_user = null - user.unset_machine() - user.client.view_size.unsupress() - playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) + playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE) /obj/machinery/computer/camera_advanced/check_eye(mob/user) if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && hasSiliconAccessInArea(user)) || user.eye_blind || user.incapacitated() ) @@ -89,9 +89,7 @@ /obj/machinery/computer/camera_advanced/Destroy() if(current_user) current_user.unset_machine() - if(eyeobj) - qdel(eyeobj) - QDEL_LIST(actions) + QDEL_NULL(eyeobj) return ..() /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) @@ -153,6 +151,8 @@ return //AIs would need to disable their own camera procs to use the console safely. Bugs happen otherwise. /obj/machinery/computer/camera_advanced/proc/give_eye_control(mob/user) + if(isnull(user?.client)) + return GrantActions(user) current_user = user eyeobj.eye_user = user @@ -193,16 +193,19 @@ return eye_user.client return null -/mob/camera/aiEye/remote/setLoc(T) +/mob/camera/aiEye/remote/setLoc(destination) if(eye_user) - T = get_turf(T) - if (T) - forceMove(T) + destination = get_turf(destination) + if (destination) + abstract_move(destination) else moveToNullspace() + update_ai_detect_hud() + if(use_static != USE_STATIC_NONE) GLOB.cameranet.visibility(src, GetViewerClient(), null, use_static) + if(visible_icon) if(eye_user.client) eye_user.client.images -= user_image @@ -233,12 +236,11 @@ button_icon_state = "camera_off" /datum/action/innate/camera_off/Activate() - if(!target || !isliving(target)) + if(!owner || !isliving(owner)) return - var/mob/living/C = target - var/mob/camera/aiEye/remote/remote_eye = C.remote_control + var/mob/camera/aiEye/remote/remote_eye = owner.remote_control var/obj/machinery/computer/camera_advanced/console = remote_eye.origin - console.remove_eye_control(target) + console.remove_eye_control(owner) /datum/action/innate/camera_jump name = "Jump To Camera" @@ -246,16 +248,15 @@ button_icon_state = "camera_jump" /datum/action/innate/camera_jump/Activate() - if(!target || !isliving(target)) + if(!owner || !isliving(owner)) return - var/mob/living/C = target - var/mob/camera/aiEye/remote/remote_eye = C.remote_control + var/mob/camera/aiEye/remote/remote_eye = owner.remote_control var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin var/list/L = list() - for (var/obj/machinery/camera/cam in GLOB.cameranet.cameras) - if(origin.z_lock.len && !(cam.z in origin.z_lock)) + for (var/obj/machinery/camera/cam as anything in GLOB.cameranet.cameras) + if(length(origin.z_lock) && !(cam.z in origin.z_lock)) continue L.Add(cam) @@ -265,17 +266,23 @@ for (var/obj/machinery/camera/netcam in L) var/list/tempnetwork = netcam.network & origin.networks - if (tempnetwork.len) + if (length(tempnetwork)) + if(!netcam.c_tag) + continue T["[netcam.c_tag][netcam.can_use() ? null : " (Deactivated)"]"] = netcam - playsound(origin, 'sound/machines/terminal_prompt.ogg', 25, 0) + playsound(origin, 'sound/machines/terminal_prompt.ogg', 25, FALSE) var/camera = input("Choose which camera you want to view", "Cameras") as null|anything in T + if(isnull(camera)) + return + if(isnull(T[camera])) + return var/obj/machinery/camera/final = T[camera] - playsound(src, "terminal_type", 25, 0) + playsound(src, "terminal_type", 25, FALSE) if(final) - playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) + playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE) remote_eye.setLoc(get_turf(final)) - C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static) - C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! + owner.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static) + owner.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! else - playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) + playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, FALSE) diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index f5761f6508..63b82f26ce 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -254,7 +254,7 @@ /datum/team/cult name = "Cult" - var/blood_target + var/atom/blood_target var/image/blood_target_image var/blood_target_reset_timer diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index b81422157c..cd348485f1 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -363,8 +363,8 @@ addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, update_action_buttons_icon)), base_cooldown) C.cult_team.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) C.cult_team.blood_target_image.appearance_flags = RESET_COLOR - C.cult_team.blood_target_image.pixel_x = -target.pixel_x - C.cult_team.blood_target_image.pixel_y = -target.pixel_y + C.cult_team.blood_target_image.pixel_x = -C.cult_team.blood_target.pixel_x + C.cult_team.blood_target_image.pixel_y = -C.cult_team.blood_target.pixel_y SEND_SOUND(owner, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) owner.client.images += C.cult_team.blood_target_image for(var/datum/mind/B in SSticker.mode.cult) diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index f26da5db38..b3030b67ec 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -212,13 +212,15 @@ UpdateButtons() /datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item) - target.name = initial(picked_item.name) - target.desc = initial(picked_item.desc) - target.icon_state = initial(picked_item.icon_state) - if(isitem(target)) - var/obj/item/I = target + var/obj/item/chameleon_item = target + + chameleon_item.name = initial(picked_item.name) + chameleon_item.desc = initial(picked_item.desc) + chameleon_item.icon_state = initial(picked_item.icon_state) + if(isitem(chameleon_item)) + var/obj/item/I = chameleon_item I.item_state = initial(picked_item.item_state) - var/obj/item/clothing/CL = target + var/obj/item/clothing/CL = chameleon_item var/obj/item/clothing/PCL = new picked_item if(istype(CL) && istype(PCL)) CL.flags_cover = PCL.flags_cover @@ -226,7 +228,7 @@ CL.mutantrace_variation = PCL.mutantrace_variation CL.mob_overlay_icon = PCL.mob_overlay_icon qdel(PCL) - target.icon = initial(picked_item.icon) + chameleon_item.icon = initial(picked_item.icon) /datum/action/item_action/chameleon/change/pda/update_item(obj/item/pda/picked_item) if(!istype(target, /obj/item/pda)) diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index e8d0564c62..b5461da25a 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -33,10 +33,11 @@ /datum/action/item_action/hands_free/activate_pill/Trigger() if(!..()) return FALSE - to_chat(owner, "You grit your teeth and burst the implanted [target.name]!") + var/obj/item/item_target = target + to_chat(owner, span_notice("You grit your teeth and burst the implanted [item_target.name]!")) log_combat(owner, null, "swallowed an implanted pill", target) - if(target.reagents.total_volume) - target.reagents.reaction(owner, INGEST) - target.reagents.trans_to(owner, target.reagents.total_volume, log = "dental pill swallow") + if(item_target.reagents.total_volume) + item_target.reagents.reaction(owner, INGEST) + item_target.reagents.trans_to(owner, item_target.reagents.total_volume, log = "dental pill swallow") qdel(target) return TRUE