From 9c92081471ccaf711f6fe35829e4c0fb505b010b Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sat, 6 Jul 2024 01:11:49 -0300 Subject: [PATCH 1/7] push --- .../integrated_electronics/subtypes/logic.dm | 9 +++++++++ .../obj/assemblies/electronic_components.dmi | Bin 23381 -> 23343 bytes 2 files changed, 9 insertions(+) diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index 37bc93e887..cc04f96e80 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -172,6 +172,15 @@ /obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B) return A.data || B.data +/obj/item/integrated_circuit/logic/binary/xor + name = "xor gate" + desc = "This gate will output TRUE if only one of the inputs evaluate to true." + icon_state = "xor" + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/logic/binary/xor/do_compare(datum/integrated_io/A, datum/integrated_io/B) + return (!!A.data + !!B.data) == 1 + /obj/item/integrated_circuit/logic/binary/less_than name = "less than gate" desc = "This will output TRUE if the first input is less than the second input." diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi index 840b5828f306f6b62e604c55a5201212ee08dc37..fe0e26f10f39a7e92b7b2a8b58956fb1878966d0 100644 GIT binary patch literal 23343 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 NhN0=zas#Kh{{q#TpR@n~ literal 23381 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%0A{|FysB<1Z>Ip^J1QG^pCt8a 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 Date: Sun, 11 Aug 2024 14:10:35 -0300 Subject: [PATCH 2/7] 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 From b3e04bd75f5a8dd140a37f5c7bf755a5ee7657a9 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sun, 11 Aug 2024 14:31:27 -0300 Subject: [PATCH 3/7] aux_base ugliness --- .../machinery/computer/camera_advanced.dm | 1 + code/modules/mining/aux_base_camera.dm | 64 ++++++++----------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index af69ec7911..a34a0ed500 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -90,6 +90,7 @@ if(current_user) current_user.unset_machine() QDEL_NULL(eyeobj) + QDEL_LIST(actions) return ..() /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm index 262e776c68..7c2c9d4acc 100644 --- a/code/modules/mining/aux_base_camera.dm +++ b/code/modules/mining/aux_base_camera.dm @@ -41,13 +41,13 @@ circuit = /obj/item/circuitboard/computer/base_construction off_action = new/datum/action/innate/camera_off/base_construction jump_action = null - var/datum/action/innate/aux_base/switch_mode/switch_mode_action = new //Action for switching the RCD's build modes - var/datum/action/innate/aux_base/build/build_action = new //Action for using the RCD - var/datum/action/innate/aux_base/airlock_type/airlock_mode_action = new //Action for setting the airlock type - var/datum/action/innate/aux_base/window_type/window_action = new //Action for setting the window type - var/datum/action/innate/aux_base/place_fan/fan_action = new //Action for spawning fans + var/datum/action/innate/aux_base/switch_mode/switch_mode_action = /datum/action/innate/aux_base/switch_mode //Action for switching the RCD's build modes + var/datum/action/innate/aux_base/build/build_action = /datum/action/innate/aux_base/build //Action for using the RCD + var/datum/action/innate/aux_base/airlock_type/airlock_mode_action = /datum/action/innate/aux_base/airlock_type //Action for setting the airlock type + var/datum/action/innate/aux_base/window_type/window_action = /datum/action/innate/aux_base/window_type //Action for setting the window type + var/datum/action/innate/aux_base/place_fan/fan_action = /datum/action/innate/aux_base/place_fan //Action for spawning fans var/fans_remaining = 0 //Number of fans in stock. - var/datum/action/innate/aux_base/install_turret/turret_action = new //Action for spawning turrets + var/datum/action/innate/aux_base/install_turret/turret_action = /datum/action/innate/aux_base/install_turret //Action for spawning turrets var/turret_stock = 0 //Turrets in stock var/obj/machinery/computer/auxillary_base/found_aux_console //Tracker for the Aux base console, so the eye can always find it. @@ -58,6 +58,9 @@ /obj/machinery/computer/camera_advanced/base_construction/Initialize(mapload) . = ..() + + populate_actions_list() + RCD = new(src) RCD.console = src if(mapload) //Map spawned consoles have a filled RCD and stocked special structures @@ -65,6 +68,20 @@ fans_remaining = 4 turret_stock = 4 +/** + * Fill the construction_actios list with actions + * + * Instantiate each action object that we'll be giving to users of + * this console, and put it in the actions list + */ +/obj/machinery/computer/camera_advanced/base_construction/proc/populate_actions_list() + actions += new switch_mode_action(src) + actions += new build_action(src) + actions += new airlock_mode_action(src) + actions += new window_action(src) + actions += new fan_action(src) + actions += new turret_action(src) + /obj/machinery/computer/camera_advanced/base_construction/CreateEye() var/spawn_spot @@ -94,43 +111,12 @@ return ..() /obj/machinery/computer/camera_advanced/base_construction/GrantActions(mob/living/user) - ..() - - if(switch_mode_action) - switch_mode_action.target = src - switch_mode_action.Grant(user) - actions += switch_mode_action - - if(build_action) - build_action.target = src - build_action.Grant(user) - actions += build_action - - if(airlock_mode_action) - airlock_mode_action.target = src - airlock_mode_action.Grant(user) - actions += airlock_mode_action - - if(window_action) - window_action.target = src - window_action.Grant(user) - actions += window_action - - if(fan_action) - fan_action.target = src - fan_action.Grant(user) - actions += fan_action - - if(turret_action) - turret_action.target = src - turret_action.Grant(user) - actions += turret_action - eyeobj.invisibility = 0 //When the eye is in use, make it visible to players so they know when someone is building. + return ..() /obj/machinery/computer/camera_advanced/base_construction/remove_eye_control(mob/living/user) - ..() eyeobj.invisibility = INVISIBILITY_MAXIMUM //Hide the eye when not in use. + return ..() /datum/action/innate/aux_base //Parent aux base action icon_icon = 'icons/mob/actions/actions_construction.dmi' From 9f53644f38a9a88dfe2df1fa27db51faa6459caa Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sun, 11 Aug 2024 15:06:18 -0300 Subject: [PATCH 4/7] fixes xenobio stuff --- .../research/xenobiology/xenobio_camera.dm | 74 +++++++------------ 1 file changed, 25 insertions(+), 49 deletions(-) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 1660feedca..8f8508c412 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -22,13 +22,13 @@ desc = "A computer used for remotely handling slimes." networks = list("ss13") circuit = /obj/item/circuitboard/computer/xenobiology - var/datum/action/innate/slime_place/slime_place_action - var/datum/action/innate/slime_pick_up/slime_up_action - var/datum/action/innate/feed_slime/feed_slime_action - var/datum/action/innate/monkey_recycle/monkey_recycle_action - var/datum/action/innate/slime_scan/scan_action - var/datum/action/innate/feed_potion/potion_action - var/datum/action/innate/hotkey_help/hotkey_help + var/datum/action/innate/slime_place/slime_place_action = /datum/action/innate/slime_place + var/datum/action/innate/slime_pick_up/slime_up_action = /datum/action/innate/slime_pick_up + var/datum/action/innate/feed_slime/feed_slime_action = /datum/action/innate/feed_slime + var/datum/action/innate/monkey_recycle/monkey_recycle_action = /datum/action/innate/monkey_recycle + var/datum/action/innate/slime_scan/scan_action = /datum/action/innate/slime_scan + var/datum/action/innate/feed_potion/potion_action = /datum/action/innate/feed_potion + var/datum/action/innate/hotkey_help/hotkey_help = /datum/action/innate/hotkey_help var/list/stored_slimes var/obj/item/slimepotion/slime/current_potion @@ -43,16 +43,16 @@ /obj/machinery/computer/camera_advanced/xenobio/Initialize(mapload) . = ..() - slime_place_action = new - slime_up_action = new - feed_slime_action = new - monkey_recycle_action = new - scan_action = new - potion_action = new - hotkey_help = new + + generate_actions() + stored_slimes = list() RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, PROC_REF(on_contents_del)) +/obj/machinery/computer/camera_advanced/xenobio/proc/generate_actions() + actions += new scan_action(src) + actions += new hotkey_help(src) + /obj/machinery/computer/camera_advanced/xenobio/Destroy() stored_slimes = null QDEL_NULL(current_potion) @@ -72,41 +72,6 @@ /obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user) ..() - if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_up_action.target = src - slime_up_action.Grant(user) - actions += slime_up_action - - if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC - slime_place_action.target = src - slime_place_action.Grant(user) - actions += slime_place_action - - if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - feed_slime_action.target = src - feed_slime_action.Grant(user) - actions += feed_slime_action - - if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS - monkey_recycle_action.target = src - monkey_recycle_action.Grant(user) - actions += monkey_recycle_action - - if(scan_action) - scan_action.target = src - scan_action.Grant(user) - actions += scan_action - - if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV - potion_action.target = src - potion_action.Grant(user) - actions += potion_action - - if(hotkey_help) - hotkey_help.target = src - hotkey_help.Grant(user) - actions += hotkey_help - RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, PROC_REF(XenoSlimeClickCtrl)) RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, PROC_REF(XenoSlimeClickAlt)) RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, PROC_REF(XenoSlimeClickShift)) @@ -139,10 +104,21 @@ else upgradetier |= I successfulupgrade = TRUE + if(I == XENOBIO_UPGRADE_SLIMEBASIC) + actions += new slime_up_action(src) + actions += new slime_place_action(src) if(I == XENOBIO_UPGRADE_SLIMEADV) + actions += new potion_action(src) max_slimes = 10 + if(I == XENOBIO_UPGRADE_MONKEYS) + actions += new feed_slime_action(src) + actions += new monkey_recycle_action(src) if(successfulupgrade) to_chat(user, "You have successfully upgraded [src] with [O].") + + for(var/datum/action/actions_removed as anything in actions) + actions_removed.Remove(current_user) + GrantActions(current_user) else to_chat(user, "[src] already has the contents of [O] installed!") return From 86faaee73edda4ad716dc075b2bf09816d21f0c8 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sun, 11 Aug 2024 15:11:17 -0300 Subject: [PATCH 5/7] buh --- code/modules/mining/aux_base_camera.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm index 7c2c9d4acc..0224ff2769 100644 --- a/code/modules/mining/aux_base_camera.dm +++ b/code/modules/mining/aux_base_camera.dm @@ -39,7 +39,7 @@ networks = list("ss13") var/obj/item/construction/rcd/internal/RCD //Internal RCD. The computer passes user commands to this in order to avoid massive copypaste. circuit = /obj/item/circuitboard/computer/base_construction - off_action = new/datum/action/innate/camera_off/base_construction + off_action = /datum/action/innate/camera_off/base_construction jump_action = null var/datum/action/innate/aux_base/switch_mode/switch_mode_action = /datum/action/innate/aux_base/switch_mode //Action for switching the RCD's build modes var/datum/action/innate/aux_base/build/build_action = /datum/action/innate/aux_base/build //Action for using the RCD From d0a14830ee00dbf3f5dff1011add684e7676c24d Mon Sep 17 00:00:00 2001 From: SandPoot Date: Mon, 12 Aug 2024 19:52:51 -0300 Subject: [PATCH 6/7] push --- code/_onclick/hud/action_button.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index b347a5c55a..562f304f24 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -76,6 +76,9 @@ if(old_object) old_object.MouseExited(over_location, over_control, params) + if(QDELETED(over_location)) + last_hovored_ref = null + return last_hovored_ref = WEAKREF(over_object) over_object.MouseEntered(over_location, over_control, params) @@ -113,6 +116,7 @@ our_hud.position_action_relative(src, button) save_position() return + . = ..() our_hud.position_action(src, screen_loc) save_position() From e4ecebe0985234ab55fa71ecb1be9ab3e9830380 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Mon, 12 Aug 2024 19:57:35 -0300 Subject: [PATCH 7/7] typecast it in the arguments ffs --- code/_onclick/hud/action_button.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 562f304f24..f5826579c8 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -59,7 +59,7 @@ // Entered and Exited won't fire while you're dragging something, because you're still "holding" it // Very much byond logic, but I want nice behavior, so we fake it with drag -/atom/movable/screen/movable/action_button/MouseDrag(atom/over_object, src_location, over_location, src_control, over_control, params) +/atom/movable/screen/movable/action_button/MouseDrag(atom/over_object, atom/src_location, atom/over_location, src_control, over_control, params) . = ..() if(!can_use(usr)) return