From e67e3e3a5ad825ebba69e5084e6b1b9378e1d479 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 09:24:46 -0700 Subject: [PATCH 01/33] start --- citadel.dme | 4 ++- .../signals/signals_atom/context_system.dm | 9 +++++++ .../dcs/signals/signals_atom/tool_system.dm | 10 +++++++ .../dcs/signals/signals_tool_system.dm | 2 -- code/game/click/context.dm | 26 +++++++++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 code/__DEFINES/dcs/signals/signals_atom/context_system.dm create mode 100644 code/__DEFINES/dcs/signals/signals_atom/tool_system.dm delete mode 100644 code/__DEFINES/dcs/signals/signals_tool_system.dm create mode 100644 code/game/click/context.dm diff --git a/citadel.dme b/citadel.dme index a08278663641..537023144572 100644 --- a/citadel.dme +++ b/citadel.dme @@ -161,12 +161,12 @@ #include "code\__DEFINES\dcs\signals\signals_global.dm" #include "code\__DEFINES\dcs\signals\signals_object.dm" #include "code\__DEFINES\dcs\signals\signals_storage.dm" -#include "code\__DEFINES\dcs\signals\signals_tool_system.dm" #include "code\__DEFINES\dcs\signals\signals_turf.dm" #include "code\__DEFINES\dcs\signals\datums\signals_beam.dm" #include "code\__DEFINES\dcs\signals\datums\signals_perspective.dm" #include "code\__DEFINES\dcs\signals\elements\conflict.dm" #include "code\__DEFINES\dcs\signals\items\signals_inducer.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\context_system.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_appearance.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_attack.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_buckling.dm" @@ -180,6 +180,7 @@ #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_throwing.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_visuals.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_x_act.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\tool_system.dm" #include "code\__DEFINES\dcs\signals\signals_item\signals_item_economy.dm" #include "code\__DEFINES\dcs\signals\signals_item\signals_item_inventory.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_appearance.dm" @@ -936,6 +937,7 @@ #include "code\game\click\adjacency_legacy.dm" #include "code\game\click\ai.dm" #include "code\game\click\click.dm" +#include "code\game\click\context.dm" #include "code\game\click\cyborg.dm" #include "code\game\click\drag_drop.dm" #include "code\game\click\item_attack.dm" diff --git a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm new file mode 100644 index 000000000000..2aa623ad86e9 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm @@ -0,0 +1,9 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + +/// from base of /atom/proc/context_query: (list/options, mob/user, distance) +/// options list is the same format as /atom/proc/context_query, insert directly to it. +#define COMSIG_ATOM_CONTEXT_QUERY "atom_context_query" +/// from base of /atom/proc/context_act: (key, mob/user) +#define COMSIG_ATOM_CONTEXT_ACT "atom_context_act" + #define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0) diff --git a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm new file mode 100644 index 000000000000..5c337e706b4f --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm @@ -0,0 +1,10 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + +/// from base of _tool_act: (I, user, function, flags, hint) where I = item, user = user, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system +/// return CLICKCHAIN_COMPONENT_SIGNAL_HANDLED to abort normal tool_act handling. +#define COMSIG_ATOM_TOOL_ACT "tool_act" +/// from base of dynamic_tool_functions: (functions, I, user) where I = item, user = user +#define COMSIG_ATOM_TOOL_QUERY "tool_query" + +#warn a way to return iamges diff --git a/code/__DEFINES/dcs/signals/signals_tool_system.dm b/code/__DEFINES/dcs/signals/signals_tool_system.dm deleted file mode 100644 index 24163dae2d1b..000000000000 --- a/code/__DEFINES/dcs/signals/signals_tool_system.dm +++ /dev/null @@ -1,2 +0,0 @@ -/// from base of _tool_act: (I, user, function, flags, hint) where I = item, user = user, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system -#define COMSIG_ATOM_TOOL_ACT "tool_act" diff --git a/code/game/click/context.dm b/code/game/click/context.dm new file mode 100644 index 000000000000..6323efe45bb9 --- /dev/null +++ b/code/game/click/context.dm @@ -0,0 +1,26 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + +/** + * get context options + * + * key is a text string + * value are tuples of (name, image) + * + * @return list(key = list(name, image)) + */ +/atom/proc/context_query(mob/user, distance) + . = list() + SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., user, distance) + +/** + * act on a context option + * + * @return TRUE / FALSE; TRUE if handled. + */ +/atom/proc/context_act(mob/user, key) + if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, user) & RAISE_ATOM_CONTEXT_ACT_HANDLED) + return TRUE + return FALSE + +#warn hook all From d8948837c7d2b0703ba87c2ed9177d8f01f986ea Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 09:25:02 -0700 Subject: [PATCH 02/33] tool port --- code/modules/tools/_tool_system.dm | 8 +++++++- code/modules/tools/items.dm | 3 +++ code/modules/tools/wrappers.dm | 3 +++ code/modules/tools/z_legacy.dm | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index b9e2030c2d5d..6e36f6a71b08 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -1,3 +1,6 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + /** * ? Atom Tool API * @@ -68,6 +71,8 @@ return _dynamic_tool_act(provided_item, user, function, TOOL_OP_AUTOPILOT | TOOL_OP_REAL, hint) // used in clickchain var/list/possibilities = dynamic_tool_functions(provided_item, user) + #warn possibilities is fundamentally used incorrectly later, we might + #warn have to refactor this to not use dynamic_tool_image at all. if(!length(possibilities) || (provided_item.tool_locked == TOOL_LOCKING_STATIC)) // no dynamic tool functionality, or dynamic functionality disabled, route normally. function = provided_item.tool_behaviour() @@ -156,7 +161,8 @@ /atom/proc/_tool_act(obj/item/I, mob/user, function, flags, hint) PRIVATE_PROC(TRUE) SHOULD_NOT_OVERRIDE(TRUE) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, user, function, flags, hint) + if((. = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, user, function, flags, hint)) & CLICKCHAIN_COMPONENT_SIGNAL_HANDLED) + return . & ~(CLICKCHAIN_COMPONENT_SIGNAL_HANDLED) return tool_act(I, user, function, flags, hint) /** diff --git a/code/modules/tools/items.dm b/code/modules/tools/items.dm index f35c57adfd94..3163f8aea321 100644 --- a/code/modules/tools/items.dm +++ b/code/modules/tools/items.dm @@ -1,3 +1,6 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + /** * item tool API: allows items to be one or more types of generic tool-functionalities * with arbitrary tool speeds and qualities, while allowing the item to hook usages. diff --git a/code/modules/tools/wrappers.dm b/code/modules/tools/wrappers.dm index 233664c9b3d8..ab785bd05248 100644 --- a/code/modules/tools/wrappers.dm +++ b/code/modules/tools/wrappers.dm @@ -1,3 +1,6 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + //! ON GOD, READ tool_system.dm's use_tool_standard to learn how to use these! /** diff --git a/code/modules/tools/z_legacy.dm b/code/modules/tools/z_legacy.dm index 4f67004a445d..37ef1820cb2d 100644 --- a/code/modules/tools/z_legacy.dm +++ b/code/modules/tools/z_legacy.dm @@ -1,3 +1,6 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2023 Citadel Station developers. *// + //! these wrappers are used for things that still check tools on attackby() //! new usages are prohibited. From b35c3496334ed7560519e234308ebbc2161293fd Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 09:25:52 -0700 Subject: [PATCH 03/33] object system --- citadel.dme | 2 + code/game/objects/objs.dm | 34 +++++++++++- code/game/objects/systems/_system.dm | 16 ++++++ code/game/objects/systems/cell_slot.dm | 77 ++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 code/game/objects/systems/_system.dm create mode 100644 code/game/objects/systems/cell_slot.dm diff --git a/citadel.dme b/citadel.dme index 537023144572..df648da87cb4 100644 --- a/citadel.dme +++ b/citadel.dme @@ -1870,6 +1870,8 @@ #include "code\game\objects\structures\stool_bed_chair_nest\chairs_vr.dm" #include "code\game\objects\structures\stool_bed_chair_nest\stools.dm" #include "code\game\objects\structures\stool_bed_chair_nest\wheelchair.dm" +#include "code\game\objects\systems\_system.dm" +#include "code\game\objects\systems\cell_slot.dm" #include "code\game\rendering\client.dm" #include "code\game\rendering\mob.dm" #include "code\game\rendering\screen.dm" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 954db393c9b8..3357ed006dc6 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -59,6 +59,11 @@ /// volume when breaking out using resist process var/breakout_volume = 100 + //? Systems - naming convention is 'object_[system]' + /// cell slot system + var/datum/object_system/cell_slot/object_cell_slot + #warn hook above + //? misc / legacy /// Set when a player renames a renamable object. var/renamed_by_player = FALSE @@ -105,6 +110,7 @@ unregister_dangerous_to_step() SStgui.close_uis(src) SSnanoui.close_uis(src) + QDEL_NULL(object_cell_slot) return ..() /obj/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) @@ -238,6 +244,24 @@ add_fingerprint(user) ..() +//? Attacks + +#warn cell attackby/attack hand + +//? Cells / Inducers + +/** + * get cell slot + */ +/obj/get_cell() + . = ..() + if(.) + return + if(object_cell_slot?.primary && !isnull(object_cell_slot.cell)) + return object_cell_slot.cell + +#warn inducer + //? Climbing /obj/MouseDroppedOn(atom/dropping, mob/user, proximity, params) @@ -368,7 +392,11 @@ H.update_health() */ -//* Hiding / Underfloor +//? Context + +#warn cell context + +//? Hiding / Underfloor /obj/proc/is_hidden_underfloor() return FALSE @@ -472,3 +500,7 @@ var/shake_dir = pick(-1, 1) animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + +//? Tool System + +#warn hook cell slot diff --git a/code/game/objects/systems/_system.dm b/code/game/objects/systems/_system.dm new file mode 100644 index 000000000000..c47ad87d80ce --- /dev/null +++ b/code/game/objects/systems/_system.dm @@ -0,0 +1,16 @@ +/** + * just the base type of object systems + * + * components are just terrible API, inefficient, and obnoxious sometimes + * /obj systems are the replacement for stuff like storage, cell slots, etc + * + * they are singletons on /obj level. + */ +/datum/object_system + abstract_type = /datum/object_system + + /// owning object + var/obj/parent + +/datum/object_system/New(obj/parent) + src.parent = parent diff --git a/code/game/objects/systems/cell_slot.dm b/code/game/objects/systems/cell_slot.dm new file mode 100644 index 000000000000..cea52de2290c --- /dev/null +++ b/code/game/objects/systems/cell_slot.dm @@ -0,0 +1,77 @@ +/** + * cell slot + */ +/datum/object_system/cell_slot + /// held cell + var/obj/item/cell/cell + /// reserved - cell type accepted enum, for when we do large/medium/small/etc cells later. + var/cell_type + /// considered primary? if so, we get returned on get_cell() + var/primary = TRUE + #warn hook below + /// allow inducer? + var/receive_inducer = FALSE + /// allow EMPs to hit? + var/receive_emp = FALSE + /// allow quick removal by clicking with hand? + var/remove_yank_offhand = FALSE + /// allow context menu removal? + var/remove_yank_context = FALSE + /// no-tool time for removal, if any + var/remove_yank_time = 0 + /// tool behavior for removal, if any + var/remove_tool_behavior = null + /// tool time for removal, if any + var/remove_tool_time = 0 + #warn hook above + /// allow explosions to hit cell? + // todo: currently unused + var/recieve_explosion = FALSE + /// legacy + // todo: kill this + var/legacy_use_device_cells = FALSE + +/datum/object_system/cell_slot/proc/accepts_cell(obj/item/cell/cell) + return legacy_use_device_cells? istype(cell, /obj/item/cell/device) : TRUE + +/datum/object_system/cell_slot/proc/remove_cell(atom/new_loc) + if(isnull(cell)) + return + . = cell + cell = null + if(cell.loc != new_loc) + cell.forceMove(new_loc) + parent.object_cell_slot_removed(., src) + +/datum/object_system/cell_slot/proc/insert_cell(obj/item/cell/cell) + if(!isnull(cell)) + . = remove_cell(parent.drop_location()) + src.cell = cell + if(cell.loc != parent) + cell.forceMove(parent) + parent.object_cell_slot_inserted(cell, src) + +//? Hooks + +/** + * hook called on cell slot removal + */ +/obj/proc/object_cell_slot_removed(obj/item/cell/cell, datum/object_system/cell_slot/slot) + return + +/** + * hook called on cell slot insertion + */ +/obj/proc/object_cell_slot_inserted(obj/item/cell/cell, datum/object_system/cell_slot/slot) + return + +//? Lazy wrappers for init + +/obj/proc/init_cell_slot_easy_tool(offhand_removal = TRUE) + ASSERT(isnull(object_cell_slot)) + object_cell_slot = new(src) + if(offhand_removal) + object_cell_slot.remove_yank_offhand = TRUE + object_cell_slot.remove_yank_context = TRUE + object_cell_slot.remove_yank_time = 0 + object_cell_slot.legacy_use_device_cells = TRUE From c491137c0545e43fef89ff84dcc49bb7f8831134 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 09:37:39 -0700 Subject: [PATCH 04/33] integrate with inducer --- code/game/objects/items/inducer.dm | 61 ++++++++------------------ code/game/objects/objs.dm | 8 ++-- code/game/objects/systems/cell_slot.dm | 43 +++++++++++++----- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index d807d6a8631c..2399937a1fbb 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -18,8 +18,6 @@ var/transfer_rate = 1000 /// type of cell to spawn var/cell_type = /obj/item/cell/high - /// our cell - var/obj/item/cell/cell /// panel open? var/opened = FALSE /// currently inducing? @@ -35,18 +33,11 @@ /obj/item/inducer/Initialize(mapload) . = ..() - if(!cell && cell_type) - cell = new cell_type + var/datum/object_system/cell_slot/cell_slot = init_cell_slot(cell_type) + cell_slot.receive_emp = TRUE + cell_slot.receive_inducer = TRUE update_appearance() -/obj/item/inducer/get_cell() - return cell - -/obj/item/inducer/emp_act(severity) - . = ..() - if(cell) - cell.emp_act(severity) - /obj/item/inducer/afterattack(atom/target, mob/user, clickchain_flags, list/params) if(user.a_intent == INTENT_HARM) return ..() @@ -59,16 +50,15 @@ to_chat(user, "You don't have the dexterity to use [src]!") return TRUE - if(!cell) + if(!obj_cell_slot.cell) to_chat(user, "[src] doesn't have a power cell installed!") return TRUE - if(!cell.charge) + if(!obj_cell_slot.cell.charge) to_chat(user, "[src]'s battery is dead!") return TRUE return FALSE - /obj/item/inducer/attackby(obj/item/W, mob/user) if(W.is_screwdriver()) playsound(src, W.tool_sound, 50, 1) @@ -82,19 +72,6 @@ opened = FALSE update_icon() return - if(istype(W, /obj/item/cell)) - if(opened) - if(!cell) - if(!user.attempt_insert_item_for_installation(W, src)) - return - to_chat(user, "You insert [W] into [src].") - cell = W - update_icon() - return - else - to_chat(user, "[src] already has \a [cell] installed!") - return - if(cantbeused(user)) return @@ -142,8 +119,8 @@ var/datum/current = targets[1] targets.Cut(1, 2) - while(!QDELETED(A) && do_after(user, 2 SECONDS, A, DO_AFTER_IGNORE_MOVEMENT, max_distance = recharge_dist) && !QDELETED(cell)) - var/amount = min(cell.charge, transfer_rate * 2) // transfer rate is per second, we do this every 2 seconds + while(!QDELETED(A) && do_after(user, 2 SECONDS, A, DO_AFTER_IGNORE_MOVEMENT, max_distance = recharge_dist) && !QDELETED(obj_cell_slot.cell)) + var/amount = min(obj_cell_slot.cell.charge, transfer_rate * 2) // transfer rate is per second, we do this every 2 seconds var/charged = current.inducer_act(src, amount, inducer_flags) spark_system.start() if(charged == INDUCER_ACT_CONTINUE) @@ -152,7 +129,7 @@ break if(charged <= 0) break - cell.use(charged) + obj_cell_slot.cell.use(charged) used += charged qdel(spark_system) @@ -161,20 +138,20 @@ inducing = FALSE user.visible_message(SPAN_NOTICE("[user] recharged [A]."), SPAN_NOTICE("Rechraged [A] with [used] units of power.")) -/obj/item/inducer/attack_self(mob/user) +/obj/item/inducer/object_cell_slot_removed(obj/item/cell/cell, datum/object_system/cell_slot/slot) . = ..() - if(.) - return - if(opened && cell) - user.visible_message("[user] removes [cell] from [src]!", "You remove [cell].") - cell.update_icon() - user.put_in_hands_or_drop(cell) - cell = null - update_icon() + update_icon() + +/obj/item/inducer/object_cell_slot_inserted(obj/item/cell/cell, datum/object_system/cell_slot/slot) + . = ..() + update_icon() + +/obj/item/inducer/object_cell_slot_mutable(mob/user, datum/object_system/cell_slot/slot) + return opened && ..() /obj/item/inducer/examine(mob/living/M) . = ..() - if(cell) + if(!isnull(obj_cell_slot.cell)) . += "
Its display shows: [round(cell.charge)] / [cell.maxcharge]." else . += "
Its display is dark." @@ -185,7 +162,7 @@ ..() cut_overlays() if(opened) - if(!cell) + if(!isnull(obj_cell_slot.cell)) add_overlay("inducer-nobat") else add_overlay("inducer-bat") diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3357ed006dc6..a23735be1639 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -61,7 +61,7 @@ //? Systems - naming convention is 'object_[system]' /// cell slot system - var/datum/object_system/cell_slot/object_cell_slot + var/datum/object_system/cell_slot/obj_cell_slot #warn hook above //? misc / legacy @@ -110,7 +110,7 @@ unregister_dangerous_to_step() SStgui.close_uis(src) SSnanoui.close_uis(src) - QDEL_NULL(object_cell_slot) + QDEL_NULL(obj_cell_slot) return ..() /obj/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) @@ -257,8 +257,8 @@ . = ..() if(.) return - if(object_cell_slot?.primary && !isnull(object_cell_slot.cell)) - return object_cell_slot.cell + if(obj_cell_slot?.primary && !isnull(obj_cell_slot.cell)) + return obj_cell_slot.cell #warn inducer diff --git a/code/game/objects/systems/cell_slot.dm b/code/game/objects/systems/cell_slot.dm index cea52de2290c..06c6c4643db6 100644 --- a/code/game/objects/systems/cell_slot.dm +++ b/code/game/objects/systems/cell_slot.dm @@ -13,10 +13,15 @@ var/receive_inducer = FALSE /// allow EMPs to hit? var/receive_emp = FALSE + /// allow explosions to hit cell? + // todo: currently unused + var/recieve_explosion = FALSE /// allow quick removal by clicking with hand? var/remove_yank_offhand = FALSE /// allow context menu removal? var/remove_yank_context = FALSE + /// allow quick removal by using in hand? + var/remove_yank_inhand = FALSE /// no-tool time for removal, if any var/remove_yank_time = 0 /// tool behavior for removal, if any @@ -24,9 +29,6 @@ /// tool time for removal, if any var/remove_tool_time = 0 #warn hook above - /// allow explosions to hit cell? - // todo: currently unused - var/recieve_explosion = FALSE /// legacy // todo: kill this var/legacy_use_device_cells = FALSE @@ -51,6 +53,9 @@ cell.forceMove(parent) parent.object_cell_slot_inserted(cell, src) +/datum/object_system/cell_slot/proc/interaction_active(mob/user) + return parent.object_cell_slot_interactable(user, src)) + //? Hooks /** @@ -65,13 +70,31 @@ /obj/proc/object_cell_slot_inserted(obj/item/cell/cell, datum/object_system/cell_slot/slot) return +/** + * hook called to check if cell slot removal behavior is active + */ +/obj/proc/object_cell_slot_mutable(mob/user, datum/object_system/cell_slot/slot) + return TRUE + //? Lazy wrappers for init -/obj/proc/init_cell_slot_easy_tool(offhand_removal = TRUE) - ASSERT(isnull(object_cell_slot)) - object_cell_slot = new(src) +/obj/proc/init_cell_slot(initial_cell_path) + RETURN_TYPE(/datum/object_system/cell_slot) + ASSERT(isnull(obj_cell_slot)) + obj_cell_slot = new(src) + if(initial_cell_path) + obj_cell_slot.cell = new initial_cell_path + return obj_cell_slot + +/obj/proc/init_cell_slot_easy_tool(initial_cell_path, offhand_removal = TRUE, inhand_removal = FALSE) + RETURN_TYPE(/datum/object_system/cell_slot) + if(isnull(init_cell_slot(initial_cell_path))) + return if(offhand_removal) - object_cell_slot.remove_yank_offhand = TRUE - object_cell_slot.remove_yank_context = TRUE - object_cell_slot.remove_yank_time = 0 - object_cell_slot.legacy_use_device_cells = TRUE + obj_cell_slot.remove_yank_offhand = TRUE + if(inhand_removal) + obj_cell_slot.remove_yank_inhand = FALSE + obj_cell_slot.remove_yank_context = TRUE + obj_cell_slot.remove_yank_time = 0 + obj_cell_slot.legacy_use_device_cells = TRUE + return obj_cell_slot From a451bf8e78fbce1eff57030b3e7b27b85e125c0f Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 10:03:27 -0700 Subject: [PATCH 05/33] context --- .../signals/signals_atom/context_system.dm | 3 + code/__DEFINES/procs/clickcode.dm | 2 + code/game/atoms/atom.dm | 2 +- code/game/click/context.dm | 4 +- code/game/click/other_mobs.dm | 14 +++ code/game/mecha/mecha.dm | 4 +- code/game/objects/items.dm | 20 ++++- code/game/objects/items/devices/flash.dm | 2 +- code/game/objects/items/devices/flashlight.dm | 2 +- .../objects/items/devices/radio/jammer.dm | 2 +- .../objects/items/devices/suit_cooling.dm | 2 +- code/game/objects/items/inducer.dm | 25 +++--- code/game/objects/items/tools/weldingtool.dm | 2 +- code/game/objects/items/uav.dm | 2 +- code/game/objects/items/weapons/RCD.dm | 4 +- .../objects/items/weapons/melee/energy.dm | 2 +- code/game/objects/items/weapons/stunbaton.dm | 2 +- code/game/objects/objs.dm | 88 +++++++++++++++++-- code/game/objects/systems/cell_slot.dm | 4 +- code/game/vehicles/vehicle.dm | 2 +- code/modules/fishing/equipment/rod.dm | 3 + code/modules/hardsuits/_rig.dm | 2 +- .../integrated_electronics/core/assemblies.dm | 2 +- code/modules/mining/drilling/drill.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 4 +- code/modules/power/apc.dm | 2 +- code/modules/power/cell.dm | 2 +- code/modules/power/lighting/lighting.dm | 2 +- code/modules/projectiles/guns/energy.dm | 2 +- .../projectiles/guns/magnetic/magnetic.dm | 2 +- .../modules/projectiles/magazines/smartmag.dm | 2 +- code/modules/shieldgen/handheld_defuser.dm | 2 +- 32 files changed, 167 insertions(+), 48 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm index 2aa623ad86e9..53f6489e7e1b 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm @@ -7,3 +7,6 @@ /// from base of /atom/proc/context_act: (key, mob/user) #define COMSIG_ATOM_CONTEXT_ACT "atom_context_act" #define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0) + +/// create context +#define ATOM_CONTEXT_TUPLE(name, image) list(name, image) diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm index f8cc82c644c7..76429539a068 100644 --- a/code/__DEFINES/procs/clickcode.dm +++ b/code/__DEFINES/procs/clickcode.dm @@ -33,6 +33,8 @@ #define CLICKCHAIN_DID_SOMETHING (1<<5) /// completely block attacking (notably, attack_mob, attack_obj) from happening by halting standard_melee_attack. #define CLICKCHAIN_DO_NOT_ATTACK (1<<6) +/// intercepted by component +#define CLICKCHAIN_COMPONENT_SIGNAL_HANDLED (1<<7) //! Reachability Depths - checked from level of DirectAccess and turf adjacency. /// default reachability depth diff --git a/code/game/atoms/atom.dm b/code/game/atoms/atom.dm index 9c9e630ee57d..b89fa613e07a 100644 --- a/code/game/atoms/atom.dm +++ b/code/game/atoms/atom.dm @@ -873,7 +873,7 @@ return reagents && (reagents.reagents_holder_flags & DRAINABLE) -/atom/proc/get_cell() +/atom/proc/get_cell(inducer) return //? Radiation diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 6323efe45bb9..68ac8901853e 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -5,9 +5,9 @@ * get context options * * key is a text string - * value are tuples of (name, image) + * value are tuples; use ATOM_CONTEXT_TUPLE to create. * - * @return list(key = list(name, image)) + * @return list(key = value) */ /atom/proc/context_query(mob/user, distance) . = list() diff --git a/code/game/click/other_mobs.dm b/code/game/click/other_mobs.dm index d54b5226b340..361ea9e44c76 100644 --- a/code/game/click/other_mobs.dm +++ b/code/game/click/other_mobs.dm @@ -32,8 +32,22 @@ /// Return TRUE to cancel other attack hand effects that respect it. /atom/proc/attack_hand(mob/user, list/params) + if(on_attack_hand(user, params)) + return TRUE . = _try_interact(user) +/** + * Override this instead of attack_hand. + * + * Return TRUE to cancel other attack hand effects that respect it. + * + * @params + * * user - the user + * * params - click parameters + */ +/atom/proc/on_attack_hand(mob/user, list/params) + return FALSE + //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. /atom/proc/_try_interact(mob/user) // if(isAdminGhostAI(user)) //admin abuse diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 04dbf514158d..410669e08932 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -401,7 +401,7 @@ return cell = new /obj/item/cell/high(src) -/obj/mecha/get_cell() +/obj/mecha/get_cell(inducer) return cell /obj/mecha/proc/add_cabin() @@ -2853,5 +2853,5 @@ occupant.clear_alert("mech damage") // Various sideways-defined get_cells -/obj/mecha/get_cell() +/obj/mecha/get_cell(inducer) return cell diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4a10872a7473..a12fc57c4f5a 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -768,17 +768,33 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. // SHOULD_CALL_PARENT(TRUE) // attack_self isn't really part of the item attack chain. SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) + if(on_attack_self(user)) + return TRUE if(interaction_flags_item & INTERACT_ITEM_ATTACK_SELF) interact(user) - on_attack_self(user) /** * Called after we attack self * Used to allow for attack_self to be interrupted by signals in nearly all cases. * You should usually override this instead of attack_self. + * + * You should do . = ..() and check ., if it's TRUE, it means a parent proc requested the call chain to stop. + * + * @return TRUE to signal to overrides to stop the chain and do nothing. */ /obj/item/proc/on_attack_self(mob/user) - return + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_inhand && obj_cell_slot.interaction_active(src)) + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + visible_self = SPAN_NOTICE("You remove the cell from [src]."), + ) + log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + return TRUE + return FALSE //? Mob Armor diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 9ece7196e696..605d91a181a3 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -72,7 +72,7 @@ icon_state = "[base_icon]" return -/obj/item/flash/get_cell() +/obj/item/flash/get_cell(inducer) return power_supply /obj/item/flash/proc/get_external_power_supply() diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 6fcf18ad20bc..6c497c9b01e3 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -57,7 +57,7 @@ update_appearance() return PROCESS_KILL -/obj/item/flashlight/get_cell() +/obj/item/flashlight/get_cell(inducer) return cell /obj/item/flashlight/verb/toggle() diff --git a/code/game/objects/items/devices/radio/jammer.dm b/code/game/objects/items/devices/radio/jammer.dm index 24453693e9c5..69ef1cf538f8 100644 --- a/code/game/objects/items/devices/radio/jammer.dm +++ b/code/game/objects/items/devices/radio/jammer.dm @@ -39,7 +39,7 @@ var/global/list/active_radio_jammers = list() QDEL_NULL(power_source) return ..() -/obj/item/radio_jammer/get_cell() +/obj/item/radio_jammer/get_cell(inducer) return power_source /obj/item/radio_jammer/proc/turn_off(mob/user) diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index d32a4a0219a7..10718aac8cd0 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -217,7 +217,7 @@ /obj/item/suit_cooling_unit/emergency/updateicon() return -/obj/item/suit_cooling_unit/emergency/get_cell() +/obj/item/suit_cooling_unit/emergency/get_cell(inducer) if(on) return null // Don't let recharging happen while we're on return cell diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index 2399937a1fbb..ad6f44ad510d 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -36,8 +36,22 @@ var/datum/object_system/cell_slot/cell_slot = init_cell_slot(cell_type) cell_slot.receive_emp = TRUE cell_slot.receive_inducer = TRUE + cell_slot.remove_yank_offhand = TRUE + cell_slot.remove_yank_context = TRUE + cell_slot.remove_yank_inhand = TRUE update_appearance() +/obj/item/inducer/examine(mob/user, dist) + . = ..() + if(!isnull(obj_cell_slot.cell)) + . += "
Its display shows: [round(obj_cell_slot.cell.charge)] / [obj_cell_slot.cell.maxcharge]." + else + . += "
Its display is dark." + if(opened) + . += SPAN_NOTICE("Its battery compartment is open, and looks like it can be closed with a screwdriver") + else + . += SPAN_NOTICE("Its battery compartment is closed, and looks like it can be opened with a screwdriver") + /obj/item/inducer/afterattack(atom/target, mob/user, clickchain_flags, list/params) if(user.a_intent == INTENT_HARM) return ..() @@ -149,15 +163,6 @@ /obj/item/inducer/object_cell_slot_mutable(mob/user, datum/object_system/cell_slot/slot) return opened && ..() -/obj/item/inducer/examine(mob/living/M) - . = ..() - if(!isnull(obj_cell_slot.cell)) - . += "
Its display shows: [round(cell.charge)] / [cell.maxcharge]." - else - . += "
Its display is dark." - if(opened) - . += "
Its battery compartment is open." - /obj/item/inducer/update_icon() ..() cut_overlays() @@ -214,7 +219,7 @@ * even if full, always add things, or the inducer might think we don't support induction when we do! */ /atom/proc/inducer_scan(obj/item/inducer/I, list/things_to_induce = list(), inducer_flags) - var/obj/item/cell/C = get_cell() + var/obj/item/cell/C = get_cell(TRUE) if(C) things_to_induce += C if(C.charge >= C.maxcharge) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index a080a6322f25..04609b2b242e 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -570,7 +570,7 @@ power_supply = new /obj/item/cell/device(src) update_icon() -/obj/item/weldingtool/electric/get_cell() +/obj/item/weldingtool/electric/get_cell(inducer) return power_supply /obj/item/weldingtool/electric/examine(mob/user, dist) diff --git a/code/game/objects/items/uav.dm b/code/game/objects/items/uav.dm index 47b10a81b77f..43cca4dbc4b8 100644 --- a/code/game/objects/items/uav.dm +++ b/code/game/objects/items/uav.dm @@ -250,7 +250,7 @@ visible_message(SPAN_NOTICE("[nickname] gracefully settles onto the ground.")) //////////////// Helpers -/obj/item/uav/get_cell() +/obj/item/uav/get_cell(inducer) return cell /obj/item/uav/relaymove(var/mob/user, direction, signal = 1) diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 7a0569b4c20e..da304f685f5e 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -291,7 +291,7 @@ QDEL_NULL(cell) return ..() -/obj/item/rcd/electric/get_cell() +/obj/item/rcd/electric/get_cell(inducer) return cell /obj/item/rcd/electric/can_afford(amount) // This makes it so borgs won't drain their last sliver of charge by mistake, as a bonus. @@ -323,7 +323,7 @@ desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity from an external power source." make_cell = FALSE -/obj/item/rcd/electric/mounted/get_cell() +/obj/item/rcd/electric/mounted/get_cell(inducer) return get_external_power_supply() /obj/item/rcd/electric/mounted/proc/get_external_power_supply() diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 30eb2ca05c58..d2b96d3c40c0 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -145,7 +145,7 @@ return return ..() -/obj/item/melee/energy/get_cell() +/obj/item/melee/energy/get_cell(inducer) return bcell /obj/item/melee/energy/update_icon() diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 97b65063c557..a2426135c332 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -30,7 +30,7 @@ . = ..() update_icon() -/obj/item/melee/baton/get_cell() +/obj/item/melee/baton/get_cell(inducer) return bcell /obj/item/melee/baton/suicide_act(mob/user) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index a23735be1639..e8ed2301ea04 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -62,7 +62,6 @@ //? Systems - naming convention is 'object_[system]' /// cell slot system var/datum/object_system/cell_slot/obj_cell_slot - #warn hook above //? misc / legacy /// Set when a player renames a renamable object. @@ -246,21 +245,38 @@ //? Attacks -#warn cell attackby/attack hand +/obj/on_attack_hand(mob/user, list/params) + . = ..() + if(.) + return + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_offhand && user.is_holding_inactive(src) && obj_cell_slot.interaction_active(user)) + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + visible_self = SPAN_NOTICE("You remove the cell from [src]."), + ) + log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + return TRUE //? Cells / Inducers /** * get cell slot */ -/obj/get_cell() +/obj/get_cell(inducer) . = ..() if(.) return - if(obj_cell_slot?.primary && !isnull(obj_cell_slot.cell)) + if(obj_cell_slot?.primary && !isnull(obj_cell_slot.cell) && (!inducer || obj_cell_slot.receive_inducer)) return obj_cell_slot.cell -#warn inducer +/obj/inducer_scan(obj/item/inducer/I, list/things_to_induce, inducer_flags) + . = ..() + if(!isnull(obj_cell_slot?.cell) && !obj_cell_slot.primary && obj_cell_slot.receive_inducer) + things_to_induce += obj_cell_slot.cell //? Climbing @@ -394,7 +410,29 @@ //? Context -#warn cell context +/obj/context_query(mob/user, distance) + . = ..() + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(user)) + .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null) + +/obj/context_act(mob/user, key) + if(key == "obj_cell_slot") + if(isnull(obj_cell_slot.cell)) + user.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) + return TRUE + if(!obj_cell_slot.interaction_active(user)) + return TRUE + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + visible_self = SPAN_NOTICE("You remove the cell from [src]."), + ) + log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + return TRUE + return ..() //? Hiding / Underfloor @@ -503,4 +541,40 @@ //? Tool System -#warn hook cell slot +/obj/dynamic_tool_functions(obj/item/I, mob/user) + if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(user)) + return ..() + . = list() + .[obj_cell_slot.remove_tool_behavior] = "remove cell" + return merge_double_lazy_assoc_list(..(), .) + +/obj/dynamic_tool_image(function, hint) + if(hint == "remove cell") + return dyntool_image_backward(function) + return ..() + +/obj/tool_act(obj/item/I, mob/user, function, flags, hint) + if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(user)) + return ..() + if(isnull(obj_cell_slot.cell)) + user.action_feedback(SPAN_WARNING("[src] has no cell in it.")) + return CLICKCHAIN_DO_NOT_PROPAGATE + log_construction(user, src, "removing cell") + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] starts removing the cell from [src]."), + visible_self = SPAN_NOTICE("You start removing the cell from [src]."), + audible_hard = SPAN_NOTICE("You hear fasteners being undone."), + ) + if(!use_tool(function, I, user, flags, obj_cell_slot.remove_tool_time, 1)) + return CLICKCHAIN_DO_NOT_PROPAGATE + log_construction(user, src, "removed cell") + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + visible_self = SPAN_NOTICE("You remove the cell from [src]."), + ) + return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE diff --git a/code/game/objects/systems/cell_slot.dm b/code/game/objects/systems/cell_slot.dm index 06c6c4643db6..76e17b59b994 100644 --- a/code/game/objects/systems/cell_slot.dm +++ b/code/game/objects/systems/cell_slot.dm @@ -28,6 +28,8 @@ var/remove_tool_behavior = null /// tool time for removal, if any var/remove_tool_time = 0 + /// removal is discrete or loud + var/remove_is_discrete = TRUE #warn hook above /// legacy // todo: kill this @@ -54,7 +56,7 @@ parent.object_cell_slot_inserted(cell, src) /datum/object_system/cell_slot/proc/interaction_active(mob/user) - return parent.object_cell_slot_interactable(user, src)) + return parent.object_cell_slot_mutable(user, src) //? Hooks diff --git a/code/game/vehicles/vehicle.dm b/code/game/vehicles/vehicle.dm index 16c57f5a5618..14d16ccbd38f 100644 --- a/code/game/vehicles/vehicle.dm +++ b/code/game/vehicles/vehicle.dm @@ -187,5 +187,5 @@ mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge) return -/obj/vehicle/get_cell() +/obj/vehicle/get_cell(inducer) return cell diff --git a/code/modules/fishing/equipment/rod.dm b/code/modules/fishing/equipment/rod.dm index d2e3ee710661..f29b4ea4e32b 100644 --- a/code/modules/fishing/equipment/rod.dm +++ b/code/modules/fishing/equipment/rod.dm @@ -81,6 +81,9 @@ update_icon() /obj/item/fishing_rod/on_attack_self(mob/user) + . = ..() + if(.) + return reel(user) /obj/item/fishing_rod/proc/reel(mob/user, atom/target) diff --git a/code/modules/hardsuits/_rig.dm b/code/modules/hardsuits/_rig.dm index e744deb0b9af..e7535c476e5f 100644 --- a/code/modules/hardsuits/_rig.dm +++ b/code/modules/hardsuits/_rig.dm @@ -117,7 +117,7 @@ var/sprint_slowdown_modifier = 0 // Sprinter module modifier. -/obj/item/hardsuit/get_cell() +/obj/item/hardsuit/get_cell(inducer) return cell /obj/item/hardsuit/examine(mob/user, dist) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 82a7de071c85..2f4f13d4d817 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -149,7 +149,7 @@ /obj/item/electronic_assembly/proc/check_interactivity(mob/user) return ui_status(user, GLOB.physical_state) == UI_INTERACTIVE -/obj/item/electronic_assembly/get_cell() +/obj/item/electronic_assembly/get_cell(inducer) return battery // TGUI diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index 59b97d13a2f6..2ef6a7d542f5 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -54,7 +54,7 @@ ) RefreshParts() -/obj/machinery/mining/drill/get_cell() +/obj/machinery/mining/drill/get_cell(inducer) return cell /obj/machinery/mining/drill/process(delta_time) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 80259f1ef5b4..740c7c9122a9 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1071,7 +1071,7 @@ to_chat(src, "Module isn't activated") installed_modules() return 1 - + if(href_list["character_profile"]) if(!profile) profile = new(src) @@ -1403,7 +1403,7 @@ /mob/living/silicon/robot/is_sentient() return braintype != BORG_BRAINTYPE_DRONE -/mob/living/silicon/robot/get_cell() +/mob/living/silicon/robot/get_cell(inducer) return cell /mob/living/silicon/robot/verb/robot_nom(var/mob/living/T in living_mobs(1)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 2e33634e47b5..4c9448b1322d 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -400,7 +400,7 @@ GLOBAL_LIST_EMPTY(apcs) return ..() -/obj/machinery/power/apc/get_cell() +/obj/machinery/power/apc/get_cell(inducer) return cell // APCs are pixel-shifted, so they need to be updated. diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 7803d3581ac1..9b61493e6f34 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -44,7 +44,7 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/cell/get_cell() +/obj/item/cell/get_cell(inducer) return src /obj/item/cell/process(delta_time) diff --git a/code/modules/power/lighting/lighting.dm b/code/modules/power/lighting/lighting.dm index 2487b2f2cecf..dd33a01955c4 100644 --- a/code/modules/power/lighting/lighting.dm +++ b/code/modules/power/lighting/lighting.dm @@ -632,7 +632,7 @@ var/global/list/light_type_cache = list() on = (s && status == LIGHT_OK) update() -/obj/machinery/light/get_cell() +/obj/machinery/light/get_cell(inducer) return cell // examine verb diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 34a4fa476934..5d3d7e0718bf 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -46,7 +46,7 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/gun/energy/get_cell() +/obj/item/gun/energy/get_cell(inducer) return power_supply /obj/item/gun/energy/process(delta_time) diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index fd78f7aee3d1..ec96d1d51869 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -35,7 +35,7 @@ QDEL_NULL(capacitor) . = ..() -/obj/item/gun/magnetic/get_cell() +/obj/item/gun/magnetic/get_cell(inducer) return cell /obj/item/gun/magnetic/process(delta_time) diff --git a/code/modules/projectiles/magazines/smartmag.dm b/code/modules/projectiles/magazines/smartmag.dm index 91abc9552a02..36f372c37b1f 100644 --- a/code/modules/projectiles/magazines/smartmag.dm +++ b/code/modules/projectiles/magazines/smartmag.dm @@ -129,7 +129,7 @@ attached_cell.emp_act(severity) // Finds the cell for the magazine, used by rechargers -/obj/item/ammo_magazine/smart/get_cell() +/obj/item/ammo_magazine/smart/get_cell(inducer) return attached_cell // Removes energy from the attached cell when creating new bullets diff --git a/code/modules/shieldgen/handheld_defuser.dm b/code/modules/shieldgen/handheld_defuser.dm index edf509c4bda7..2c0d19c2b871 100644 --- a/code/modules/shieldgen/handheld_defuser.dm +++ b/code/modules/shieldgen/handheld_defuser.dm @@ -21,7 +21,7 @@ STOP_PROCESSING(SSobj, src) . = ..() -/obj/item/shield_diffuser/get_cell() +/obj/item/shield_diffuser/get_cell(inducer) return cell /obj/item/shield_diffuser/process(delta_time) From 1d92d1764041ead720f7d7464019089e32d39411 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:00:38 -0700 Subject: [PATCH 06/33] context --- citadel.dme | 4 ++ code/__DEFINES/admin/admin.dm | 2 + .../signals/signals_atom/context_system.dm | 9 ++++- code/__DEFINES/event_args.dm | 7 ++++ code/datums/event_args/_event_args.dm | 5 +++ code/datums/event_args/actor.dm | 12 ++++++ code/datums/event_args/clickchain.dm | 18 +++++++++ code/game/atoms/atom.dm | 4 ++ code/game/click/click.dm | 2 + code/game/click/context.dm | 10 +++-- code/game/click/other_mobs.dm | 8 ++-- code/game/objects/objs.dm | 37 +++++++++++-------- code/game/objects/systems/cell_slot.dm | 2 - code/game/rendering/legacy/radial.dm | 6 +++ code/modules/client/client.dm | 4 ++ code/modules/client/client_procs.dm | 2 + code/modules/logging/logging.dm | 10 +++++ code/modules/mob/login.dm | 3 ++ code/modules/mob/mob.dm | 2 + code/modules/tools/_tool_system.dm | 2 + 20 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 code/__DEFINES/event_args.dm create mode 100644 code/datums/event_args/_event_args.dm create mode 100644 code/datums/event_args/actor.dm create mode 100644 code/datums/event_args/clickchain.dm diff --git a/citadel.dme b/citadel.dme index df648da87cb4..762c367d9859 100644 --- a/citadel.dme +++ b/citadel.dme @@ -43,6 +43,7 @@ #include "code\__DEFINES\damage_organs.dm" #include "code\__DEFINES\directional.dm" #include "code\__DEFINES\dna.dm" +#include "code\__DEFINES\event_args.dm" #include "code\__DEFINES\fonts.dm" #include "code\__DEFINES\gamemode.dm" #include "code\__DEFINES\holidays.dm" @@ -744,6 +745,9 @@ #include "code\datums\elements\clothing\dynamic_recolor.dm" #include "code\datums\elements\items\darksight_granter.dm" #include "code\datums\elements\items\hud_granter.dm" +#include "code\datums\event_args\_event_args.dm" +#include "code\datums\event_args\actor.dm" +#include "code\datums\event_args\clickchain.dm" #include "code\datums\helper_datums\construction_datum.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" diff --git a/code/__DEFINES/admin/admin.dm b/code/__DEFINES/admin/admin.dm index 2dc222d92e88..a22547f2273d 100644 --- a/code/__DEFINES/admin/admin.dm +++ b/code/__DEFINES/admin/admin.dm @@ -60,6 +60,8 @@ #define ADMIN_LOOKUP(user) ("[key_name_admin(user)][ADMIN_QUE(user)]") #define ADMIN_LOOKUPFLW(user) ("[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]") #define COORD(src) ("[src ? src.Admin_Coordinates_Readable() : "nonexistent location"]") +// todo: this should be made faster/better, and support stuff like inventory / storage awareness +#define AUDIT_COORD(src) ("[src ? src.Admin_Coordinates_Readable() : "nonexistent location"]") #define AREACOORD(src) ("[src ? src.Admin_Coordinates_Readable(TRUE) : "nonexistent location"]") #define ADMIN_COORDJMP(src) ("[src ? src.Admin_Coordinates_Readable(FALSE, TRUE) : "nonexistent location"]") #define ADMIN_VERBOSEJMP(src) ("[src ? src.Admin_Coordinates_Readable(TRUE, TRUE) : "nonexistent location"]") diff --git a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm index 53f6489e7e1b..630e27ef2be7 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm @@ -9,4 +9,11 @@ #define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0) /// create context -#define ATOM_CONTEXT_TUPLE(name, image) list(name, image) +/// * name: name +/// * image: context menu image +/// * distance: distance where this is valid; much be reachable or actable; null = requires adjacency or adjacency-equivalence +#define ATOM_CONTEXT_TUPLE(name, image, distance) list(name, image, distance) + +/// when used as distance, telekinetics and other things do not count as adjacency +// todo: currently not implemented +#define ATOM_CONTEXT_FORCE_PHYSICAL_ADJACENCY null diff --git a/code/__DEFINES/event_args.dm b/code/__DEFINES/event_args.dm new file mode 100644 index 000000000000..7018e567ce05 --- /dev/null +++ b/code/__DEFINES/event_args.dm @@ -0,0 +1,7 @@ +//? for /datum/event_args/actor + +#define WRAP_MOB_TO_ACTOR_EVENT_ARGS(VARNAME) VARNAME = ismob(VARNAME)? new /datum/event_args/actor(VARNAME) : VARNAME + +//? for /datum/event_args/clickchain + +#define WRAP_MOB_TO_CLICKCHAIN_EVENT_ARGS(VARNAME) VARNAME = ismob(VARNAME)? new /datum/event_args/clickchain(VARNAME) : VARNAME diff --git a/code/datums/event_args/_event_args.dm b/code/datums/event_args/_event_args.dm new file mode 100644 index 000000000000..d2569f99fff3 --- /dev/null +++ b/code/datums/event_args/_event_args.dm @@ -0,0 +1,5 @@ +/** + * datums used to hold data for procs without having to pass too many args around + */ +/datum/event_args + abstract_type = /datum/event_args diff --git a/code/datums/event_args/actor.dm b/code/datums/event_args/actor.dm new file mode 100644 index 000000000000..528d81820de1 --- /dev/null +++ b/code/datums/event_args/actor.dm @@ -0,0 +1,12 @@ +/** + * used to hold semantic data about an action being done by an actor vs initiator (controller) + */ +/datum/event_args/actor + /// the mob performing the action + var/mob/performer + /// the mob actually initiating the action, e.g. a remote controller. + var/mob/initiator + +/datum/event_args/actor/New(mob/performer, mob/initiator) + src.performer = performer + src.initiator = isnull(initiator)? performer : initiator diff --git a/code/datums/event_args/clickchain.dm b/code/datums/event_args/clickchain.dm new file mode 100644 index 000000000000..074c0e26aa3d --- /dev/null +++ b/code/datums/event_args/clickchain.dm @@ -0,0 +1,18 @@ +/** + * used to hold data about a click action + */ +/datum/event_args/clickchain + /// the mob performing the action + var/mob/performer + /// the mob actually initiating the action, e.g. a remote controller. + var/mob/initiator + /// a_intent + var/intent + /// click params + var/list/params + +/datum/event_args/clickchain/New(mob/performer, mob/initiator, intent, list/params) + src.performer = performer + src.initiator = isnull(initiator)? performer : initiator + src.intent = isnull(intent)? performer.a_intent : intent + src.params = isnull(params)? list() : params diff --git a/code/game/atoms/atom.dm b/code/game/atoms/atom.dm index b89fa613e07a..3a00472a35d2 100644 --- a/code/game/atoms/atom.dm +++ b/code/game/atoms/atom.dm @@ -41,6 +41,10 @@ /// armor datum type var/armor_type = /datum/armor/none + //? Context + /// open context menus by mob + var/list/context_menus + //? Economy /// intrinsic worth without accounting containing reagents / materials - applies in static and dynamic mode. var/worth_intrinsic = 0 diff --git a/code/game/click/click.dm b/code/game/click/click.dm index d58539cf6565..fdf533a4fe32 100644 --- a/code/game/click/click.dm +++ b/code/game/click/click.dm @@ -289,6 +289,8 @@ /atom/proc/AltClick(var/mob/user) SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) + if(context_menu(new /datum/event_args/actor(user))) + return TRUE return FALSE // todo: rework diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 68ac8901853e..cc36acb63487 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -9,7 +9,7 @@ * * @return list(key = value) */ -/atom/proc/context_query(mob/user, distance) +/atom/proc/context_query(datum/event_args/actor/actor) . = list() SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., user, distance) @@ -18,9 +18,13 @@ * * @return TRUE / FALSE; TRUE if handled. */ -/atom/proc/context_act(mob/user, key) +/atom/proc/context_act(datum/event_args/actor/actor, key) if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, user) & RAISE_ATOM_CONTEXT_ACT_HANDLED) return TRUE return FALSE -#warn hook all +/atom/proc/context_menu(datum/event_args/actor/actor) + // admin proccall support + WRAP_MOB_TO_ACTOR_EVENT_ARGS(actor) + // todo: dynamically rebuild menu based on distance? + #warn impl diff --git a/code/game/click/other_mobs.dm b/code/game/click/other_mobs.dm index 361ea9e44c76..93d2f50dae07 100644 --- a/code/game/click/other_mobs.dm +++ b/code/game/click/other_mobs.dm @@ -31,8 +31,9 @@ A.attack_hand(src) /// Return TRUE to cancel other attack hand effects that respect it. +// todo: /datum/event_args/clickchain /atom/proc/attack_hand(mob/user, list/params) - if(on_attack_hand(user, params)) + if(on_attack_hand(new /datum/event_args/actor(user, intent = user.a_intent, params = params))) return TRUE . = _try_interact(user) @@ -42,10 +43,9 @@ * Return TRUE to cancel other attack hand effects that respect it. * * @params - * * user - the user - * * params - click parameters + * * e_args - click data */ -/atom/proc/on_attack_hand(mob/user, list/params) +/atom/proc/on_attack_hand(datum/event_args/clickchain/e_args) return FALSE //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index e8ed2301ea04..1a7ab51d59af 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -245,20 +245,20 @@ //? Attacks -/obj/on_attack_hand(mob/user, list/params) +/obj/on_attack_hand(datum/event_args/clickchain/e_args) . = ..() if(.) return - if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_offhand && user.is_holding_inactive(src) && obj_cell_slot.interaction_active(user)) - user.visible_action_feedback( + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_offhand && e_args.performer.is_holding_inactive(src) && obj_cell_slot.interaction_active(user)) + e_args.performer.visible_action_feedback( target = src, hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + visible_hard = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), visible_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") - user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + log_construction(e_args.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) return TRUE //? Cells / Inducers @@ -410,30 +410,37 @@ //? Context -/obj/context_query(mob/user, distance) +/obj/context_query(datum/event_args/actor/actor) . = ..() if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(user)) - .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null) + .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null, null) -/obj/context_act(mob/user, key) +/obj/context_act(datum/event_args/actor/actor, key) if(key == "obj_cell_slot") if(isnull(obj_cell_slot.cell)) - user.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) + actor.performer.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) return TRUE - if(!obj_cell_slot.interaction_active(user)) + if(!obj_cell_slot.interaction_active(actor.performer)) return TRUE - user.visible_action_feedback( + actor.performer.visible_action_feedback( target = src, hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), + visible_hard = SPAN_NOTICE("[actor.performer] removes the cell from [src]."), audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), visible_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") - user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + log_construction(actor.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + actor.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(actor.performer)) return TRUE return ..() +//? EMP + +/obj/emp_act(severity) + . = ..() + if(obj_cell_slot?.receive_emp) + obj_cell_slot?.cell?.emp_act(severity) + //? Hiding / Underfloor /obj/proc/is_hidden_underfloor() diff --git a/code/game/objects/systems/cell_slot.dm b/code/game/objects/systems/cell_slot.dm index 76e17b59b994..e772c9b37097 100644 --- a/code/game/objects/systems/cell_slot.dm +++ b/code/game/objects/systems/cell_slot.dm @@ -8,7 +8,6 @@ var/cell_type /// considered primary? if so, we get returned on get_cell() var/primary = TRUE - #warn hook below /// allow inducer? var/receive_inducer = FALSE /// allow EMPs to hit? @@ -30,7 +29,6 @@ var/remove_tool_time = 0 /// removal is discrete or loud var/remove_is_discrete = TRUE - #warn hook above /// legacy // todo: kill this var/legacy_use_device_cells = FALSE diff --git a/code/game/rendering/legacy/radial.dm b/code/game/rendering/legacy/radial.dm index a75870ad3a52..464001674da3 100644 --- a/code/game/rendering/legacy/radial.dm +++ b/code/game/rendering/legacy/radial.dm @@ -314,3 +314,9 @@ GLOBAL_LIST_EMPTY(radial_menus) QDEL_NULL(menu) GLOB.radial_menus -= uniqueid return answer + +/datum/radial_menu/context_menu + +/datum/radial_menu/Destroy() + LAZYREMOVE(anchor.context_menus, current_user) + return ..() diff --git a/code/modules/client/client.dm b/code/modules/client/client.dm index 915bb8a0680d..57b2b0908a09 100644 --- a/code/modules/client/client.dm +++ b/code/modules/client/client.dm @@ -52,6 +52,10 @@ /// panic bunker is still resolving var/panic_bunker_pending = FALSE + //? Context Menus + /// open context menu + var/datum/radial_menu/context_menu/context_menu + //? Rendering /// Click catcher var/atom/movable/screen/click_catcher/click_catcher diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 376641d2b80e..23dc06cc8aeb 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -359,6 +359,8 @@ return ..() /client/Destroy() + // get rid of context menus + QDEL_NULL(context_menu) // Unregister globals GLOB.clients -= src GLOB.directory -= ckey diff --git a/code/modules/logging/logging.dm b/code/modules/logging/logging.dm index 53ef337d6fec..ef0a16a906b8 100644 --- a/code/modules/logging/logging.dm +++ b/code/modules/logging/logging.dm @@ -22,12 +22,22 @@ /** * Log construction action + * + * todo: log initiator */ /proc/log_construction(mob/user, atom/target, message) log_game("CONSTRUCTION: [key_name(user)] [COORD(user)] -> [target] [COORD(target)]: [message]") +/** + * log click - context menu + */ +/proc/log_click_context(datum/event_args/actor/actor, atom/target, message) + log_click("CONTEXT: [key_name(actor.initiator)][actor.performer != actor.initiator? " via [key_name(actor.performer)]" : ""] -> [target] [AUDIT_COORD(target)]: [message]") + /** * Log stack crafting + * + * todo: log initiator */ /proc/log_stackcrafting(mob/user, obj/item/stack/stack, name, amount, used, turf/where = get_turf(user)) log_game("STACKCRAFT: [key_name(user)] crafted [amount] of [name] with [used] of [stack] at [where]") diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 5d0c48e5e963..1820d5514afe 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -27,6 +27,9 @@ update_Login_details() world.update_status() + // get rid of old context menus + QDEL_NULL(client.context_menu) + client.images = list() //remove the images such as AIs being unable to see runes client.screen = list() //remove hud items just in case if(hud_used) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 70777dce0d63..c55499db698d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -52,6 +52,8 @@ return ..() /mob/Destroy() + // context menu + QDEL_NULL(context_menu) // status effects for(var/id in status_effects) var/datum/status_effect/effect = status_effects[id] diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 6e36f6a71b08..9676a181d33f 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -1,6 +1,8 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// +#warn use /datum/event_args/actor/actor + /** * ? Atom Tool API * From 524cb116d5b12121effb7c4355b0e46a51f17932 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:13:46 -0700 Subject: [PATCH 07/33] context --- code/__DEFINES/dcs/signals/signals_atom/context_system.dm | 7 ++++--- code/game/click/context.dm | 4 ++-- code/game/click/other_mobs.dm | 2 +- code/game/objects/objs.dm | 6 +++--- code/modules/mob/mob.dm | 2 -- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm index 630e27ef2be7..eefd472f7be5 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm @@ -1,10 +1,10 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -/// from base of /atom/proc/context_query: (list/options, mob/user, distance) +/// from base of /atom/proc/context_query: (list/options, datum/event_args/actor/actor) /// options list is the same format as /atom/proc/context_query, insert directly to it. #define COMSIG_ATOM_CONTEXT_QUERY "atom_context_query" -/// from base of /atom/proc/context_act: (key, mob/user) +/// from base of /atom/proc/context_act: (key, datum/event_args/actor/actor) #define COMSIG_ATOM_CONTEXT_ACT "atom_context_act" #define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0) @@ -12,7 +12,8 @@ /// * name: name /// * image: context menu image /// * distance: distance where this is valid; much be reachable or actable; null = requires adjacency or adjacency-equivalence -#define ATOM_CONTEXT_TUPLE(name, image, distance) list(name, image, distance) +/// * mobility: mobility flags required +#define ATOM_CONTEXT_TUPLE(name, image, distance, mobility) list(name, image, distance, mobility) /// when used as distance, telekinetics and other things do not count as adjacency // todo: currently not implemented diff --git a/code/game/click/context.dm b/code/game/click/context.dm index cc36acb63487..64200c940e2f 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -11,7 +11,7 @@ */ /atom/proc/context_query(datum/event_args/actor/actor) . = list() - SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., user, distance) + SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., actor) /** * act on a context option @@ -19,7 +19,7 @@ * @return TRUE / FALSE; TRUE if handled. */ /atom/proc/context_act(datum/event_args/actor/actor, key) - if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, user) & RAISE_ATOM_CONTEXT_ACT_HANDLED) + if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, actor) & RAISE_ATOM_CONTEXT_ACT_HANDLED) return TRUE return FALSE diff --git a/code/game/click/other_mobs.dm b/code/game/click/other_mobs.dm index 93d2f50dae07..c0ec19a8fb0e 100644 --- a/code/game/click/other_mobs.dm +++ b/code/game/click/other_mobs.dm @@ -33,7 +33,7 @@ /// Return TRUE to cancel other attack hand effects that respect it. // todo: /datum/event_args/clickchain /atom/proc/attack_hand(mob/user, list/params) - if(on_attack_hand(new /datum/event_args/actor(user, intent = user.a_intent, params = params))) + if(on_attack_hand(new /datum/event_args/clickchain(user, intent = user.a_intent, params = params))) return TRUE . = _try_interact(user) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 1a7ab51d59af..d1473b5eea90 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -249,7 +249,7 @@ . = ..() if(.) return - if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_offhand && e_args.performer.is_holding_inactive(src) && obj_cell_slot.interaction_active(user)) + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_offhand && e_args.performer.is_holding_inactive(src) && obj_cell_slot.interaction_active(e_args.performer)) e_args.performer.visible_action_feedback( target = src, hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, @@ -412,8 +412,8 @@ /obj/context_query(datum/event_args/actor/actor) . = ..() - if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(user)) - .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null, null) + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(actor.performer)) + .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null, null, MOBILITY_CAN_USE) /obj/context_act(datum/event_args/actor/actor, key) if(key == "obj_cell_slot") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c55499db698d..70777dce0d63 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -52,8 +52,6 @@ return ..() /mob/Destroy() - // context menu - QDEL_NULL(context_menu) // status effects for(var/id in status_effects) var/datum/status_effect/effect = status_effects[id] From 1e5014cf49233c2d50a0f9eaa94bd591dab9b85f Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:13:59 -0700 Subject: [PATCH 08/33] context --- code/modules/power/cell.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index d6d7a02edc0f..27014e8c924c 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -1,4 +1,4 @@ ->>>// the power cell +// the power cell // charge from 0 to 100% // fits in APC to provide backup power From 5cce0fcd8e56651fb0aee14e31e627706051129f Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:36:17 -0700 Subject: [PATCH 09/33] this is hell --- .../signals/signals_atom/context_system.dm | 4 +- code/__DEFINES/event_args.dm | 4 +- code/datums/event_args/actor.dm | 37 +++++++++++++++++++ code/datums/event_args/clickchain.dm | 11 ++---- code/datums/progressbar.dm | 4 ++ code/game/atoms/action_feedback.dm | 8 ++-- code/game/click/context.dm | 12 +++--- code/game/click/other_mobs.dm | 6 +-- code/game/objects/objs.dm | 22 +++++------ code/modules/logging/logging.dm | 4 +- code/modules/tools/_tool_system.dm | 2 +- 11 files changed, 76 insertions(+), 38 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm index eefd472f7be5..e765fd72e577 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/context_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/context_system.dm @@ -1,10 +1,10 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -/// from base of /atom/proc/context_query: (list/options, datum/event_args/actor/actor) +/// from base of /atom/proc/context_query: (list/options, datum/event_args/actor/e_args) /// options list is the same format as /atom/proc/context_query, insert directly to it. #define COMSIG_ATOM_CONTEXT_QUERY "atom_context_query" -/// from base of /atom/proc/context_act: (key, datum/event_args/actor/actor) +/// from base of /atom/proc/context_act: (key, datum/event_args/actor/e_args) #define COMSIG_ATOM_CONTEXT_ACT "atom_context_act" #define RAISE_ATOM_CONTEXT_ACT_HANDLED (1<<0) diff --git a/code/__DEFINES/event_args.dm b/code/__DEFINES/event_args.dm index 7018e567ce05..cfbbc03c37c3 100644 --- a/code/__DEFINES/event_args.dm +++ b/code/__DEFINES/event_args.dm @@ -2,6 +2,6 @@ #define WRAP_MOB_TO_ACTOR_EVENT_ARGS(VARNAME) VARNAME = ismob(VARNAME)? new /datum/event_args/actor(VARNAME) : VARNAME -//? for /datum/event_args/clickchain +//? for /datum/event_args/actor/clickchain -#define WRAP_MOB_TO_CLICKCHAIN_EVENT_ARGS(VARNAME) VARNAME = ismob(VARNAME)? new /datum/event_args/clickchain(VARNAME) : VARNAME +#define WRAP_MOB_TO_CLICKCHAIN_EVENT_ARGS(VARNAME) VARNAME = ismob(VARNAME)? new /datum/event_args/actor/clickchain(VARNAME) : VARNAME diff --git a/code/datums/event_args/actor.dm b/code/datums/event_args/actor.dm index 528d81820de1..c3c975f28fed 100644 --- a/code/datums/event_args/actor.dm +++ b/code/datums/event_args/actor.dm @@ -10,3 +10,40 @@ /datum/event_args/actor/New(mob/performer, mob/initiator) src.performer = performer src.initiator = isnull(initiator)? performer : initiator + +/datum/event_args/actor/proc/chat_feedback(atom/target, msg) + performer.action_feedback(msg, target) + initiator.action_feedback(msg, target) + +/datum/event_args/actor/proc/bubble_feedback(atom/target, msg) + performer.bubble_action_feedback(msg, target) + initiator.bubble_action_feedback(msg, target) + +/datum/event_args/actor/proc/visible_feedback(atom/target, range, visible, audible, visible_self, otherwise_self, visible_them, otherwise_them) + performer.visible_action_feedback( + target = target, + initiator = initiator, + hard_range = range, + visible_hard = visible, + audible_hard = audible, + visible_self = visible_self, + otherwise_self = otherwise_self, + visible_them = visible_them, + otherwise_them = otherwise_them, + ) + +/datum/event_args/actor/proc/visible_dual_feedback(atom/target, range_hard, range_soft, visible_hard, visible_soft, audible_hard, audible_soft, visible_self, otherwise_self, visible_them, otherwise_them) + performer.visible_action_feedback( + target = target, + initiator = initiator, + hard_range = range_hard, + soft_range = range_soft, + visible_hard = visible_hard, + visible_soft = visible_soft, + audible_hard = audible_hard, + audible_soft = audible_soft, + visible_self = visible_self, + otherwise_self = otherwise_self, + visible_them = visible_them, + otherwise_them = otherwise_them, + ) diff --git a/code/datums/event_args/clickchain.dm b/code/datums/event_args/clickchain.dm index 074c0e26aa3d..ce2039376a3f 100644 --- a/code/datums/event_args/clickchain.dm +++ b/code/datums/event_args/clickchain.dm @@ -1,18 +1,13 @@ /** * used to hold data about a click action */ -/datum/event_args/clickchain - /// the mob performing the action - var/mob/performer - /// the mob actually initiating the action, e.g. a remote controller. - var/mob/initiator +/datum/event_args/actor/clickchain /// a_intent var/intent /// click params var/list/params -/datum/event_args/clickchain/New(mob/performer, mob/initiator, intent, list/params) - src.performer = performer - src.initiator = isnull(initiator)? performer : initiator +/datum/event_args/actor/clickchain/New(mob/performer, mob/initiator, intent, list/params) + ..() src.intent = isnull(intent)? performer.a_intent : intent src.params = isnull(params)? list() : params diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 8813b1be798f..ee4a71eee143 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -1,3 +1,7 @@ +/proc/create_actor_progress_bar(datum/event_args/actor/e_args, goal_number, atom/target) + // todo: also show initiator the progress bar + return new /datum/progressbar(e_args.performer, goal_number, target) + /datum/progressbar var/goal = 1 var/image/bar diff --git a/code/game/atoms/action_feedback.dm b/code/game/atoms/action_feedback.dm index e3e2d4065a00..52a8466ca558 100644 --- a/code/game/atoms/action_feedback.dm +++ b/code/game/atoms/action_feedback.dm @@ -7,6 +7,7 @@ * * @params * * target - target atom + * * initiator - additional thing to show a message to as self * * hard_range - how far to display hard message; defaults to MESSAGE_RANGE_COMBAT_LOUD. if doesn't exist we use soft. * * soft_range - how far to display soft message; defaults to MESSAGE_RANGE_COMBAT_LOUD. overrides hard range if smaller. * * visible_hard - hard message. if doesn't exist we use soft message. @@ -14,11 +15,11 @@ * * visible_soft - soft message. * * audible_soft - what blind people hear when inside soft range (overridden by self and them if specified) * * visible_self - what we see - * * audible_self - override if self is blind. if null, defaults to 'self. + * * otherwise_self - override if self is blind. if null, defaults to 'self. * * visible_them - what the target see - * * audible_them - what the target sees if they are blind. if null, defaults to 'them'. + * * otherwise_them - what the target sees if they are blind. if null, defaults to 'them'. */ -/atom/proc/visible_action_feedback(atom/target, hard_range = MESSAGE_RANGE_COMBAT_LOUD, soft_range, visible_hard, audible_hard, audible_soft, visible_soft, visible_self, audible_self, visible_them, audible_them) +/atom/proc/visible_action_feedback(atom/target, atom/initiator, hard_range = MESSAGE_RANGE_COMBAT_LOUD, soft_range, visible_hard, audible_hard, audible_soft, visible_soft, visible_self, otherwise_self, visible_them, otherwise_them) var/list/viewing var/viewing_range = max(soft_range, hard_range) //! LEGACY @@ -30,6 +31,7 @@ //! end var/hard_visible = visible_hard || visible_soft var/hard_audible = audible_hard || audible_soft + // todo: all of this needs rewritten oh my god for(var/atom/movable/AM as anything in viewing) if(get_dist(AM, src) <= hard_range) if(ismob(AM)) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 64200c940e2f..5c7737d45a18 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -9,22 +9,22 @@ * * @return list(key = value) */ -/atom/proc/context_query(datum/event_args/actor/actor) +/atom/proc/context_query(datum/event_args/actor/e_args) . = list() - SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., actor) + SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_QUERY, ., e_args) /** * act on a context option * * @return TRUE / FALSE; TRUE if handled. */ -/atom/proc/context_act(datum/event_args/actor/actor, key) - if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, actor) & RAISE_ATOM_CONTEXT_ACT_HANDLED) +/atom/proc/context_act(datum/event_args/actor/e_args, key) + if(SEND_SIGNAL(src, COMSIG_ATOM_CONTEXT_ACT, key, e_args) & RAISE_ATOM_CONTEXT_ACT_HANDLED) return TRUE return FALSE -/atom/proc/context_menu(datum/event_args/actor/actor) +/atom/proc/context_menu(datum/event_args/actor/e_args) // admin proccall support - WRAP_MOB_TO_ACTOR_EVENT_ARGS(actor) + WRAP_MOB_TO_ACTOR_EVENT_ARGS(e_args) // todo: dynamically rebuild menu based on distance? #warn impl diff --git a/code/game/click/other_mobs.dm b/code/game/click/other_mobs.dm index c0ec19a8fb0e..0506362b2318 100644 --- a/code/game/click/other_mobs.dm +++ b/code/game/click/other_mobs.dm @@ -31,9 +31,9 @@ A.attack_hand(src) /// Return TRUE to cancel other attack hand effects that respect it. -// todo: /datum/event_args/clickchain +// todo: /datum/event_args/actor/clickchain /atom/proc/attack_hand(mob/user, list/params) - if(on_attack_hand(new /datum/event_args/clickchain(user, intent = user.a_intent, params = params))) + if(on_attack_hand(new /datum/event_args/actor/clickchain(user, intent = user.a_intent, params = params))) return TRUE . = _try_interact(user) @@ -45,7 +45,7 @@ * @params * * e_args - click data */ -/atom/proc/on_attack_hand(datum/event_args/clickchain/e_args) +/atom/proc/on_attack_hand(datum/event_args/actor/clickchain/e_args) return FALSE //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index d1473b5eea90..da150d2831b6 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -245,7 +245,7 @@ //? Attacks -/obj/on_attack_hand(datum/event_args/clickchain/e_args) +/obj/on_attack_hand(datum/event_args/actor/clickchain/e_args) . = ..() if(.) return @@ -410,27 +410,27 @@ //? Context -/obj/context_query(datum/event_args/actor/actor) +/obj/context_query(datum/event_args/actor/e_args) . = ..() - if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(actor.performer)) + if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(e_args.performer)) .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null, null, MOBILITY_CAN_USE) -/obj/context_act(datum/event_args/actor/actor, key) +/obj/context_act(datum/event_args/actor/e_args, key) if(key == "obj_cell_slot") if(isnull(obj_cell_slot.cell)) - actor.performer.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) + e_args.performer.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) return TRUE - if(!obj_cell_slot.interaction_active(actor.performer)) + if(!obj_cell_slot.interaction_active(e_args.performer)) return TRUE - actor.performer.visible_action_feedback( + e_args.visible_feedback( target = src, hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[actor.performer] removes the cell from [src]."), + visible_hard = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), - visible_self = SPAN_NOTICE("You remove the cell from [src]."), + otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(actor.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") - actor.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(actor.performer)) + log_construction(e_args.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) return TRUE return ..() diff --git a/code/modules/logging/logging.dm b/code/modules/logging/logging.dm index ef0a16a906b8..1df25668753f 100644 --- a/code/modules/logging/logging.dm +++ b/code/modules/logging/logging.dm @@ -31,8 +31,8 @@ /** * log click - context menu */ -/proc/log_click_context(datum/event_args/actor/actor, atom/target, message) - log_click("CONTEXT: [key_name(actor.initiator)][actor.performer != actor.initiator? " via [key_name(actor.performer)]" : ""] -> [target] [AUDIT_COORD(target)]: [message]") +/proc/log_click_context(datum/event_args/actor/e_args, atom/target, message) + log_click("CONTEXT: [key_name(e_args.initiator)][e_args.performer != e_args.initiator? " via [key_name(e_args.performer)]" : ""] -> [target] [AUDIT_COORD(target)]: [message]") /** * Log stack crafting diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 9676a181d33f..d27205791841 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -1,7 +1,7 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -#warn use /datum/event_args/actor/actor +#warn use /datum/event_args/actor/e_args /** * ? Atom Tool API From 100eadbb3ca0f9fbad9b25e0a8a935308b92606a Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:42:55 -0700 Subject: [PATCH 10/33] now comes the hard part --- .../dcs/signals/signals_atom/tool_system.dm | 8 +- code/game/objects/objs.dm | 6 +- code/modules/tools/_tool_system.dm | 97 ++++++++++--------- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm index 5c337e706b4f..cc91e399d4e3 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm @@ -4,7 +4,7 @@ /// from base of _tool_act: (I, user, function, flags, hint) where I = item, user = user, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system /// return CLICKCHAIN_COMPONENT_SIGNAL_HANDLED to abort normal tool_act handling. #define COMSIG_ATOM_TOOL_ACT "tool_act" -/// from base of dynamic_tool_functions: (functions, I, user) where I = item, user = user -#define COMSIG_ATOM_TOOL_QUERY "tool_query" - -#warn a way to return iamges +/// from base of dynamic_tool_functions: (I, user, functions, hint_images) where I = item, user = user. +/// inject by merging into functions, and associating hints to images in hint_images +/// remember to use merge_double_lazy_assoc_list() to merge function lists! +#define COMSIG_ATOM_TOOL_FUNCTIONS "tool_functions" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index da150d2831b6..fab8e51bf413 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -424,9 +424,9 @@ return TRUE e_args.visible_feedback( target = src, - hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), - audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), + audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) log_construction(e_args.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index d27205791841..b8afa9b5c5bd 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -17,7 +17,7 @@ * * intended api for static tool usage: * - * - override necessary _act for that tool type + * * override necessary _act for that tool type * .../function_act(...) * if(use_(...)) * # success code @@ -26,11 +26,11 @@ * return TRUE // halt attack chain * * intended api for dynamic tool usage: - * - override dynamic_tool_functions() to return the functions and minimal qualities for a user - * - override dynamic_tool_act() if needed, otherwise it will simply go into tool_act - * - override dynamic_tool_image() to return the image to render for a specific tool function for radials - * - realistically, you just need to override dynamic_tool_functions. - * - if you don't override dynamic_tool_image you are a lemming and it'll probabl be ugly. + * * override dynamic_tool_functions() to return the functions and minimal qualities for a user + * * override dynamic_tool_act() if needed, otherwise it will simply go into tool_act + * * override dynamic_tool_image() to return the image to render for a specific tool function for radials + * * realistically, you just need to override dynamic_tool_functions. + * * if you don't override dynamic_tool_image you are a lemming and it'll probabl be ugly. * * It's That Simple (tm)! * @@ -46,12 +46,12 @@ * warning: this proc is not necessarily called only within clickcode. * * @params - * - I - the item - * - user - the user - * - clickchain_flags - the clickchain flags given - * - function - forced function - used in automation - * - hint - forced hint - used in automation - * - reachability_check - a callback used for reachability checks. if none, defaults to mob.Reachability when in clickcode, can always reach otherwise. + * * I - the item + * * user - the user + * * clickchain_flags - the clickchain flags given + * * function - forced function - used in automation + * * hint - forced hint - used in automation + * * reachability_check - a callback used for reachability checks. if none, defaults to mob.Reachability when in clickcode, can always reach otherwise. */ /atom/proc/tool_interaction(obj/item/I, mob/user, clickchain_flags, function, hint, datum/callback/reachability_check) SHOULD_NOT_OVERRIDE(TRUE) @@ -171,19 +171,19 @@ * primary proc to be used when calling an interaction with a tool with an atom * * everything in this proc and procs it calls: - * - should not verify that the item is on the user - * - can, but doesn't need to verify that the item has the function in question (assumed it does) - * - should not require a user to run (do not runtime without user) - * - should handle functions with helpers in tihs file whenever possibl + * * should not verify that the item is on the user + * * can, but doesn't need to verify that the item has the function in question (assumed it does) + * * should not require a user to run (do not runtime without user) + * * should handle functions with helpers in tihs file whenever possibl * * default behaviour: route the call to _act, which interrupts the melee attack chain if it returns TRUE. * * @params - * - I - the tool in question - * - user - the user in question, if they exist - * - function - the tool function used - * - flags - tool operation flags - * - hint - the operation hint, if the calling system is the dynamic tool system. + * * I - the tool in question + * * user - the user in question, if they exist + * * function - the tool function used + * * flags - tool operation flags + * * hint - the operation hint, if the calling system is the dynamic tool system. */ /atom/proc/tool_act(obj/item/I, mob/user, function, flags, hint) switch(function) @@ -207,13 +207,13 @@ * standard use tool * * @params - * - function - tool function - * - I - the tool - * - user - the person using it - * - flags - tool operation flags - * - delay - how long it'll take to use the tool - * - cost - optional; cost multiplier to the default cost of 1 per second. - * - usage - optional; usage flags for tool speed/quality checks. + * * function - tool function + * * I - the tool + * * user - the person using it + * * flags - tool operation flags + * * delay - how long it'll take to use the tool + * * cost - optional; cost multiplier to the default cost of 1 per second. + * * usage - optional; usage flags for tool speed/quality checks. */ /atom/proc/use_tool_standard(function, obj/item/I, mob/user, flags, delay, cost, usage) return use_tool(function, I, user, flags, delay, cost, usage) @@ -222,14 +222,14 @@ * primary proc called by wrappers to use a tool on us * * @params - * - function - tool function - * - I - the tool - * - user - the person using it - * - flags - tool operation flags - * - delay - how long it'll take to use the tool - * - cost - optional; cost multiplier to the default cost of 1 per second. - * - usage - optional; usage flags for tool speed/quality checks. - * - volume - optional; volume override + * * function - tool function + * * I - the tool + * * user - the person using it + * * flags - tool operation flags + * * delay - how long it'll take to use the tool + * * cost - optional; cost multiplier to the default cost of 1 per second. + * * usage - optional; usage flags for tool speed/quality checks. + * * volume - optional; volume override */ /atom/proc/use_tool(function, obj/item/I, mob/user, flags, delay, cost = 1, usage, volume) SHOULD_NOT_OVERRIDE(TRUE) @@ -266,12 +266,13 @@ * if you're caching your own list, make sure to return cache.Copy()! * * @params - * - I - the tool used, if any - * - user - the user, if any + * * I - the tool used, if any + * * user - the user, if any + * * hint_images - allows us to immediately associate hints to specific images without calling dynamic_tool_image after. usually not what you want. */ -/atom/proc/dynamic_tool_functions(obj/item/I, mob/user) - // todo: signal - return list() +/atom/proc/dynamic_tool_functions(obj/item/I, mob/user, list/hint_images = list()) + . = list() + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, user, ., hint_images) /atom/proc/_dynamic_tool_act(obj/item/I, mob/user, function, flags, hint) PRIVATE_PROC(TRUE) @@ -287,11 +288,11 @@ * this must return a set of clickchain flags! * * @params - * - I - the tool used - * - user - the user, if any - * - function - the tool behaviour used - * - flags - tool operation flags - * - hint - the hint of what operation to do + * * I - the tool used + * * user - the user, if any + * * function - the tool behaviour used + * * flags - tool operation flags + * * hint - the hint of what operation to do */ /atom/proc/dynamic_tool_act(obj/item/I, mob/user, function, flags, hint) return tool_act(I, user, function, flags, hint) @@ -302,8 +303,8 @@ * WARNING: If you use tool **and** hint, you need to implement a hintless, or return to base to use the default. * * @params - * - function - the tool behaviour - * - hint - the context provided when you want to implement multiple actions for a tool + * * function - the tool behaviour + * * hint - the context provided when you want to implement multiple actions for a tool */ /atom/proc/dynamic_tool_image(function, hint) return dyntool_image_neutral(function) From 18b6e47e490aa5b7b1c561048594b710779dc93b Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:50:38 -0700 Subject: [PATCH 11/33] item replacements --- .../dcs/signals/signals_atom/tool_system.dm | 4 +- .../game/machinery/_machinery_construction.dm | 2 +- code/game/machinery/misc/bioscan_antenna.dm | 2 +- code/game/objects/items/tools/switchtool.dm | 4 +- code/game/objects/items/tools/weldingtool.dm | 4 +- code/game/objects/objs.dm | 2 +- code/game/objects/structures/window.dm | 2 +- code/modules/fishing/aquarium/aquarium.dm | 2 +- .../projectiles/ammunition/ammo_casing.dm | 2 +- code/modules/sculpting/sculpting_block.dm | 2 +- code/modules/tools/_tool_system.dm | 14 ++--- code/modules/tools/items.dm | 60 +++++++++---------- 12 files changed, 50 insertions(+), 50 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm index cc91e399d4e3..7dd639e4f162 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm @@ -1,10 +1,10 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -/// from base of _tool_act: (I, user, function, flags, hint) where I = item, user = user, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system +/// from base of _tool_act: (I, user, function, flags, hint) where I = item, e_args = clickchain data, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system /// return CLICKCHAIN_COMPONENT_SIGNAL_HANDLED to abort normal tool_act handling. #define COMSIG_ATOM_TOOL_ACT "tool_act" -/// from base of dynamic_tool_functions: (I, user, functions, hint_images) where I = item, user = user. +/// from base of dynamic_tool_functions: (I, datum/event_args/actor/clickchain/e_args, functions, hint_images) where I = item, e_args = clickchain data. /// inject by merging into functions, and associating hints to images in hint_images /// remember to use merge_double_lazy_assoc_list() to merge function lists! #define COMSIG_ATOM_TOOL_FUNCTIONS "tool_functions" diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index b2e8dc5afae6..52d220084f4a 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -1,7 +1,7 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -/obj/machinery/dynamic_tool_functions(obj/item/I, mob/user) +/obj/machinery/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() if(tool_deconstruct && !isnull(default_deconstruct) && panel_open) LAZYADD(.[tool_panel], "deconstruct") diff --git a/code/game/machinery/misc/bioscan_antenna.dm b/code/game/machinery/misc/bioscan_antenna.dm index e7d0c52c06d8..49dfa4460b93 100644 --- a/code/game/machinery/misc/bioscan_antenna.dm +++ b/code/game/machinery/misc/bioscan_antenna.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(bioscan_antenna_list) user.visible_message(SPAN_NOTICE("[user] reprograms the network on [src]."), range = MESSAGE_RANGE_CONFIGURATION) change_network(new_network) -/obj/machinery/bioscan_antenna/dynamic_tool_functions(obj/item/I, mob/user) +/obj/machinery/bioscan_antenna/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() if(network_mutable) .[TOOL_MULTITOOL] = "change network" diff --git a/code/game/objects/items/tools/switchtool.dm b/code/game/objects/items/tools/switchtool.dm index 64a57623544d..e1420f552939 100644 --- a/code/game/objects/items/tools/switchtool.dm +++ b/code/game/objects/items/tools/switchtool.dm @@ -256,11 +256,11 @@ return "shield" //? tool redirection -/obj/item/switchtool/tool_check(function, mob/user, atom/target, flags, usage) +/obj/item/switchtool/tool_check(function, datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) return (function in tool_functions)? tool_quality : null //? tool redirection -/obj/item/switchtool/tool_query(mob/user, atom/target, flags, usage) +/obj/item/switchtool/tool_query(datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) . = list() for(var/i in tool_functions) .[i] = tool_quality diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 04609b2b242e..7c297035d35c 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -162,7 +162,7 @@ /obj/item/weldingtool/proc/get_max_fuel() return max_fuel -/obj/item/weldingtool/using_as_tool(function, flags, mob/user, atom/target, time, cost, usage) +/obj/item/weldingtool/using_as_tool(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage) . = ..() if(!. || function != TOOL_WELDER) return @@ -175,7 +175,7 @@ user.action_feedback(SPAN_WARNING("[src] doesn't have enough fuel left to do that!"), target) return FALSE -/obj/item/weldingtool/used_as_tool(function, flags, mob/user, atom/target, time, cost, usage, success) +/obj/item/weldingtool/used_as_tool(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success) . = ..() if(!.) return diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index fab8e51bf413..bf07b65cb191 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -548,7 +548,7 @@ //? Tool System -/obj/dynamic_tool_functions(obj/item/I, mob/user) +/obj/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(user)) return ..() . = list() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index f1d095eedbab..d28d8f18e3d6 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -507,7 +507,7 @@ deconstruct(ATOM_DECONSTRUCT_DISASSEMBLED) -/obj/structure/window/dynamic_tool_functions(obj/item/I, mob/user) +/obj/structure/window/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) if (construction_state == WINDOW_STATE_UNSECURED) . = list( TOOL_SCREWDRIVER = TOOL_HINT_SCREWING_WINDOW_FRAME, diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 156c2f2fefc5..3bbfc8c2e7cc 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -118,7 +118,7 @@ update_appearance() return TRUE -/obj/structure/aquarium/dynamic_tool_functions(obj/item/I, mob/user) +/obj/structure/aquarium/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = ..() if(allow_unanchor) .[TOOL_WRENCH] = anchored? "anchor" : "unanchor" diff --git a/code/modules/projectiles/ammunition/ammo_casing.dm b/code/modules/projectiles/ammunition/ammo_casing.dm index af3afd358323..528ad249b4b9 100644 --- a/code/modules/projectiles/ammunition/ammo_casing.dm +++ b/code/modules/projectiles/ammunition/ammo_casing.dm @@ -62,7 +62,7 @@ user.action_feedback(SPAN_NOTICE("You inscribe [label_text] into \the [initial(stored.name)]."), src) stored.name = "[initial(stored.name)] (\"[label_text]\")" -/obj/item/ammo_casing/dynamic_tool_functions(obj/item/I, mob/user) +/obj/item/ammo_casing/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list( TOOL_SCREWDRIVER = list( "etch" diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 899e34465699..dec5e18c663a 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -183,7 +183,7 @@ . = ..() material.place_sheet(drop_location(), 10) -/obj/structure/sculpting_block/dynamic_tool_functions(obj/item/I, mob/user) +/obj/structure/sculpting_block/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() .[TOOL_WRENCH] = anchored? "unanchor" : "anchor" .[TOOL_WELDER] = "deconstruct" diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index b8afa9b5c5bd..458c9b871713 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -270,16 +270,16 @@ * * user - the user, if any * * hint_images - allows us to immediately associate hints to specific images without calling dynamic_tool_image after. usually not what you want. */ -/atom/proc/dynamic_tool_functions(obj/item/I, mob/user, list/hint_images = list()) +/atom/proc/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, user, ., hint_images) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, e_args, ., hint_images) -/atom/proc/_dynamic_tool_act(obj/item/I, mob/user, function, flags, hint) +/atom/proc/_dynamic_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) PRIVATE_PROC(TRUE) SHOULD_NOT_OVERRIDE(TRUE) flags |= TOOL_OP_DYNAMIC - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, user, function, flags, hint) - return dynamic_tool_act(I, user, function, flags, hint) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, e_args, function, flags, hint) + return dynamic_tool_act(I, e_args, function, flags, hint) /** * called when we are acted on by the dynamic tool system @@ -294,8 +294,8 @@ * * flags - tool operation flags * * hint - the hint of what operation to do */ -/atom/proc/dynamic_tool_act(obj/item/I, mob/user, function, flags, hint) - return tool_act(I, user, function, flags, hint) +/atom/proc/dynamic_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) + return tool_act(I, e_args, function, flags, hint) /** * builds the image used for the radial icon diff --git a/code/modules/tools/items.dm b/code/modules/tools/items.dm index 3163f8aea321..a0c0bd467781 100644 --- a/code/modules/tools/items.dm +++ b/code/modules/tools/items.dm @@ -31,12 +31,12 @@ * that's where things like skill checks are done. * * @params - * - user - person using tool, can be null + * - e_args - person using tool, can be null * - target - atom being used on, can be null * - flags - tool operation flags * - usage - what we're being used for, bitfield */ -/obj/item/proc/tool_query(mob/user, atom/target, flags, usage) +/obj/item/proc/tool_query(datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) RETURN_TYPE(/list) . = list() // if normal tool behavior @@ -46,7 +46,7 @@ if(tool_override) . |= tool_override for(var/i in .) - .[i] = tool_quality_transform(.[i], user, target, flags, usage) + .[i] = tool_quality_transform(.[i], e_args, target, flags, usage) /** * checks for a tool function @@ -57,16 +57,16 @@ * * @params * - function - tool function enum - * - user - person using tool, if any + * - e_args - person using tool, if any * - target - atom tool being used on, if any * - flags - tool operation flags * - usage - what we're being used for, bitfield */ -/obj/item/proc/tool_check(function, mob/user, atom/target, flags, usage) +/obj/item/proc/tool_check(function, datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) ASSERT(function) if(tool_override && tool_override[function]) - return tool_quality_transform(tool_override[function], user, target, flags, usage) - return (function == tool_behaviour)? tool_quality_transform(tool_quality, user, target, flags, usage) : null + return tool_quality_transform(tool_override[function], e_args, target, flags, usage) + return (function == tool_behaviour)? tool_quality_transform(tool_quality, e_args, target, flags, usage) : null /** * transforms tool quality according to a user's skill @@ -74,12 +74,12 @@ * @params * - original - original quality * - * - user - user, if any + * - e_args - actor data, if any * - target - target, if any * - flags - tool operation flags * - usage - what we're being used for, bitfield */ -/obj/item/proc/tool_quality_transform(original, user, target, flags, usage) +/obj/item/proc/tool_quality_transform(original, datum/event_args/actor/clickchain/e_args, target, flags, usage) return original /** @@ -91,12 +91,12 @@ * * @params * - function - tool function enum - * - user - person using tool, if any + * - e_args - actor data for person using tool, if any * - target - atom tool being used on, if any * - flags - tool operation flags * - usage - what we're being used for, bitfield */ -/obj/item/proc/tool_speed(function, mob/user, atom/target, flags, usage) +/obj/item/proc/tool_speed(function, datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) SHOULD_CALL_PARENT(TRUE) return (flags & TOOL_OP_INSTANT)? 0 : tool_speed @@ -116,14 +116,14 @@ * * @params * - function - tool function enum; if null, defaults to static tool behaviour. - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - flags - tool operation flags * - usage - what we're being used for */ -/obj/item/proc/tool_quality(function = tool_behaviour(), mob/user, atom/target, flags, usage) +/obj/item/proc/tool_quality(function = tool_behaviour(), datum/event_args/actor/clickchain/e_args, atom/target, flags, usage) // this is just a wrapper, the only difference is function is automatically provided. - return tool_check(function, user, target, flags, usage) + return tool_check(function, e_args, target, flags, usage) /** * called when we start being used as a tool @@ -132,13 +132,13 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - approximated duration of the action in deciseconds * - cost - cost multiplier * - usage - usage flags, if any */ -/obj/item/proc/using_as_tool(function, flags, mob/user, atom/target, time, cost, usage) +/obj/item/proc/using_as_tool(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage) SHOULD_CALL_PARENT(TRUE) return TRUE @@ -149,14 +149,14 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - duration of the action in deciseconds * - cost - cost multiplier * - usage - usage flags, if any * - success - was it successful? */ -/obj/item/proc/used_as_tool(function, flags, mob/user, atom/target, time, cost, usage, success) +/obj/item/proc/used_as_tool(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success) SHOULD_CALL_PARENT(TRUE) return TRUE @@ -166,17 +166,17 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - duration of the action in deciseconds * - cost - cost multiplier * - usage - usage flags, if any * - volume - volume for sounds */ -/obj/item/proc/tool_feedback_start(function, flags, mob/user, atom/target, time, cost, usage, volume) +/obj/item/proc/tool_feedback_start(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, volume) SHOULD_CALL_PARENT(TRUE) if(!(flags & TOOL_OP_NO_STANDARD_AUDIO)) - standard_tool_feedback_sound(function, flags, user, target, time, cost, usage, volume) + standard_tool_feedback_sound(function, flags, e_args, target, time, cost, usage, volume) /** * standard feedback for ending a tool usage @@ -184,7 +184,7 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - duration of the action in deciseconds * - cost - cost multiplier @@ -192,10 +192,10 @@ * - success - was it successful? * - volume - volume for sounds */ -/obj/item/proc/tool_feedback_end(function, flags, mob/user, atom/target, time, cost, usage, success, volume) +/obj/item/proc/tool_feedback_end(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success, volume) SHOULD_CALL_PARENT(TRUE) if(!(flags & TOOL_OP_NO_STANDARD_AUDIO)) - standard_tool_feedback_sound(function, flags, user, target, time, cost, usage, success) + standard_tool_feedback_sound(function, flags, e_args, target, time, cost, usage, success) /** * plays tool sound @@ -203,7 +203,7 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - duration of the action in deciseconds * - cost - cost multiplier @@ -211,14 +211,14 @@ * - success - was it successful? null if we're just starting * - volume - volume for sounds */ -/obj/item/proc/standard_tool_feedback_sound(function, flags, mob/user, atom/target, time, cost, usage, success, volume = 50) +/obj/item/proc/standard_tool_feedback_sound(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success, volume = 50) if(isnull(success)) // starting - playsound(src, tool_sound(function, flags, user, target, time, cost, usage, success), volume, TRUE) + playsound(src, tool_sound(function, flags, e_args, target, time, cost, usage, success), volume, TRUE) else // finishing if(time >= MIN_TOOL_SOUND_DELAY) - playsound(src, tool_sound(function, flags, user, target, time, cost, usage, success), volume, TRUE) + playsound(src, tool_sound(function, flags, e_args, target, time, cost, usage, success), volume, TRUE) /** * gets sound to play on tool usage @@ -226,14 +226,14 @@ * @params * - function - tool function enum * - flags - tool operation flags - * - user - person using tool, if any + * - e_args - actor data of who's using the tool * - target - atom tool being used on, if any * - time - duration of the action in deciseconds * - cost - cost multiplier * - usage - usage flags, if any * - success - was it successful? null if we're just starting */ -/obj/item/proc/tool_sound(function, flags, mob/user, atom/target, time, cost, usage, success) +/obj/item/proc/tool_sound(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success) if(tool_sound) return tool_sound // return default From b9be9512e164ab8fa05f2ed93e9181b5d7efc414 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:52:05 -0700 Subject: [PATCH 12/33] mistakes --- code/datums/event_args/actor.dm | 10 ++++++++-- code/game/objects/items/tools/weldingtool.dm | 4 ++-- code/game/objects/objs.dm | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/code/datums/event_args/actor.dm b/code/datums/event_args/actor.dm index c3c975f28fed..ea76526683f5 100644 --- a/code/datums/event_args/actor.dm +++ b/code/datums/event_args/actor.dm @@ -11,14 +11,17 @@ src.performer = performer src.initiator = isnull(initiator)? performer : initiator -/datum/event_args/actor/proc/chat_feedback(atom/target, msg) +/datum/event_args/actor/proc/chat_feedback(msg, atom/target) performer.action_feedback(msg, target) initiator.action_feedback(msg, target) -/datum/event_args/actor/proc/bubble_feedback(atom/target, msg) +/datum/event_args/actor/proc/bubble_feedback(msg, atom/target) performer.bubble_action_feedback(msg, target) initiator.bubble_action_feedback(msg, target) +/** + * It is highly recommended to use named parameters with this. + */ /datum/event_args/actor/proc/visible_feedback(atom/target, range, visible, audible, visible_self, otherwise_self, visible_them, otherwise_them) performer.visible_action_feedback( target = target, @@ -32,6 +35,9 @@ otherwise_them = otherwise_them, ) +/** + * It is highly recommended to use named parameters with this. + */ /datum/event_args/actor/proc/visible_dual_feedback(atom/target, range_hard, range_soft, visible_hard, visible_soft, audible_hard, audible_soft, visible_self, otherwise_self, visible_them, otherwise_them) performer.visible_action_feedback( target = target, diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 7c297035d35c..56273803514e 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -167,12 +167,12 @@ if(!. || function != TOOL_WELDER) return if(!isOn()) - user.action_feedback(SPAN_WARNING("[src] must be on to be used to weld!"), target) + e_args.chat_feedback(SPAN_WARNING("[src] must be on to be used to weld!"), target) return FALSE // floor var/computed = round(cost * time * TOOL_WELDING_FUEL_PER_DS) if(get_fuel() < computed) - user.action_feedback(SPAN_WARNING("[src] doesn't have enough fuel left to do that!"), target) + e_args.chat_feedback(SPAN_WARNING("[src] doesn't have enough fuel left to do that!"), target) return FALSE /obj/item/weldingtool/used_as_tool(function, flags, datum/event_args/actor/clickchain/e_args, atom/target, time, cost, usage, success) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index bf07b65cb191..87c3dd3894da 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -549,7 +549,7 @@ //? Tool System /obj/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) - if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(user)) + if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(e_args.performer)) return ..() . = list() .[obj_cell_slot.remove_tool_behavior] = "remove cell" From 9042bd3c1151a8c07611c18f941db8737d99a144 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:53:45 -0700 Subject: [PATCH 13/33] event args --- code/game/machinery/misc/bioscan_antenna.dm | 2 +- code/game/machinery/pipe/construction.dm | 4 +- code/game/objects/structures/window.dm | 6 +- .../machinery/components/component.dm | 2 +- code/modules/fishing/aquarium/aquarium.dm | 2 +- .../projectiles/ammunition/ammo_casing.dm | 2 +- code/modules/sculpting/sculpting_block.dm | 4 +- code/modules/tools/_tool_system.dm | 2 +- code/modules/tools/wrappers.dm | 56 +++++++++---------- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/code/game/machinery/misc/bioscan_antenna.dm b/code/game/machinery/misc/bioscan_antenna.dm index 49dfa4460b93..d82ac73fe610 100644 --- a/code/game/machinery/misc/bioscan_antenna.dm +++ b/code/game/machinery/misc/bioscan_antenna.dm @@ -34,7 +34,7 @@ GLOBAL_LIST_EMPTY(bioscan_antenna_list) change_network(null) return ..() -/obj/machinery/bioscan_antenna/multitool_act(obj/item/I, mob/user, flags, hint) +/obj/machinery/bioscan_antenna/multitool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!network_mutable) return ..() . = TRUE diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index ac6b4eb4122b..3d7e81b2236d 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -180,7 +180,7 @@ Buildable meters return wrench_act(W, user) return ..() -/obj/item/pipe/wrench_act(obj/item/I, mob/user, flags, hint) +/obj/item/pipe/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!isturf(loc)) return TRUE @@ -269,7 +269,7 @@ Buildable meters return wrench_act(W, user) return ..() -/obj/item/pipe_meter/wrench_act(obj/item/I, mob/user, flags, hint) +/obj/item/pipe_meter/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) var/obj/machinery/atmospherics/pipe/pipe for(var/obj/machinery/atmospherics/pipe/P in loc) if(P.piping_layer == piping_layer) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d28d8f18e3d6..3201b468e1c0 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -453,7 +453,7 @@ new shardtype(drop_location()) -/obj/structure/window/screwdriver_act(obj/item/I, mob/user, flags, hint) +/obj/structure/window/screwdriver_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if (construction_state == WINDOW_STATE_UNSECURED || construction_state == WINDOW_STATE_SCREWED_TO_FLOOR || !considered_reinforced) @@ -483,7 +483,7 @@ construction_state = unsecuring ? WINDOW_STATE_CROWBRARED_IN : WINDOW_STATE_SECURED_TO_FRAME -/obj/structure/window/crowbar_act(obj/item/I, mob/user, flags, hint) +/obj/structure/window/crowbar_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if (!considered_reinforced) return @@ -496,7 +496,7 @@ construction_state = unsecuring ? WINDOW_STATE_SCREWED_TO_FLOOR : WINDOW_STATE_CROWBRARED_IN -/obj/structure/window/wrench_act(obj/item/I, mob/user, flags, hint) +/obj/structure/window/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if (construction_state != WINDOW_STATE_UNSECURED) user.action_feedback(SPAN_WARNING("[src] has to be entirely unfastened from the floor before you can disasemble it!")) diff --git a/code/modules/atmospherics/machinery/components/component.dm b/code/modules/atmospherics/machinery/components/component.dm index e2ffac8c1685..860568d158aa 100644 --- a/code/modules/atmospherics/machinery/components/component.dm +++ b/code/modules/atmospherics/machinery/components/component.dm @@ -125,7 +125,7 @@ ui = new(user, src, tgui_interface) ui.open() -/obj/machinery/atmospherics/component/multitool_act(obj/item/I, mob/user, flags, hint) +/obj/machinery/atmospherics/component/multitool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = ..() if(.) return diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 3bbfc8c2e7cc..bf1eb3239a06 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -129,7 +129,7 @@ return anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH) return ..() -/obj/structure/aquarium/wrench_act(obj/item/I, mob/user, flags, hint) +/obj/structure/aquarium/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!allow_unanchor) return ..() if(use_wrench(I, user, delay = 4 SECONDS)) diff --git a/code/modules/projectiles/ammunition/ammo_casing.dm b/code/modules/projectiles/ammunition/ammo_casing.dm index 528ad249b4b9..97f70548728e 100644 --- a/code/modules/projectiles/ammunition/ammo_casing.dm +++ b/code/modules/projectiles/ammunition/ammo_casing.dm @@ -48,7 +48,7 @@ setDir(pick(GLOB.cardinal)) //spin spent casings update_icon() -/obj/item/ammo_casing/screwdriver_act(obj/item/I, mob/user, flags, hint) +/obj/item/ammo_casing/screwdriver_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if(!stored) user.action_feedback(SPAN_WARNING("There is no bullet in [src] to inscribe."), src) diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index dec5e18c663a..fcbd5cd235f1 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -128,7 +128,7 @@ initiate_sculpting(user, tool = I) return CLICKCHAIN_DO_NOT_PROPAGATE -/obj/structure/sculpting_block/wrench_act(obj/item/I, mob/user, flags, hint) +/obj/structure/sculpting_block/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = ..() if(.) return @@ -153,7 +153,7 @@ set_anchored(!anchored) return TRUE -/obj/structure/sculpting_block/welder_act(obj/item/I, mob/user, flags, hint) +/obj/structure/sculpting_block/welder_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = ..() if(.) return diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 458c9b871713..0d5a172a2338 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -216,7 +216,7 @@ * * usage - optional; usage flags for tool speed/quality checks. */ /atom/proc/use_tool_standard(function, obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool(function, I, user, flags, delay, cost, usage) + return use_tool(function, I, e_args, flags, delay, cost, usage) /** * primary proc called by wrappers to use a tool on us diff --git a/code/modules/tools/wrappers.dm b/code/modules/tools/wrappers.dm index ab785bd05248..0d8535103e99 100644 --- a/code/modules/tools/wrappers.dm +++ b/code/modules/tools/wrappers.dm @@ -12,7 +12,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/crowbar_act(obj/item/I, mob/user, flags, hint) +/atom/proc/crowbar_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -24,14 +24,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_crowbar(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_CROWBAR, I, user, flags, delay, cost, usage) +/atom/proc/use_crowbar(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_CROWBAR, I, e_args, flags, delay, cost, usage) /** * Called when a wrench is used on us. @@ -42,7 +42,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/wrench_act(obj/item/I, mob/user, flags, hint) +/atom/proc/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -54,14 +54,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_wrench(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_WRENCH, I, user, flags, delay, cost, usage) +/atom/proc/use_wrench(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_WRENCH, I, e_args, flags, delay, cost, usage) /** * Called when a welder is used on us. @@ -72,7 +72,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/welder_act(obj/item/I, mob/user, flags, hint) +/atom/proc/welder_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -84,14 +84,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_welder(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_WELDER, I, user, flags, delay, cost, usage) +/atom/proc/use_welder(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_WELDER, I, e_args, flags, delay, cost, usage) /** * Called when a pair of wirecutters is used on us. @@ -102,7 +102,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/wirecutter_act(obj/item/I, mob/user, flags, hint) +/atom/proc/wirecutter_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -114,14 +114,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_wirecutter(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_WIRECUTTER, I, user, flags, delay, cost, usage) +/atom/proc/use_wirecutter(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_WIRECUTTER, I, e_args, flags, delay, cost, usage) /** * Called when a screwdriver is used on us. @@ -132,7 +132,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/screwdriver_act(obj/item/I, mob/user, flags, hint) +/atom/proc/screwdriver_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -144,14 +144,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_screwdriver(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_SCREWDRIVER, I, user, flags, delay, cost, usage) +/atom/proc/use_screwdriver(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_SCREWDRIVER, I, e_args, flags, delay, cost, usage) /** * Called when a analyzer is used on us. @@ -162,7 +162,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/analyzer_act(obj/item/I, mob/user, flags, hint) +/atom/proc/analyzer_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -174,14 +174,14 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_analyzer(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_ANALYZER, I, user, flags, delay, cost, usage) +/atom/proc/use_analyzer(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_ANALYZER, I, e_args, flags, delay, cost, usage) /** @@ -193,7 +193,7 @@ * - flags - tool operation flags * - hint - operation hint, if using dynamic tool system */ -/atom/proc/multitool_act(obj/item/I, mob/user, flags, hint) +/atom/proc/multitool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) return FALSE /** @@ -205,12 +205,12 @@ * * @params * - I - the item - * - user - the user, if any + * - e_args - clickchain data, if any * - flags - tool operation flags * - delay - how long this should take * - cost - multiplier for cost, standard tool "cost" is 1 per second of usage. * - usage - usage flags for skill system checks. */ -/atom/proc/use_multitool(obj/item/I, mob/user, flags, delay, cost, usage) - return use_tool_standard(TOOL_MULTITOOL, I, user, flags, delay, cost, usage) +/atom/proc/use_multitool(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) + return use_tool_standard(TOOL_MULTITOOL, I, e_args, flags, delay, cost, usage) From 1eb3605cba8392997e633fcbb999096e94ec9533 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:56:22 -0700 Subject: [PATCH 14/33] now to deal with the compile errors --- code/game/click/items.dm | 2 +- .../game/machinery/_machinery_construction.dm | 2 +- code/game/objects/objs.dm | 2 +- code/modules/tools/_tool_system.dm | 30 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/code/game/click/items.dm b/code/game/click/items.dm index c703faac0e45..eb53a2568388 100644 --- a/code/game/click/items.dm +++ b/code/game/click/items.dm @@ -54,7 +54,7 @@ // are we on harm intent? if so, lol no if(user && (user.a_intent == INTENT_HARM)) return NONE - return target.tool_interaction(src, user, clickchain_flags | CLICKCHAIN_TOOL_ACT) + return target.tool_interaction(src, new /datum/event_args/actor/clickchain(user, params = params), clickchain_flags | CLICKCHAIN_TOOL_ACT) /** * called at the start of melee attack chains diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index 52d220084f4a..e05cb95a0f03 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -19,7 +19,7 @@ return dyntool_image_backward(function) return ..() -/obj/machinery/tool_act(obj/item/I, mob/user, function, flags, hint) +/obj/machinery/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) if(INTERACTING_WITH_FOR(user, src, INTERACTING_FOR_CONSTRUCTION)) return CLICKCHAIN_DO_NOT_PROPAGATE START_INTERACTING_WITH(user, src, INTERACTING_FOR_CONSTRUCTION) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 87c3dd3894da..25b67fc8a811 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -560,7 +560,7 @@ return dyntool_image_backward(function) return ..() -/obj/tool_act(obj/item/I, mob/user, function, flags, hint) +/obj/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(user)) return ..() if(isnull(obj_cell_slot.cell)) diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 0d5a172a2338..48d1d1548039 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -53,11 +53,11 @@ * * hint - forced hint - used in automation * * reachability_check - a callback used for reachability checks. if none, defaults to mob.Reachability when in clickcode, can always reach otherwise. */ -/atom/proc/tool_interaction(obj/item/I, mob/user, clickchain_flags, function, hint, datum/callback/reachability_check) +/atom/proc/tool_interaction(obj/item/I, datum/event_args/actor/clickchain/e_args, clickchain_flags, function, hint, datum/callback/reachability_check) SHOULD_NOT_OVERRIDE(TRUE) return _tool_interaction_entrypoint(I, user, clickchain_flags, function, hint, reachability_check) -/atom/proc/_tool_interaction_entrypoint(obj/item/provided_item, mob/user, clickchain_flags, function, hint, datum/callback/reachability_check) +/atom/proc/_tool_interaction_entrypoint(obj/item/provided_item, datum/event_args/actor/clickchain/e_args, clickchain_flags, function, hint, datum/callback/reachability_check) SHOULD_NOT_OVERRIDE(TRUE) PRIVATE_PROC(TRUE) if(isnull(reachability_check)) @@ -160,12 +160,12 @@ return NONE //! Primary Tool API -/atom/proc/_tool_act(obj/item/I, mob/user, function, flags, hint) +/atom/proc/_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) PRIVATE_PROC(TRUE) SHOULD_NOT_OVERRIDE(TRUE) - if((. = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, user, function, flags, hint)) & CLICKCHAIN_COMPONENT_SIGNAL_HANDLED) + if((. = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT, I, e_args, function, flags, hint)) & CLICKCHAIN_COMPONENT_SIGNAL_HANDLED) return . & ~(CLICKCHAIN_COMPONENT_SIGNAL_HANDLED) - return tool_act(I, user, function, flags, hint) + return tool_act(I, e_args, function, flags, hint) /** * primary proc to be used when calling an interaction with a tool with an atom @@ -185,22 +185,22 @@ * * flags - tool operation flags * * hint - the operation hint, if the calling system is the dynamic tool system. */ -/atom/proc/tool_act(obj/item/I, mob/user, function, flags, hint) +/atom/proc/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) switch(function) if(TOOL_CROWBAR) - return crowbar_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return crowbar_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_MULTITOOL) - return multitool_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return multitool_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_SCREWDRIVER) - return screwdriver_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return screwdriver_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_WRENCH) - return wrench_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return wrench_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_WELDER) - return welder_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return welder_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_WIRECUTTER) - return wirecutter_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return wirecutter_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE if(TOOL_ANALYZER) - return analyzer_act(I, user, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE + return analyzer_act(I, e_args, flags, hint)? CLICKCHAIN_DO_NOT_PROPAGATE : NONE //? Add more tool_acts as necessary. /** @@ -215,7 +215,7 @@ * * cost - optional; cost multiplier to the default cost of 1 per second. * * usage - optional; usage flags for tool speed/quality checks. */ -/atom/proc/use_tool_standard(function, obj/item/I, mob/user, flags, delay, cost, usage) +/atom/proc/use_tool_standard(function, obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost, usage) return use_tool(function, I, e_args, flags, delay, cost, usage) /** @@ -231,7 +231,7 @@ * * usage - optional; usage flags for tool speed/quality checks. * * volume - optional; volume override */ -/atom/proc/use_tool(function, obj/item/I, mob/user, flags, delay, cost = 1, usage, volume) +/atom/proc/use_tool(function, obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost = 1, usage, volume) SHOULD_NOT_OVERRIDE(TRUE) var/quality = I.tool_check(function, user, src, flags, usage) if(!quality) From c97852cb50db89d455aa78f89afd4ce499162c1e Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 11:59:54 -0700 Subject: [PATCH 15/33] e_args --- code/__HELPERS/do_after.dm | 7 ++++--- code/modules/tools/_tool_system.dm | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm index 32dc1a7da37a..a0365eeb132a 100644 --- a/code/__HELPERS/do_after.dm +++ b/code/__HELPERS/do_after.dm @@ -68,8 +68,9 @@ * * max_distance - if not null, the user is required to be get_dist() <= max_distance from target. * * additional_checks - a callback that allows for custom checks. this is invoked with our args directly, allowing us to modify delay. * * progress_anchor - override progressbar anchor location + * * progress_instance - override progressbar instance */ -/proc/do_after(mob/user, delay, atom/target, flags, mobility_flags = MOBILITY_CAN_USE, max_distance, datum/callback/additional_checks, atom/progress_anchor) +/proc/do_after(mob/user, delay, atom/target, flags, mobility_flags = MOBILITY_CAN_USE, max_distance, datum/callback/additional_checks, atom/progress_anchor, datum/progressbar/progress_instance) if(isnull(user)) return FALSE if(!delay) @@ -97,10 +98,10 @@ var/obj/item/active_held_item = user.get_active_held_item() - var/datum/progressbar/progress + var/datum/progressbar/progress = progress_instance var/original_delay = delay var/delay_factor = 1 - if(!(flags & DO_AFTER_NO_PROGRESS) && (!isnull(progress_anchor || !isnull(target)))) + if(isnull(progress) && !(flags & DO_AFTER_NO_PROGRESS) && (!isnull(progress_anchor || !isnull(target)))) progress = new(user, delay, progress_anchor || target) var/start_time = world.time diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 48d1d1548039..9fef088a5976 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -233,26 +233,26 @@ */ /atom/proc/use_tool(function, obj/item/I, datum/event_args/actor/clickchain/e_args, flags, delay, cost = 1, usage, volume) SHOULD_NOT_OVERRIDE(TRUE) - var/quality = I.tool_check(function, user, src, flags, usage) + var/quality = I.tool_check(function, e_args, src, flags, usage) if(!quality) return FALSE - var/speed = I.tool_speed(function, user, src, flags, usage) + var/speed = I.tool_speed(function, e_args, src, flags, usage) //! this currently makes tools more efficient if you have more toolspeed. //! this is probably a bad thing. // todo: automatically adjust cost to rectify this. // todo: tool_cost()? potentially invert cost multiplier automagically, or invert it in this proc. delay = delay * speed - if(!I.using_as_tool(function, flags, user, src, delay, cost, usage)) + if(!I.using_as_tool(function, flags, e_args, src, delay, cost, usage)) return FALSE - I.tool_feedback_start(function, flags, user, src, delay, cost, usage, volume) - if(!do_after(user, delay, src)) - I.used_as_tool(function, flags, user, src, delay, cost, usage, FALSE) - I.tool_feedback_end(function, flags, user, src, delay, cost, usage, FALSE, volume) + I.tool_feedback_start(function, flags, e_args, src, delay, cost, usage, volume) + if(!do_after(e_args.performer, delay, src, progress_instance = create_actor_progress_bar(e_args, delay))) + I.used_as_tool(function, flags, e_args, src, delay, cost, usage, FALSE) + I.tool_feedback_end(function, flags, e_args, src, delay, cost, usage, FALSE, volume) return FALSE - if(!I.used_as_tool(function, flags, user, src, delay, cost, usage, TRUE)) - I.tool_feedback_end(function, flags, user, src, delay, cost, usage, FALSE, volume) + if(!I.used_as_tool(function, flags, e_args, src, delay, cost, usage, TRUE)) + I.tool_feedback_end(function, flags, e_args, src, delay, cost, usage, FALSE, volume) return FALSE - I.tool_feedback_end(function, flags, user, src, delay, cost, usage, TRUE, volume) + I.tool_feedback_end(function, flags, e_args, src, delay, cost, usage, TRUE, volume) return TRUE //! Dynamic Tool API From 7cd287f3b55a3eac01af56b86bfa4a7fe6ea9cb3 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 12:07:09 -0700 Subject: [PATCH 16/33] entity args conversion --- code/datums/event_args/actor.dm | 6 +++-- code/game/machinery/misc/bioscan_antenna.dm | 11 +++++--- code/game/machinery/pipe/construction.dm | 18 +++++++------ code/game/objects/objs.dm | 28 ++++++++++----------- code/game/objects/structures/window.dm | 18 ++++++------- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/code/datums/event_args/actor.dm b/code/datums/event_args/actor.dm index ea76526683f5..c5186ef2ed96 100644 --- a/code/datums/event_args/actor.dm +++ b/code/datums/event_args/actor.dm @@ -13,11 +13,13 @@ /datum/event_args/actor/proc/chat_feedback(msg, atom/target) performer.action_feedback(msg, target) - initiator.action_feedback(msg, target) + if(performer != initiator) + initiator.action_feedback(msg, target) /datum/event_args/actor/proc/bubble_feedback(msg, atom/target) performer.bubble_action_feedback(msg, target) - initiator.bubble_action_feedback(msg, target) + if(performer != initiator) + initiator.bubble_action_feedback(msg, target) /** * It is highly recommended to use named parameters with this. diff --git a/code/game/machinery/misc/bioscan_antenna.dm b/code/game/machinery/misc/bioscan_antenna.dm index d82ac73fe610..2e3ccc9f0096 100644 --- a/code/game/machinery/misc/bioscan_antenna.dm +++ b/code/game/machinery/misc/bioscan_antenna.dm @@ -38,10 +38,15 @@ GLOBAL_LIST_EMPTY(bioscan_antenna_list) if(!network_mutable) return ..() . = TRUE - var/new_network = default_input_text(user, "What do you want to set the network key to?", "Modify Network", network_key) - if(!user.Reachability(src) || isnull(new_network)) + var/new_network = default_input_text(e_args.initiator, "What do you want to set the network key to?", "Modify Network", network_key) + if(!e_args.performer.Reachability(src) || isnull(new_network)) return - user.visible_message(SPAN_NOTICE("[user] reprograms the network on [src]."), range = MESSAGE_RANGE_CONFIGURATION) + e_args.visible_feedback( + target = src, + visible = SPAN_NOTICE("[e_args.performer] reprograms the network on [src]."), + range = MESSAGE_RANGE_CONFIGURATION, + otherwise_self = SPAN_NOTICE("You reprogram the network on [src]."), + ) change_network(new_network) /obj/machinery/bioscan_antenna/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 3d7e81b2236d..5e9119f4d80d 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -184,19 +184,19 @@ Buildable meters if(!isturf(loc)) return TRUE - add_fingerprint(user) + add_fingerprint(e_args.performer) fixdir() var/obj/machinery/atmospherics/fakeA = pipe_type var/initial_flags = initial(fakeA.pipe_flags) for(var/obj/machinery/atmospherics/M in loc) if((M.pipe_flags & initial_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers. - to_chat(user, "Something is hogging the tile!") + e_args.chat_feedback(SPAN_WARNING("Something is hogging the tile!"), src) return TRUE if((M.piping_layer != piping_layer) && !((M.pipe_flags | initial_flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER continue if(M.get_init_dirs() & SSmachines.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe - to_chat(user, "There is already a pipe at that location!") + e_args.chat_feedback(SPAN_WARNING("There is already a pipe at that location!"), src) return TRUE // no conflicts found @@ -205,15 +205,17 @@ Buildable meters // TODO - Evaluate and remove the "need at least one thing to connect to" thing ~Leshana // With how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment. if (QDELETED(A)) - to_chat(user, "There's nothing to connect this pipe section to!") + e_args.chat_feedback(SPAN_WARNING("There's nothing to connect this pipe section to!"), src) return TRUE transfer_fingerprints_to(A) playsound(src, I.tool_sound, 50, 1) - user.visible_message( \ - "[user] fastens \the [src].", \ - "You fasten \the [src].", \ - "You hear ratcheting.") + e_args.visible_feedback( + target = src, + visible = SPAN_NOTICE("[e_args.performer] fastens \the [src]."), + audible = SPAN_WARNING("You hear ratcheting."), + otherwise_self = SPAN_NOTICE("You fasten \the [src].") + ) qdel(src) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 25b67fc8a811..18cb4de5862a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -564,24 +564,24 @@ if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(user)) return ..() if(isnull(obj_cell_slot.cell)) - user.action_feedback(SPAN_WARNING("[src] has no cell in it.")) + e_args.chat_feedback(SPAN_WARNING("[src] has no cell in it.")) return CLICKCHAIN_DO_NOT_PROPAGATE - log_construction(user, src, "removing cell") - user.visible_action_feedback( + log_construction(e_args.performer, src, "removing cell") + e_args.visible_feedback( target = src, - hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] starts removing the cell from [src]."), - visible_self = SPAN_NOTICE("You start removing the cell from [src]."), - audible_hard = SPAN_NOTICE("You hear fasteners being undone."), + range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] starts removing the cell from [src]."), + audible = SPAN_NOTICE("You hear fasteners being undone."), + otherwise_self = SPAN_NOTICE("You start removing the cell from [src]."), ) - if(!use_tool(function, I, user, flags, obj_cell_slot.remove_tool_time, 1)) + if(!use_tool(function, I, e_args, flags, obj_cell_slot.remove_tool_time, 1)) return CLICKCHAIN_DO_NOT_PROPAGATE - log_construction(user, src, "removed cell") - user.visible_action_feedback( + log_construction(e_args.performer, src, "removed cell") + e_args.visible_feedback( target = src, - hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), - audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), - visible_self = SPAN_NOTICE("You remove the cell from [src]."), + range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] removes the cell from [src]."), + audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 3201b468e1c0..645848616be9 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -457,11 +457,11 @@ . = TRUE if (construction_state == WINDOW_STATE_UNSECURED || construction_state == WINDOW_STATE_SCREWED_TO_FLOOR || !considered_reinforced) - if (!use_screwdriver(I, user, flags)) + if (!use_screwdriver(I, e_args, flags)) return var/unsecuring = construction_state != WINDOW_STATE_UNSECURED - user.action_feedback(SPAN_NOTICE("You [unsecuring? "unfasten" : "fasten"] the frame [unsecuring? "from" : "to"] the floor."), src) + e_args.chat_feedback(SPAN_NOTICE("You [unsecuring? "unfasten" : "fasten"] the frame [unsecuring? "from" : "to"] the floor."), src) if (unsecuring) construction_state = WINDOW_STATE_UNSECURED set_anchored(FALSE) @@ -475,11 +475,11 @@ if (construction_state != WINDOW_STATE_CROWBRARED_IN && construction_state != WINDOW_STATE_SECURED_TO_FRAME) return - if (!use_screwdriver(I, user, flags)) + if (!use_screwdriver(I, e_args, flags)) return var/unsecuring = construction_state == WINDOW_STATE_SECURED_TO_FRAME - user.action_feedback(SPAN_NOTICE("You [unsecuring? "unfasten" : "fasten"] the window [unsecuring? "from" : "to"] the frame."), src) + e_args.chat_feedback(SPAN_NOTICE("You [unsecuring? "unfasten" : "fasten"] the window [unsecuring? "from" : "to"] the frame."), src) construction_state = unsecuring ? WINDOW_STATE_CROWBRARED_IN : WINDOW_STATE_SECURED_TO_FRAME @@ -489,21 +489,21 @@ return if (construction_state != WINDOW_STATE_CROWBRARED_IN && construction_state != WINDOW_STATE_SCREWED_TO_FLOOR) return - if (!use_crowbar(I, user, flags)) + if (!use_crowbar(I, e_args, flags)) return var/unsecuring = construction_state == WINDOW_STATE_CROWBRARED_IN - user.action_feedback(SPAN_NOTICE("You pry [src] [unsecuring ? "out of" : "into"] the frame."), src) + e_args.chat_feedback(SPAN_NOTICE("You pry [src] [unsecuring ? "out of" : "into"] the frame."), src) construction_state = unsecuring ? WINDOW_STATE_SCREWED_TO_FLOOR : WINDOW_STATE_CROWBRARED_IN /obj/structure/window/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if (construction_state != WINDOW_STATE_UNSECURED) - user.action_feedback(SPAN_WARNING("[src] has to be entirely unfastened from the floor before you can disasemble it!")) + e_args.chat_feedback(SPAN_WARNING("[src] has to be entirely unfastened from the floor before you can disasemble it!")) return - if (!use_wrench(I, user, flags)) + if (!use_wrench(I, e_args, flags)) return - user.action_feedback(SPAN_NOTICE("You disassemble [src]."), src) + e_args.chat_feedback(SPAN_NOTICE("You disassemble [src]."), src) deconstruct(ATOM_DECONSTRUCT_DISASSEMBLED) From c6cb2aebb68022e494db0b720077ce56d7941edd Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 12:15:48 -0700 Subject: [PATCH 17/33] entity args conversion --- code/game/machinery/_machinery_construction.dm | 18 +++++++++--------- code/game/objects/items.dm | 6 +++--- code/game/objects/objs.dm | 12 ++++++------ code/modules/fishing/aquarium/aquarium.dm | 12 ++++++++++-- code/modules/fishing/equipment/rod.dm | 4 ++-- code/modules/logging/logging.dm | 4 ++-- .../projectiles/ammunition/ammo_casing.dm | 10 ++++++---- code/modules/sculpting/sculpting_block.dm | 8 ++++---- 8 files changed, 42 insertions(+), 32 deletions(-) diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index e05cb95a0f03..b798f92c5627 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -20,27 +20,27 @@ return ..() /obj/machinery/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) - if(INTERACTING_WITH_FOR(user, src, INTERACTING_FOR_CONSTRUCTION)) + if(INTERACTING_WITH_FOR(e_args.performer, src, INTERACTING_FOR_CONSTRUCTION)) return CLICKCHAIN_DO_NOT_PROPAGATE - START_INTERACTING_WITH(user, src, INTERACTING_FOR_CONSTRUCTION) + START_INTERACTING_WITH(e_args.performer, src, INTERACTING_FOR_CONSTRUCTION) if(function == tool_deconstruct && !isnull(default_deconstruct)) - if(default_deconstruction_dismantle(I, user, flags = flags)) + if(default_deconstruction_dismantle(I, e_args, flags = flags)) . = CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE . = CLICKCHAIN_DO_NOT_PROPAGATE else if(function == tool_unanchor && !isnull(default_unanchor)) - if(default_deconstruction_anchor(I, user, flags = flags)) + if(default_deconstruction_anchor(I, e_args, flags = flags)) . = CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE . = CLICKCHAIN_DO_NOT_PROPAGATE else if(function == tool_panel && !isnull(default_panel)) - if(default_deconstruction_panel(I, user, flags = flags)) + if(default_deconstruction_panel(I, e_args, flags = flags)) . = CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE . = CLICKCHAIN_DO_NOT_PROPAGATE - STOP_INTERACTING_WITH(user, src,INTERACTING_FOR_CONSTRUCTION) + STOP_INTERACTING_WITH(e_args.performer, src,INTERACTING_FOR_CONSTRUCTION) if(isnull(.)) return ..() // todo: better verb/message support -/obj/machinery/proc/default_deconstruction_panel(obj/item/tool, mob/user, speed_mult = 1, flags) +/obj/machinery/proc/default_deconstruction_panel(obj/item/tool, datum/event_args/actor/clickchain/e_args speed_mult = 1, flags) var/needed_time = default_panel * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) user.visible_action_feedback( @@ -61,7 +61,7 @@ return TRUE // todo: better verb/message support -/obj/machinery/proc/default_deconstruction_dismantle(obj/item/tool, mob/user, speed_mult = 1, flags) +/obj/machinery/proc/default_deconstruction_dismantle(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_deconstruct * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) user.visible_action_feedback( @@ -82,7 +82,7 @@ return TRUE // todo: better verb/message support -/obj/machinery/proc/default_deconstruction_anchor(obj/item/tool, mob/user, speed_mult = 1, flags) +/obj/machinery/proc/default_deconstruction_anchor(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_unanchor * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) user.visible_action_feedback( diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 55375c80cf05..d5612b461381 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -769,7 +769,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. // SHOULD_CALL_PARENT(TRUE) // attack_self isn't really part of the item attack chain. SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) - if(on_attack_self(user)) + if(on_attack_self(new /datum/event_args/actor(user))) return TRUE if(interaction_flags_item & INTERACT_ITEM_ATTACK_SELF) interact(user) @@ -783,7 +783,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. * * @return TRUE to signal to overrides to stop the chain and do nothing. */ -/obj/item/proc/on_attack_self(mob/user) +/obj/item/proc/on_attack_self(datum/event_args/actor/e_args) if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_inhand && obj_cell_slot.interaction_active(src)) user.visible_action_feedback( target = src, @@ -792,7 +792,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), visible_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(user, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) return TRUE return FALSE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 18cb4de5862a..e9ead3f9937f 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -257,7 +257,7 @@ audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), visible_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(e_args.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) return TRUE @@ -429,7 +429,7 @@ audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) - log_construction(e_args.performer, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") + log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) return TRUE return ..() @@ -566,21 +566,21 @@ if(isnull(obj_cell_slot.cell)) e_args.chat_feedback(SPAN_WARNING("[src] has no cell in it.")) return CLICKCHAIN_DO_NOT_PROPAGATE - log_construction(e_args.performer, src, "removing cell") + log_construction(e_args, src, "removing cell") e_args.visible_feedback( target = src, range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] starts removing the cell from [src]."), + visible = SPAN_NOTICE("[e_args.performer] starts removing the cell from [src]."), audible = SPAN_NOTICE("You hear fasteners being undone."), otherwise_self = SPAN_NOTICE("You start removing the cell from [src]."), ) if(!use_tool(function, I, e_args, flags, obj_cell_slot.remove_tool_time, 1)) return CLICKCHAIN_DO_NOT_PROPAGATE - log_construction(e_args.performer, src, "removed cell") + log_construction(e_args, src, "removed cell") e_args.visible_feedback( target = src, range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] removes the cell from [src]."), + visible = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index bf1eb3239a06..fbb02c86d018 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -132,8 +132,16 @@ /obj/structure/aquarium/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!allow_unanchor) return ..() - if(use_wrench(I, user, delay = 4 SECONDS)) - user.visible_message(SPAN_NOTICE("[user] [anchored? "fastens [src] to the ground" : "unfastens [src] from the ground"]."), range = MESSAGE_RANGE_CONSTRUCTION) + if(use_wrench(I, e_args, delay = 4 SECONDS)) + log_construction(e_args.performer, src, "fastened") + set_anchored(!anchor) + e_args.visible_feedback( + target = src, + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[e_args.performer] [anchored? "fastens [src] to the ground" : "unfastens [src] from the ground"]."), + audbile = SPAN_WARNING("You hear bolts being [anchored? "fastened" : "unfastened"]"), + otherwise_self = SPAN_NOTICE("You [anchored? "fasten" : "unfasten"] [src]."), + ) return TRUE return ..() diff --git a/code/modules/fishing/equipment/rod.dm b/code/modules/fishing/equipment/rod.dm index f29b4ea4e32b..d86b1d995d6c 100644 --- a/code/modules/fishing/equipment/rod.dm +++ b/code/modules/fishing/equipment/rod.dm @@ -80,11 +80,11 @@ SStgui.update_uis(src) update_icon() -/obj/item/fishing_rod/on_attack_self(mob/user) +/obj/item/fishing_rod/on_attack_self(datum/event_args/actor/e_argsr) . = ..() if(.) return - reel(user) + reel(e_args.performer) /obj/item/fishing_rod/proc/reel(mob/user, atom/target) // signal first for fishing minigame diff --git a/code/modules/logging/logging.dm b/code/modules/logging/logging.dm index 1df25668753f..dd3ca429729d 100644 --- a/code/modules/logging/logging.dm +++ b/code/modules/logging/logging.dm @@ -25,8 +25,8 @@ * * todo: log initiator */ -/proc/log_construction(mob/user, atom/target, message) - log_game("CONSTRUCTION: [key_name(user)] [COORD(user)] -> [target] [COORD(target)]: [message]") +/proc/log_construction(datum/event_args/actor/e_args, atom/target, message) + log_game("CONSTRUCTION: [key_name(e_args.performer)] [COORD(e_args.performer)] -> [target] [COORD(target)]: [message]") /** * log click - context menu diff --git a/code/modules/projectiles/ammunition/ammo_casing.dm b/code/modules/projectiles/ammunition/ammo_casing.dm index 97f70548728e..6db71addfe76 100644 --- a/code/modules/projectiles/ammunition/ammo_casing.dm +++ b/code/modules/projectiles/ammunition/ammo_casing.dm @@ -51,15 +51,17 @@ /obj/item/ammo_casing/screwdriver_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) . = TRUE if(!stored) - user.action_feedback(SPAN_WARNING("There is no bullet in [src] to inscribe."), src) + e_args.chat_feedback(SPAN_WARNING("There is no bullet in [src] to inscribe."), src) + return + var/label_text = input(e_args.initiator, "Inscribe some text into [initial(stored.name)]", "Inscription", stored.name) + if(!e_args.performer.Adjacent(src)) return - var/label_text = input(user, "Inscribe some text into [initial(stored.name)]", "Inscription", stored.name) label_text = sanitize(label_text, MAX_NAME_LEN, extra = FALSE) if(!label_text) - user.action_feedback(SPAN_NOTICE("You scratch the inscription off of [initial(stored.name)]."), src) + e_args.chat_feedback(SPAN_NOTICE("You scratch the inscription off of [initial(stored.name)]."), src) stored.name = initial(stored.name) return - user.action_feedback(SPAN_NOTICE("You inscribe [label_text] into \the [initial(stored.name)]."), src) + e_args.chat_feedback(SPAN_NOTICE("You inscribe [label_text] into \the [initial(stored.name)]."), src) stored.name = "[initial(stored.name)] (\"[label_text]\")" /obj/item/ammo_casing/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index fcbd5cd235f1..20931201baf0 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -139,7 +139,7 @@ visible_self = SPAN_NOTICE("You start [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), audible_hard = SPAN_WARNING("You hear bolts being [anchored? "unfastened" : "fastened"]."), ) - log_construction(user, src, "started [anchored? "unanchoring" : "anchoring"]") + log_construction(ue_argsser, src, "started [anchored? "unanchoring" : "anchoring"]") if(!use_wrench(I, user, flags, 3 SECONDS)) return TRUE user.visible_action_feedback( @@ -149,7 +149,7 @@ visible_self = SPAN_NOTICE("You finish [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), audible_hard = SPAN_WARNING("You hear bolts [anchored? "falling out" : "clicking into place"]."), ) - log_construction(user, src, "[anchored? "unanchored" : "anchored"]") + log_construction(e_args, src, "[anchored? "unanchored" : "anchored"]") set_anchored(!anchored) return TRUE @@ -164,7 +164,7 @@ visible_self = SPAN_NOTICE("You start slicing [src] apart."), audible_hard = SPAN_WARNING("You hear the sound of a welding torch being used on something metallic."), ) - log_construction(user, src, "started deconstructing") + log_construction(e_args, src, "started deconstructing") if(!use_welder(I, user, flags, 7 SECONDS, 3)) return TRUE user.visible_action_feedback( @@ -174,7 +174,7 @@ visible_self = SPAN_NOTICE("You slice [src] apart."), audible_hard = SPAN_WARNING("You hear the sound of a welding torch moving back into open air, and a few pieces of metal falling apart."), ) - log_construction(user, src, "deconstructed") + log_construction(e_args, src, "deconstructed") set_anchored(!anchored) deconstruct(ATOM_DECONSTRUCT_DISASSEMBLED) return TRUE From 455d76151c1e2aa9ad565ae4b1fb1d2b5a4b7c51 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 12:16:02 -0700 Subject: [PATCH 18/33] entity args conversion --- code/game/machinery/_machinery_construction.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index b798f92c5627..e57aac898182 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -40,7 +40,7 @@ return ..() // todo: better verb/message support -/obj/machinery/proc/default_deconstruction_panel(obj/item/tool, datum/event_args/actor/clickchain/e_args speed_mult = 1, flags) +/obj/machinery/proc/default_deconstruction_panel(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_panel * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) user.visible_action_feedback( From bd86d66b88f5c15735e390d378b43e1d09267e53 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 12:18:29 -0700 Subject: [PATCH 19/33] fix --- code/game/objects/items.dm | 12 ++++++------ code/game/objects/objs.dm | 2 +- .../atmospherics/machinery/components/component.dm | 14 ++++++++------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d5612b461381..14f19a4be467 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -785,15 +785,15 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. */ /obj/item/proc/on_attack_self(datum/event_args/actor/e_args) if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_inhand && obj_cell_slot.interaction_active(src)) - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] removes the cell from [src]."), - audible_hard = SPAN_NOTICE("You hear fasteners falling out and something being removed."), - visible_self = SPAN_NOTICE("You remove the cell from [src]."), + range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] removes the cell from [src]."), + audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), + otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") - user.put_in_hands_or_drop(obj_cell_slot.remove_cell(user)) + e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) return TRUE return FALSE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index e9ead3f9937f..1f74e6d05ebb 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -561,7 +561,7 @@ return ..() /obj/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) - if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(user)) + if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(e_args.performer)) return ..() if(isnull(obj_cell_slot.cell)) e_args.chat_feedback(SPAN_WARNING("[src] has no cell in it.")) diff --git a/code/modules/atmospherics/machinery/components/component.dm b/code/modules/atmospherics/machinery/components/component.dm index 860568d158aa..a98444090dbc 100644 --- a/code/modules/atmospherics/machinery/components/component.dm +++ b/code/modules/atmospherics/machinery/components/component.dm @@ -132,14 +132,16 @@ if(isnull(default_multitool_hijack)) return FALSE if(hijack_require_exposed && is_hidden_underfloor()) - user.action_feedback(SPAN_WARNING("You can't reach the controls of [src] while it's covered by flooring."), src) + e_args.chat_feedback(SPAN_WARNING("You can't reach the controls of [src] while it's covered by flooring."), src) return TRUE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = MESSAGE_RANGE_CONFIGURATION, - visible_hard = SPAN_WARNING("[user] starts tinkering with [src] using their [I]!"), + range = MESSAGE_RANGE_CONFIGURATION, + visible = SPAN_WARNING("[user] starts tinkering with [src] using their [I]!"), + otherwise_self = SPAN_WARNING("You start tinkering with [src] using your [I]..."), ) - if(!do_after(user, default_multitool_hijack, src, mobility_flags = MOBILITY_CAN_USE)) + if(!do_after(e_args.performer, default_multitool_hijack, src, mobility_flags = MOBILITY_CAN_USE, progress_instance = create_actor_progress_bar(e_args))) return TRUE - ui_interact(user) + // todo: uh, this obviously needs a wrapper + ui_interact(e_args.initiator) return TRUE From a9d235671758e2f334d9926e079d4c9465c9ab50 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 14:34:37 -0700 Subject: [PATCH 20/33] fix --- .../game/machinery/_machinery_construction.dm | 54 ++++++++++--------- code/game/machinery/pipe/construction.dm | 4 +- code/game/objects/items.dm | 2 +- .../machinery/components/component.dm | 2 +- code/modules/fishing/aquarium/aquarium.dm | 4 +- code/modules/fishing/equipment/rod.dm | 2 +- code/modules/sculpting/sculpting_block.dm | 40 +++++++------- 7 files changed, 57 insertions(+), 51 deletions(-) diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index e57aac898182..761ec5f6ce65 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -43,19 +43,21 @@ /obj/machinery/proc/default_deconstruction_panel(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_panel * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] starts to [panel_open? "close" : "open"] [src]'s maintenance panel."), - audible_soft = SPAN_WARNING("You hear something being (un)fastened."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] starts to [panel_open? "close" : "open"] [src]'s maintenance panel."), + audible = SPAN_WARNING("You hear something being (un)fastened."), + otherwise_self = SPAN_WARNING("You start to [panel_open? "close" : "open"] [src]'s panel."), ) if(!use_tool(tool_panel, tool, user, flags, needed_time)) return FALSE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] [panel_open? "closes" : "opens"] [src]'s maintenance panel."), - audible_soft = SPAN_WARNING("You hear something being (un)fastened."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] [panel_open? "closes" : "opens"] [src]'s maintenance panel."), + audible = SPAN_WARNING("You hear something being (un)fastened."), + otherwise_self = SPAN_WARNING("You [panel_open? "close" : "open"] [src]'s panel."), ) set_panel_open(!panel_open) return TRUE @@ -64,19 +66,21 @@ /obj/machinery/proc/default_deconstruction_dismantle(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_deconstruct * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] starts to dismantle [src]."), - audible_soft = SPAN_WARNING("You hear a series of small parts being removed from something."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] starts to dismantle [src]."), + audible = SPAN_WARNING("You hear a series of small parts being removed from something."), + otherwise_self = SPAN_WARNING("You start to dismantle [src]."), ) if(!use_tool(tool_deconstruct, tool, user, flags, needed_time)) return FALSE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] dismantles [src]."), - audible_soft = SPAN_WARNING("You hear something getting dismantled."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] dismantles [src]."), + audible = SPAN_WARNING("You hear something getting dismantled."), + otherwise_self = SPAN_WARNING("You dismantle [src]."), ) dismantle() return TRUE @@ -85,19 +89,21 @@ /obj/machinery/proc/default_deconstruction_anchor(obj/item/tool, datum/event_args/actor/clickchain/e_args, speed_mult = 1, flags) var/needed_time = default_unanchor * speed_mult * (isnull(tool)? 1 : tool.tool_speed) if(needed_time) - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] starts to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), - audible_soft = SPAN_WARNING("You hear something heavy being (un)fastened."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] starts to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), + audible = SPAN_WARNING("You hear something heavy being (un)fastened."), + otherwise_self = SPAN_WARNING("You start to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), ) if(!use_tool(tool_unanchor, tool, user, flags, needed_time)) return FALSE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - soft_range = MESSAGE_RANGE_CONSTRUCTION, - visible_soft = SPAN_WARNING("[user] [anchored? "bolts" : "unbolts"] [src] [anchored? "to" : "from"] from the floor."), - audible_soft = SPAN_WARNING("You hear something heavy being (un)fastened."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_WARNING("[user] [anchored? "bolts" : "unbolts"] [src] [anchored? "to" : "from"] from the floor."), + audible = SPAN_WARNING("You hear something heavy being (un)fastened."), + otherwise_self = SPAN_WARNING("You [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), ) set_anchored(!anchored) return TRUE diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 5e9119f4d80d..e26127bf7fb6 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -278,11 +278,11 @@ Buildable meters pipe = P break if(!pipe) - to_chat(user, "You need to fasten it to a pipe!") + e_args.chat_feedback(SPAN_WARNING("You need to fasten it to a pipe!"), src) return TRUE new /obj/machinery/meter(loc, piping_layer) playsound(src, I.tool_sound, 50, 1) - to_chat(user, "You fasten the meter to the pipe.") + e_args.chat_feedback(SPAN_NOTICE("You fasten the meter to the pipe."), src) qdel(src) /obj/item/pipe_meter/dropped(mob/user, flags, atom/newLoc) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 14f19a4be467..020bb28213b8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -788,7 +788,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. e_args.visible_feedback( target = src, range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] removes the cell from [src]."), + visible = SPAN_NOTICE("[e_args.performer] removes the cell from [src]."), audible = SPAN_NOTICE("You hear fasteners falling out and something being removed."), otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) diff --git a/code/modules/atmospherics/machinery/components/component.dm b/code/modules/atmospherics/machinery/components/component.dm index a98444090dbc..91d8305d24dc 100644 --- a/code/modules/atmospherics/machinery/components/component.dm +++ b/code/modules/atmospherics/machinery/components/component.dm @@ -137,7 +137,7 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONFIGURATION, - visible = SPAN_WARNING("[user] starts tinkering with [src] using their [I]!"), + visible = SPAN_WARNING("[e_args.performer] starts tinkering with [src] using their [I]!"), otherwise_self = SPAN_WARNING("You start tinkering with [src] using your [I]..."), ) if(!do_after(e_args.performer, default_multitool_hijack, src, mobility_flags = MOBILITY_CAN_USE, progress_instance = create_actor_progress_bar(e_args))) diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index fbb02c86d018..6a71505a7481 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -134,12 +134,12 @@ return ..() if(use_wrench(I, e_args, delay = 4 SECONDS)) log_construction(e_args.performer, src, "fastened") - set_anchored(!anchor) + set_anchored(!anchored) e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, visible = SPAN_NOTICE("[e_args.performer] [anchored? "fastens [src] to the ground" : "unfastens [src] from the ground"]."), - audbile = SPAN_WARNING("You hear bolts being [anchored? "fastened" : "unfastened"]"), + audible = SPAN_WARNING("You hear bolts being [anchored? "fastened" : "unfastened"]"), otherwise_self = SPAN_NOTICE("You [anchored? "fasten" : "unfasten"] [src]."), ) return TRUE diff --git a/code/modules/fishing/equipment/rod.dm b/code/modules/fishing/equipment/rod.dm index d86b1d995d6c..4af1ad639709 100644 --- a/code/modules/fishing/equipment/rod.dm +++ b/code/modules/fishing/equipment/rod.dm @@ -80,7 +80,7 @@ SStgui.update_uis(src) update_icon() -/obj/item/fishing_rod/on_attack_self(datum/event_args/actor/e_argsr) +/obj/item/fishing_rod/on_attack_self(datum/event_args/actor/e_args) . = ..() if(.) return diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 20931201baf0..80a4a00b616f 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -132,22 +132,22 @@ . = ..() if(.) return - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] starts [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), - visible_self = SPAN_NOTICE("You start [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), - audible_hard = SPAN_WARNING("You hear bolts being [anchored? "unfastened" : "fastened"]."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] starts [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), + audible = SPAN_WARNING("You hear bolts being [anchored? "unfastened" : "fastened"]."), + otherwise_self = SPAN_NOTICE("You start [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), ) log_construction(ue_argsser, src, "started [anchored? "unanchoring" : "anchoring"]") if(!use_wrench(I, user, flags, 3 SECONDS)) return TRUE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] finishes [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), - visible_self = SPAN_NOTICE("You finish [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), - audible_hard = SPAN_WARNING("You hear bolts [anchored? "falling out" : "clicking into place"]."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] finishes [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), + audible = SPAN_WARNING("You hear bolts [anchored? "falling out" : "clicking into place"]."), + otherwise_self = SPAN_NOTICE("You finish [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), ) log_construction(e_args, src, "[anchored? "unanchored" : "anchored"]") set_anchored(!anchored) @@ -157,22 +157,22 @@ . = ..() if(.) return - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] starts slicing [src] apart."), - visible_self = SPAN_NOTICE("You start slicing [src] apart."), - audible_hard = SPAN_WARNING("You hear the sound of a welding torch being used on something metallic."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] starts slicing [src] apart."), + audible = SPAN_WARNING("You hear the sound of a welding torch being used on something metallic."), + otherwise_self = SPAN_NOTICE("You start slicing [src] apart."), ) log_construction(e_args, src, "started deconstructing") if(!use_welder(I, user, flags, 7 SECONDS, 3)) return TRUE - user.visible_action_feedback( + e_args.visible_feedback( target = src, - hard_range = MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[user] slices [src] apart."), - visible_self = SPAN_NOTICE("You slice [src] apart."), - audible_hard = SPAN_WARNING("You hear the sound of a welding torch moving back into open air, and a few pieces of metal falling apart."), + range = MESSAGE_RANGE_CONSTRUCTION, + visible = SPAN_NOTICE("[user] slices [src] apart."), + audible = SPAN_WARNING("You hear the sound of a welding torch moving back into open air, and a few pieces of metal falling apart."), + otherwise_self = SPAN_NOTICE("You slice [src] apart."), ) log_construction(e_args, src, "deconstructed") set_anchored(!anchored) From 0ebd73d2c5ad1992ca94643e33a664b0f7fae5c2 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 14:54:53 -0700 Subject: [PATCH 21/33] stuff --- code/__DEFINES/procs/clickcode.dm | 1 + .../game/machinery/_machinery_construction.dm | 18 +++++++-------- code/modules/sculpting/sculpting_block.dm | 14 +++++------ code/modules/tools/_tool_system.dm | 23 ++++++++++++------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm index 76429539a068..66b60deaee3b 100644 --- a/code/__DEFINES/procs/clickcode.dm +++ b/code/__DEFINES/procs/clickcode.dm @@ -24,6 +24,7 @@ /// person can reach us normally #define CLICKCHAIN_HAS_PROXIMITY (1<<1) /// in tool act - used to check if we should do default proximity checks when none are specified +/// this is added to clickchain flags by tool_attack_chain. #define CLICKCHAIN_TOOL_ACT (1<<2) /// redirected by something - like when a switchtool to another item #define CLICKCHAIN_REDIRECTED (1<<3) diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index 761ec5f6ce65..a5185a876220 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -46,16 +46,16 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] starts to [panel_open? "close" : "open"] [src]'s maintenance panel."), + visible = SPAN_WARNING("[e_args.performer] starts to [panel_open? "close" : "open"] [src]'s maintenance panel."), audible = SPAN_WARNING("You hear something being (un)fastened."), otherwise_self = SPAN_WARNING("You start to [panel_open? "close" : "open"] [src]'s panel."), ) - if(!use_tool(tool_panel, tool, user, flags, needed_time)) + if(!use_tool(tool_panel, tool, e_args, flags, needed_time)) return FALSE e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] [panel_open? "closes" : "opens"] [src]'s maintenance panel."), + visible = SPAN_WARNING("[e_args.performer] [panel_open? "closes" : "opens"] [src]'s maintenance panel."), audible = SPAN_WARNING("You hear something being (un)fastened."), otherwise_self = SPAN_WARNING("You [panel_open? "close" : "open"] [src]'s panel."), ) @@ -69,16 +69,16 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] starts to dismantle [src]."), + visible = SPAN_WARNING("[e_args.performer] starts to dismantle [src]."), audible = SPAN_WARNING("You hear a series of small parts being removed from something."), otherwise_self = SPAN_WARNING("You start to dismantle [src]."), ) - if(!use_tool(tool_deconstruct, tool, user, flags, needed_time)) + if(!use_tool(tool_deconstruct, tool, e_args, flags, needed_time)) return FALSE e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] dismantles [src]."), + visible = SPAN_WARNING("[e_args.performer] dismantles [src]."), audible = SPAN_WARNING("You hear something getting dismantled."), otherwise_self = SPAN_WARNING("You dismantle [src]."), ) @@ -92,16 +92,16 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] starts to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), + visible = SPAN_WARNING("[e_args.performer] starts to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), audible = SPAN_WARNING("You hear something heavy being (un)fastened."), otherwise_self = SPAN_WARNING("You start to [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), ) - if(!use_tool(tool_unanchor, tool, user, flags, needed_time)) + if(!use_tool(tool_unanchor, tool, e_args, flags, needed_time)) return FALSE e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_WARNING("[user] [anchored? "bolts" : "unbolts"] [src] [anchored? "to" : "from"] from the floor."), + visible = SPAN_WARNING("[e_args.performer] [anchored? "bolts" : "unbolts"] [src] [anchored? "to" : "from"] from the floor."), audible = SPAN_WARNING("You hear something heavy being (un)fastened."), otherwise_self = SPAN_WARNING("You [anchored? "unbolt" : "bolt"] [src] [anchored? "from" : "to"] the floor."), ) diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 80a4a00b616f..5fab9a8e8b6c 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -135,17 +135,17 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] starts [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), + visible = SPAN_NOTICE("[e_args.performer] starts [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), audible = SPAN_WARNING("You hear bolts being [anchored? "unfastened" : "fastened"]."), otherwise_self = SPAN_NOTICE("You start [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), ) - log_construction(ue_argsser, src, "started [anchored? "unanchoring" : "anchoring"]") - if(!use_wrench(I, user, flags, 3 SECONDS)) + log_construction(e_args, src, "started [anchored? "unanchoring" : "anchoring"]") + if(!use_wrench(I, e_args, flags, 3 SECONDS)) return TRUE e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] finishes [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), + visible = SPAN_NOTICE("[e_args.performer] finishes [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), audible = SPAN_WARNING("You hear bolts [anchored? "falling out" : "clicking into place"]."), otherwise_self = SPAN_NOTICE("You finish [anchored? "unbolting [src] from the floor" : "bolting [src] to the floor"]."), ) @@ -160,17 +160,17 @@ e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] starts slicing [src] apart."), + visible = SPAN_NOTICE("[e_args.performer] starts slicing [src] apart."), audible = SPAN_WARNING("You hear the sound of a welding torch being used on something metallic."), otherwise_self = SPAN_NOTICE("You start slicing [src] apart."), ) log_construction(e_args, src, "started deconstructing") - if(!use_welder(I, user, flags, 7 SECONDS, 3)) + if(!use_welder(I, e_args, flags, 7 SECONDS, 3)) return TRUE e_args.visible_feedback( target = src, range = MESSAGE_RANGE_CONSTRUCTION, - visible = SPAN_NOTICE("[user] slices [src] apart."), + visible = SPAN_NOTICE("[e_args.performer] slices [src] apart."), audible = SPAN_WARNING("You hear the sound of a welding torch moving back into open air, and a few pieces of metal falling apart."), otherwise_self = SPAN_NOTICE("You slice [src] apart."), ) diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 9fef088a5976..069eb893609c 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -55,7 +55,7 @@ */ /atom/proc/tool_interaction(obj/item/I, datum/event_args/actor/clickchain/e_args, clickchain_flags, function, hint, datum/callback/reachability_check) SHOULD_NOT_OVERRIDE(TRUE) - return _tool_interaction_entrypoint(I, user, clickchain_flags, function, hint, reachability_check) + return _tool_interaction_entrypoint(I, e_args, clickchain_flags, function, hint, reachability_check) /atom/proc/_tool_interaction_entrypoint(obj/item/provided_item, datum/event_args/actor/clickchain/e_args, clickchain_flags, function, hint, datum/callback/reachability_check) SHOULD_NOT_OVERRIDE(TRUE) @@ -63,24 +63,31 @@ if(isnull(reachability_check)) if(clickchain_flags & CLICKCHAIN_TOOL_ACT) // provided_item should never be null - reachability_check = CALLBACK(user, TYPE_PROC_REF(/atom/movable, Reachability), src, null, provided_item.reach, provided_item) + // we inject our default reachability check if tool act is set by tool attack chain + // otherwise we just ignore it if it wasn't specified + reachability_check = CALLBACK(e_args.performer, TYPE_PROC_REF(/atom/movable, Reachability), src, null, provided_item.reach, provided_item) if(reachability_check && !reachability_check.Invoke()) return NONE // from click chain if(provided_item) if(function) // automation, just go - return _dynamic_tool_act(provided_item, user, function, TOOL_OP_AUTOPILOT | TOOL_OP_REAL, hint) + return _dynamic_tool_act(provided_item, e_args, function, TOOL_OP_AUTOPILOT | TOOL_OP_REAL, hint) + var/list/hint_images = list() // used in clickchain - var/list/possibilities = dynamic_tool_functions(provided_item, user) - #warn possibilities is fundamentally used incorrectly later, we might - #warn have to refactor this to not use dynamic_tool_image at all. + // as of now, format is: + // function = hint OR list(hint, ...) + // hint images is passed in so it can be prebuilt by components + // more info is in comment of dynamic_tool_functions + var/list/possibilities = dynamic_tool_functions(provided_item, e_args, hint_images) if(!length(possibilities) || (provided_item.tool_locked == TOOL_LOCKING_STATIC)) // no dynamic tool functionality, or dynamic functionality disabled, route normally. function = provided_item.tool_behaviour() if(!function) return NONE - return _tool_act(provided_item, user, function, TOOL_OP_REAL) + return _tool_act(provided_item, e_args, function, TOOL_OP_REAL) + #warn possibilities is fundamentally used incorrectly later, we might + #warn have to refactor this to not use dynamic_tool_image at all. // enumerate var/list/functions = provided_item.tool_query(user, src) if((provided_item.tool_locked == TOOL_LOCKING_AUTO) && (length(functions) == 1)) @@ -268,7 +275,7 @@ * @params * * I - the tool used, if any * * user - the user, if any - * * hint_images - allows us to immediately associate hints to specific images without calling dynamic_tool_image after. usually not what you want. + * * hint_images - allows us to immediately associate hints to specific images without calling dynamic_tool_image after. usually not what you want, as this isn't lazy. */ /atom/proc/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() From c1d13dc9831096516af6c70509cd906251b29932 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 15:04:38 -0700 Subject: [PATCH 22/33] get rid of image proc --- citadel.dme | 1 + .../dcs/signals/signals_atom/tool_system.dm | 4 +- code/__DEFINES/tools/functionality.dm | 10 ---- .../game/machinery/_machinery_construction.dm | 14 ++---- code/game/objects/objs.dm | 7 +-- code/game/objects/structures/window.dm | 50 +++++++++---------- code/modules/fishing/aquarium/aquarium.dm | 8 +-- code/modules/sculpting/sculpting_block.dm | 16 +----- code/modules/tools/_tool_system.dm | 30 ++--------- code/modules/tools/visuals.dm | 8 +++ 10 files changed, 45 insertions(+), 103 deletions(-) create mode 100644 code/modules/tools/visuals.dm diff --git a/citadel.dme b/citadel.dme index caf6c4b075f4..869d1c332b28 100644 --- a/citadel.dme +++ b/citadel.dme @@ -4691,6 +4691,7 @@ #include "code\modules\tools\_tool_system.dm" #include "code\modules\tools\items.dm" #include "code\modules\tools\multitool.dm" +#include "code\modules\tools\visuals.dm" #include "code\modules\tools\wrappers.dm" #include "code\modules\tools\z_legacy.dm" #include "code\modules\tooltip\tooltip.dm" diff --git a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm index 7dd639e4f162..92399f327674 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm @@ -4,7 +4,7 @@ /// from base of _tool_act: (I, user, function, flags, hint) where I = item, e_args = clickchain data, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system /// return CLICKCHAIN_COMPONENT_SIGNAL_HANDLED to abort normal tool_act handling. #define COMSIG_ATOM_TOOL_ACT "tool_act" -/// from base of dynamic_tool_functions: (I, datum/event_args/actor/clickchain/e_args, functions, hint_images) where I = item, e_args = clickchain data. -/// inject by merging into functions, and associating hints to images in hint_images +/// from base of dynamic_tool_functions: (I, datum/event_args/actor/clickchain/e_args, functions) where I = item, e_args = clickchain data. +/// inject by merging into functions /// remember to use merge_double_lazy_assoc_list() to merge function lists! #define COMSIG_ATOM_TOOL_FUNCTIONS "tool_functions" diff --git a/code/__DEFINES/tools/functionality.dm b/code/__DEFINES/tools/functionality.dm index 1f6a4e3cc896..989989538382 100644 --- a/code/__DEFINES/tools/functionality.dm +++ b/code/__DEFINES/tools/functionality.dm @@ -38,16 +38,6 @@ GLOBAL_REAL_VAR(_dyntool_image_states) = list( //* None yet! Waiting on skill-system design. -//? Tool hints - make these human readable! - -#define TOOL_HINT_UNSCREWING_WINDOW_FRAME "unsecure frame" -#define TOOL_HINT_SCREWING_WINDOW_FRAME "secure frame" -#define TOOL_HINT_UNSCREWING_WINDOW_PANE "unfasten pane" -#define TOOL_HINT_SCREWING_WINDOW_PANE "fasten pane" -#define TOOL_HINT_CROWBAR_WINDOW_IN "pane in" -#define TOOL_HINT_CROWBAR_WINDOW_OUT "pane out" -#define TOOL_HINT_WRENCH_WINDOW_DISASSEMBLY "dismantle" - //? tool_locked var /// unlocked - use dynamic tool system diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index a5185a876220..3e5ddd9aa2fa 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -4,21 +4,13 @@ /obj/machinery/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() if(tool_deconstruct && !isnull(default_deconstruct) && panel_open) - LAZYADD(.[tool_panel], "deconstruct") + LAZYSET(.[tool_deconstruct], "deconstruct", dyntool_image_backward(tool_deconstruct)) if(tool_unanchor && !isnull(default_unanchor)) - LAZYADD(.[tool_panel], anchored? "unanchor" : "anchor") + LAZYSET(.[tool_unanchor], anchored? "unanchor" : "anchor", anchored? dyntool_image_backward(tool_unanchor) : dyntool_image_forward(tool_unanchor)) if(tool_panel && !isnull(default_panel)) - LAZYADD(.[tool_panel], panel_open? "close panel" : "open panel") + LAZYSET(.[tool_panel], panel_open? "close panel" : "open panel", panel_open? dyntool_image_forward(tool_panel) : dyntool_image_backward(tool_panel)) return merge_double_lazy_assoc_list(., ..()) -/obj/machinery/dynamic_tool_image(function, hint) - switch(hint) - if("anchor", "close panel") - return dyntool_image_backward(function) - if("unanchor", "open panel", "deconstruct") - return dyntool_image_backward(function) - return ..() - /obj/machinery/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) if(INTERACTING_WITH_FOR(e_args.performer, src, INTERACTING_FOR_CONSTRUCTION)) return CLICKCHAIN_DO_NOT_PROPAGATE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 1f74e6d05ebb..66932c19e19d 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -552,14 +552,9 @@ if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(e_args.performer)) return ..() . = list() - .[obj_cell_slot.remove_tool_behavior] = "remove cell" + LAZYSET(.[obj_cell_slot.remove_tool_behavior], "remove cell", dyntool_image_backward(obj_cell_slot.remove_tool_behavior)) return merge_double_lazy_assoc_list(..(), .) -/obj/dynamic_tool_image(function, hint) - if(hint == "remove cell") - return dyntool_image_backward(function) - return ..() - /obj/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) if(isnull(obj_cell_slot) || (obj_cell_slot.remove_tool_behavior != function) || !obj_cell_slot.interaction_active(e_args.performer)) return ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 645848616be9..3305b6c839fe 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -510,49 +510,47 @@ /obj/structure/window/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) if (construction_state == WINDOW_STATE_UNSECURED) . = list( - TOOL_SCREWDRIVER = TOOL_HINT_SCREWING_WINDOW_FRAME, - TOOL_WRENCH + TOOL_SCREWDRIVER = list( + "fasten frame" = dyntool_image_forward(TOOL_SCREWDRIVER), + ), + TOOL_WRENCH = list( + "deconstruct" = dyntool_image_backward(TOOL_WRENCH), + ), ) else if (!considered_reinforced) . = list( - TOOL_SCREWDRIVER = TOOL_HINT_UNSCREWING_WINDOW_FRAME + TOOL_SCREWDRIVER = list( + "unfasten frame" = dyntool_image_backward(TOOL_SCREWDRIVER), + ), ) else switch (construction_state) if (WINDOW_STATE_SCREWED_TO_FLOOR) . = list( - TOOL_SCREWDRIVER = TOOL_HINT_UNSCREWING_WINDOW_FRAME, - TOOL_CROWBAR = TOOL_HINT_CROWBAR_WINDOW_IN + TOOL_SCREWDRIVER = list( + "unfasten frame" = dyntool_image_backward(TOOL_SCREWDRIVER), + ), + TOOL_CROWBAR = list( + "seat pane" = dyntool_image_forward(TOOL_CROWBAR), + ), ) if (WINDOW_STATE_CROWBRARED_IN) . = list( - TOOL_SCREWDRIVER = TOOL_HINT_SCREWING_WINDOW_PANE, - TOOL_CROWBAR = TOOL_HINT_CROWBAR_WINDOW_OUT + TOOL_SCREWDRIVER = list( + "fasten pane" = dyntool_image_forward(TOOL_SCREWDRIVER), + ), + TOOL_CROWBAR = list( + "unseat pane" = dyntool_image_backward(TOOL_CROWBAR), + ), ) if (WINDOW_STATE_SECURED_TO_FRAME) . = list( - TOOL_SCREWDRIVER = TOOL_HINT_UNSCREWING_WINDOW_PANE + TOOL_SCREWDRIVER = list( + "unfasten pane" = dyntool_image_backward(TOOL_SCREWDRIVER), + ), ) return merge_double_lazy_assoc_list(., ..()) - -/obj/structure/window/dynamic_tool_image(function, hint) - switch (hint) - if (TOOL_HINT_CROWBAR_WINDOW_IN) - return dyntool_image_forward(TOOL_CROWBAR) - if (TOOL_HINT_CROWBAR_WINDOW_OUT) - return dyntool_image_backward(TOOL_CROWBAR) - if (TOOL_HINT_SCREWING_WINDOW_FRAME) - return dyntool_image_forward(TOOL_SCREWDRIVER) - if (TOOL_HINT_UNSCREWING_WINDOW_FRAME) - return dyntool_image_backward(TOOL_SCREWDRIVER) - if (TOOL_HINT_SCREWING_WINDOW_PANE) - return dyntool_image_forward(TOOL_SCREWDRIVER) - if (TOOL_HINT_UNSCREWING_WINDOW_PANE) - return dyntool_image_backward(TOOL_SCREWDRIVER) - return ..() - - //This proc is used to update the icons of nearby windows. /obj/structure/window/proc/update_nearby_icons() update_appearance() diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 6a71505a7481..6a0a2b161064 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -121,13 +121,7 @@ /obj/structure/aquarium/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = ..() if(allow_unanchor) - .[TOOL_WRENCH] = anchored? "anchor" : "unanchor" - -/obj/structure/aquarium/dynamic_tool_image(function, hint) - switch(function) - if(TOOL_WRENCH) - return anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH) - return ..() + LAZYSET(.[TOOL_WRENCH], anchored? "unanchor" : "anchor", anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH)) /obj/structure/aquarium/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!allow_unanchor) diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 5fab9a8e8b6c..5936ce3b4d7e 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -185,22 +185,10 @@ /obj/structure/sculpting_block/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() - .[TOOL_WRENCH] = anchored? "unanchor" : "anchor" - .[TOOL_WELDER] = "deconstruct" + LAZYSET(.[TOOL_WRENCH], anchored? "unanchor" : "anchor", anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH)) + LAZYSET(.[TOOL_WELDER], "deconstruct", dyntool_image_backward(TOOL_WELDER)) return merge_double_lazy_assoc_list(., ..()) -/obj/structure/sculpting_block/dynamic_tool_image(function, hint) - . = ..() - if(.) - return - switch(hint) - if("unanchor") - return dyntool_image_backward(TOOL_WRENCH) - if("anchor") - return dyntool_image_forward(TOOL_WRENCH) - if("deconstruct") - return dyntool_image_backward(TOOL_WELDER) - /** * returns speed multiplier, or null if not tool */ diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index 069eb893609c..ee2fadc8d986 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -73,7 +73,6 @@ if(function) // automation, just go return _dynamic_tool_act(provided_item, e_args, function, TOOL_OP_AUTOPILOT | TOOL_OP_REAL, hint) - var/list/hint_images = list() // used in clickchain // as of now, format is: // function = hint OR list(hint, ...) @@ -267,7 +266,7 @@ * returns a list of behaviours that can be used on us in our current state * the behaviour may be associated to a list of "hints" for multiple possible actions per behaviour. * the hint should be human readable. - * associating directly to a single hint is allowed. + * hints can / should be associated to images for graphics, otherwise defaults to dyntool neutral images * * **warning**: by default, the provided list is mutable * if you're caching your own list, make sure to return cache.Copy()! @@ -275,11 +274,10 @@ * @params * * I - the tool used, if any * * user - the user, if any - * * hint_images - allows us to immediately associate hints to specific images without calling dynamic_tool_image after. usually not what you want, as this isn't lazy. */ -/atom/proc/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/atom/proc/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args) . = list() - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, e_args, ., hint_images) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, e_args, .) /atom/proc/_dynamic_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) PRIVATE_PROC(TRUE) @@ -303,25 +301,3 @@ */ /atom/proc/dynamic_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) return tool_act(I, e_args, function, flags, hint) - -/** - * builds the image used for the radial icon - * - * WARNING: If you use tool **and** hint, you need to implement a hintless, or return to base to use the default. - * - * @params - * * function - the tool behaviour - * * hint - the context provided when you want to implement multiple actions for a tool - */ -/atom/proc/dynamic_tool_image(function, hint) - return dyntool_image_neutral(function) - -//! Dynamic Tools - default images -/proc/dyntool_image_neutral(function) - return image('icons/screen/radial/tools/generic.dmi', icon_state = _dyntool_image_states[function] || "unknown") - -/proc/dyntool_image_forward(function) - return image('icons/screen/radial/tools/generic.dmi', icon_state = "[_dyntool_image_states[function] || "unknown"]_up") - -/proc/dyntool_image_backward(function) - return image('icons/screen/radial/tools/generic.dmi', icon_state = "[_dyntool_image_states[function] || "unknown"]_down") diff --git a/code/modules/tools/visuals.dm b/code/modules/tools/visuals.dm new file mode 100644 index 000000000000..90516413ec42 --- /dev/null +++ b/code/modules/tools/visuals.dm @@ -0,0 +1,8 @@ +/proc/dyntool_image_neutral(function) + return image('icons/screen/radial/tools/generic.dmi', icon_state = _dyntool_image_states[function] || "unknown") + +/proc/dyntool_image_forward(function) + return image('icons/screen/radial/tools/generic.dmi', icon_state = "[_dyntool_image_states[function] || "unknown"]_up") + +/proc/dyntool_image_backward(function) + return image('icons/screen/radial/tools/generic.dmi', icon_state = "[_dyntool_image_states[function] || "unknown"]_down") From dfe0997e0b1d0116b1537e3da31f834af04bf419 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 16:37:31 -0700 Subject: [PATCH 23/33] refactor that --- .../dcs/signals/signals_atom/tool_system.dm | 4 +- .../game/machinery/_machinery_construction.dm | 2 +- code/game/machinery/misc/bioscan_antenna.dm | 2 +- code/game/objects/objs.dm | 2 +- code/game/objects/structures/window.dm | 2 +- code/modules/fishing/aquarium/aquarium.dm | 2 +- .../projectiles/ammunition/ammo_casing.dm | 2 +- code/modules/sculpting/sculpting_block.dm | 2 +- code/modules/tools/_tool_system.dm | 89 ++++++++++--------- 9 files changed, 54 insertions(+), 53 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm index 92399f327674..5d9c7ab9c1de 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/tool_system.dm @@ -4,7 +4,7 @@ /// from base of _tool_act: (I, user, function, flags, hint) where I = item, e_args = clickchain data, function = tool behaviour, flags = tool operation flags, hint = set by dynamic tool system /// return CLICKCHAIN_COMPONENT_SIGNAL_HANDLED to abort normal tool_act handling. #define COMSIG_ATOM_TOOL_ACT "tool_act" -/// from base of dynamic_tool_functions: (I, datum/event_args/actor/clickchain/e_args, functions) where I = item, e_args = clickchain data. +/// from base of dynamic_tool_query: (I, datum/event_args/actor/clickchain/e_args, functions) where I = item, e_args = clickchain data. /// inject by merging into functions /// remember to use merge_double_lazy_assoc_list() to merge function lists! -#define COMSIG_ATOM_TOOL_FUNCTIONS "tool_functions" +#define COMSIG_ATOM_TOOL_QUERY "tool_functions" diff --git a/code/game/machinery/_machinery_construction.dm b/code/game/machinery/_machinery_construction.dm index 3e5ddd9aa2fa..025d3d1b213c 100644 --- a/code/game/machinery/_machinery_construction.dm +++ b/code/game/machinery/_machinery_construction.dm @@ -1,7 +1,7 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -/obj/machinery/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/machinery/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() if(tool_deconstruct && !isnull(default_deconstruct) && panel_open) LAZYSET(.[tool_deconstruct], "deconstruct", dyntool_image_backward(tool_deconstruct)) diff --git a/code/game/machinery/misc/bioscan_antenna.dm b/code/game/machinery/misc/bioscan_antenna.dm index 2e3ccc9f0096..286bd68c62b0 100644 --- a/code/game/machinery/misc/bioscan_antenna.dm +++ b/code/game/machinery/misc/bioscan_antenna.dm @@ -49,7 +49,7 @@ GLOBAL_LIST_EMPTY(bioscan_antenna_list) ) change_network(new_network) -/obj/machinery/bioscan_antenna/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/machinery/bioscan_antenna/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() if(network_mutable) .[TOOL_MULTITOOL] = "change network" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 66932c19e19d..3b82a6c0ecde 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -548,7 +548,7 @@ //? Tool System -/obj/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) if(isnull(obj_cell_slot) || !obj_cell_slot.remove_tool_behavior || !obj_cell_slot.interaction_active(e_args.performer)) return ..() . = list() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 3305b6c839fe..1e8b1d22cd9b 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -507,7 +507,7 @@ deconstruct(ATOM_DECONSTRUCT_DISASSEMBLED) -/obj/structure/window/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/structure/window/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) if (construction_state == WINDOW_STATE_UNSECURED) . = list( TOOL_SCREWDRIVER = list( diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 6a0a2b161064..51ff4fd5641e 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -118,7 +118,7 @@ update_appearance() return TRUE -/obj/structure/aquarium/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/structure/aquarium/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = ..() if(allow_unanchor) LAZYSET(.[TOOL_WRENCH], anchored? "unanchor" : "anchor", anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH)) diff --git a/code/modules/projectiles/ammunition/ammo_casing.dm b/code/modules/projectiles/ammunition/ammo_casing.dm index 6db71addfe76..cb3a53a228dc 100644 --- a/code/modules/projectiles/ammunition/ammo_casing.dm +++ b/code/modules/projectiles/ammunition/ammo_casing.dm @@ -64,7 +64,7 @@ e_args.chat_feedback(SPAN_NOTICE("You inscribe [label_text] into \the [initial(stored.name)]."), src) stored.name = "[initial(stored.name)] (\"[label_text]\")" -/obj/item/ammo_casing/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/item/ammo_casing/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list( TOOL_SCREWDRIVER = list( "etch" diff --git a/code/modules/sculpting/sculpting_block.dm b/code/modules/sculpting/sculpting_block.dm index 5936ce3b4d7e..c3cf53eb47ee 100644 --- a/code/modules/sculpting/sculpting_block.dm +++ b/code/modules/sculpting/sculpting_block.dm @@ -183,7 +183,7 @@ . = ..() material.place_sheet(drop_location(), 10) -/obj/structure/sculpting_block/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) +/obj/structure/sculpting_block/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images = list()) . = list() LAZYSET(.[TOOL_WRENCH], anchored? "unanchor" : "anchor", anchored? dyntool_image_backward(TOOL_WRENCH) : dyntool_image_forward(TOOL_WRENCH)) LAZYSET(.[TOOL_WELDER], "deconstruct", dyntool_image_backward(TOOL_WELDER)) diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index ee2fadc8d986..cde806324820 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -1,8 +1,6 @@ //* This file is explicitly licensed under the MIT license. *// //* Copyright (c) 2023 Citadel Station developers. *// -#warn use /datum/event_args/actor/e_args - /** * ? Atom Tool API * @@ -26,10 +24,10 @@ * return TRUE // halt attack chain * * intended api for dynamic tool usage: - * * override dynamic_tool_functions() to return the functions and minimal qualities for a user + * * override dynamic_tool_query() to return the functions and minimal qualities for a user * * override dynamic_tool_act() if needed, otherwise it will simply go into tool_act * * override dynamic_tool_image() to return the image to render for a specific tool function for radials - * * realistically, you just need to override dynamic_tool_functions. + * * realistically, you just need to override dynamic_tool_query. * * if you don't override dynamic_tool_image you are a lemming and it'll probabl be ugly. * * It's That Simple (tm)! @@ -77,24 +75,22 @@ // as of now, format is: // function = hint OR list(hint, ...) // hint images is passed in so it can be prebuilt by components - // more info is in comment of dynamic_tool_functions - var/list/possibilities = dynamic_tool_functions(provided_item, e_args, hint_images) + // more info is in comment of dynamic_tool_query + var/list/possibilities = dynamic_tool_query(provided_item, e_args) if(!length(possibilities) || (provided_item.tool_locked == TOOL_LOCKING_STATIC)) // no dynamic tool functionality, or dynamic functionality disabled, route normally. function = provided_item.tool_behaviour() if(!function) return NONE return _tool_act(provided_item, e_args, function, TOOL_OP_REAL) - #warn possibilities is fundamentally used incorrectly later, we might - #warn have to refactor this to not use dynamic_tool_image at all. + var/list/functions = provided_item.tool_query(e_args, src) // enumerate - var/list/functions = provided_item.tool_query(user, src) if((provided_item.tool_locked == TOOL_LOCKING_AUTO) && (length(functions) == 1)) // use first function function = functions[1] - if(!(function in possibilities)) + if(isnull(possibilities[function])) // not found, route normally - return _tool_act(provided_item, user, function, TOOL_OP_REAL) + return _tool_act(provided_item, e_args, function, TOOL_OP_REAL) else for(var/i in possibilities) if(functions[i]) @@ -105,60 +101,65 @@ function = provided_item.tool_behaviour() if(!function) return NONE - return _tool_act(provided_item, user, function, TOOL_OP_REAL) + return _tool_act(provided_item, e_args, function, TOOL_OP_REAL) + // possibilities is now filtered // everything in possibilities is valid for the tool var/list/transformed = list() + // check if we have function locked already if(!function) // we're about to sleep; if we're already breaking from this, maybe like, don't - if(INTERACTING_WITH_FOR(user, src, INTERACTING_FOR_DYNAMIC_TOOL)) + if(INTERACTING_WITH_FOR(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL)) return CLICKCHAIN_DO_NOT_PROPAGATE // if we didn't pick function already - for(var/i in possibilities) - // is there only one hint? - var/list/associated = possibilities[i] - if(associated && (!islist(associated) || (length(associated) == 1))) - // yes there is! - associated = islist(associated)? associated[1] : associated + for(var/potential_function in possibilities) + var/list/potential_hints = possibilities[potential_function] + var/image/radial_render + var/radial_text = potential_function + if(length(potential_hints) == 1) + radial_text = potential_hints[1] + radial_render = potential_hints[hint] || dyntool_image_neutral(potential_function) else - associated = null - var/image/I = dynamic_tool_image(i, associated) - I.maptext = MAPTEXT_CENTER(associated || i) - I.maptext_x = -16 - I.maptext_y = 32 - I.maptext_width = 64 - transformed[i] = I + radial_render = dyntool_image_neutral(potential_function) + radial_render.maptext = MAPTEXT_CENTER(radial_text) + radial_render.maptext_x = -16 + radial_render.maptext_y = 32 + radial_render.maptext_width = 64 + transformed[potential_function] = radial_render // todo: radial menu at some point should be made to automatically close when they click something else. - START_INTERACTING_WITH(user, src, INTERACTING_FOR_DYNAMIC_TOOL) - function = show_radial_menu(user, src, transformed, custom_check = reachability_check) - STOP_INTERACTING_WITH(user, src, INTERACTING_FOR_DYNAMIC_TOOL) + // todo: the initiator/performer pattern doesn't work well with radial menu and interacting with + // todo: because there's no semantics for mutexing the performer vs the initator + // todo: in the future, we are going to want to get a proper mutex up for tool interactions + START_INTERACTING_WITH(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL) + function = show_radial_menu(e_args.initiator, src, transformed, custom_check = reachability_check) + STOP_INTERACTING_WITH(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL) if(!function || (reachability_check && !reachability_check.Invoke())) return CLICKCHAIN_DO_NOT_PROPAGATE // determine hint var/list/hints = possibilities[function] if(!islist(hints)) // is a direct hint or null - return _dynamic_tool_act(provided_item, user, function, TOOL_OP_REAL, hints) + return _dynamic_tool_act(provided_item, e_args, function, TOOL_OP_REAL, hints) else if(length(hints) <= 1) // no hint, or only one hint - return _dynamic_tool_act(provided_item, user, function, TOOL_OP_REAL, length(hints)? hints[1] : null) + return _dynamic_tool_act(provided_item, e_args, function, TOOL_OP_REAL, length(hints)? hints[1] : null) // we're about to sleep; if we're already breaking from this, maybe like, don't - if(INTERACTING_WITH_FOR(user, src, INTERACTING_FOR_DYNAMIC_TOOL)) + if(INTERACTING_WITH_FOR(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL)) return CLICKCHAIN_DO_NOT_PROPAGATE transformed.len = 0 for(var/i in hints) - var/image/I = dynamic_tool_image(function, i) - I.maptext = MAPTEXT_CENTER(i) - I.maptext_x = -16 - I.maptext_y = 32 - I.maptext_width = 64 - transformed[i] = I - START_INTERACTING_WITH(user, src, INTERACTING_FOR_DYNAMIC_TOOL) - hint = show_radial_menu(user, src, transformed, custom_check = reachability_check) - STOP_INTERACTING_WITH(user, src, INTERACTING_FOR_DYNAMIC_TOOL) + var/image/radial_render = hints[i] || dyntool_image_neutral(function) + radial_render.maptext = MAPTEXT_CENTER(i) + radial_render.maptext_x = -16 + radial_render.maptext_y = 32 + radial_render.maptext_width = 64 + transformed[i] = radial_render + START_INTERACTING_WITH(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL) + hint = show_radial_menu(e_args.initiator, src, transformed, custom_check = reachability_check) + STOP_INTERACTING_WITH(e_args.initiator, src, INTERACTING_FOR_DYNAMIC_TOOL) if(!hint || (reachability_check && !reachability_check.Invoke())) return CLICKCHAIN_DO_NOT_PROPAGATE // use hint - return _dynamic_tool_act(provided_item, user, function, TOOL_OP_REAL, hint) | CLICKCHAIN_DO_NOT_PROPAGATE + return _dynamic_tool_act(provided_item, e_args, function, TOOL_OP_REAL, hint) | CLICKCHAIN_DO_NOT_PROPAGATE else // in the future, we might have situations where clicking something with an empty hand // yet having organs that server as built-in tools can do something with @@ -275,9 +276,9 @@ * * I - the tool used, if any * * user - the user, if any */ -/atom/proc/dynamic_tool_functions(obj/item/I, datum/event_args/actor/clickchain/e_args) +/atom/proc/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args) . = list() - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_FUNCTIONS, I, e_args, .) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_QUERY, I, e_args, .) /atom/proc/_dynamic_tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint) PRIVATE_PROC(TRUE) From 495e9ead5baa964fcb98a429206fca1aac20f85e Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 16:59:46 -0700 Subject: [PATCH 24/33] fix --- code/__DEFINES/procs/clickcode.dm | 8 ++++++++ code/game/click/context.dm | 6 ++++++ code/game/click/reachability.dm | 26 +++++++++++++++----------- code/game/objects/objs.dm | 14 ++++++++++++-- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm index 66b60deaee3b..9e38b340ea9c 100644 --- a/code/__DEFINES/procs/clickcode.dm +++ b/code/__DEFINES/procs/clickcode.dm @@ -40,3 +40,11 @@ //! Reachability Depths - checked from level of DirectAccess and turf adjacency. /// default reachability depth #define DEFAULT_REACHABILITY_DEPTH 3 // enough to reach into pill bottles in box in backpack + +//! Reachability +/// can't reach - this *must* be a fals-y value. +#define REACH_FAILED 0 +/// can physically reach normally +#define REACH_PHYSICAL 1 +/// can reach with something like telekinesis +#define REACH_INDIRECT 2 diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 5c7737d45a18..8bf897f4647a 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -16,6 +16,8 @@ /** * act on a context option * + * things in this should re-check validity / sanity! + * * @return TRUE / FALSE; TRUE if handled. */ /atom/proc/context_act(datum/event_args/actor/e_args, key) @@ -27,4 +29,8 @@ // admin proccall support WRAP_MOB_TO_ACTOR_EVENT_ARGS(e_args) // todo: dynamically rebuild menu based on distance? + var/client/receiving = e_args.initiator.client + if(isnull(receiving)) + // well what the hell are we doing here? + // automated functions should be using context_query and context_act directly #warn impl diff --git a/code/game/click/reachability.dm b/code/game/click/reachability.dm index 6627d906b6d4..9623a1cd899f 100644 --- a/code/game/click/reachability.dm +++ b/code/game/click/reachability.dm @@ -27,6 +27,10 @@ * - for loop runs 3 times, hits turf, doesn't add turf area * - TurfAdjacency is checked since it isn't a ranged attack * + * Caveats: + * * This is not enough for 'can we physically reach'; that should be Adjacency. This is because telekinesis is a thing, and will be added later. + * * For this reason, the cost is higher than just checking 'can telekinesis', because telekinesis is checked after physical, as physical is stronger. + * * @params * - target - the target * - depth - max depth - should be at least 1 in most cases. @@ -36,12 +40,12 @@ /atom/movable/proc/Reachability(atom/target, depth = DEFAULT_REACHABILITY_DEPTH, range = 1, obj/item/tool) if(!target) // apologies sir, you may not grasp the void... - return FALSE + return REACH_FAILED // direct cache - check if we can access something using if dc[atom] var/list/dc = DirectAccessCache() // optimization - a lot of the time we're clicking on ourselves/things on ourselves if(dc[target]) - return TRUE + return REACH_PHYSICAL // turf adjacency enabled? stores if we can try to path to our turf var/turf/tadj // loc checking @@ -105,7 +109,7 @@ continue if(dc[l]) // found - return TRUE + return REACH_PHYSICAL if(isturf(l) && !th) // is turf; turf adjacency enabled th = l @@ -117,7 +121,7 @@ ++i if(!(tadj && th)) // didn't hit both, fail - return FALSE + return REACH_FAILED // at this point, we're on a turf if(range == 1) // most common case: reach directly aronud yourself @@ -136,18 +140,18 @@ if(n.TurfAdjacency(th)) // succeeded qdel(D) - return TRUE + return REACH_PHYSICAL // dumb directional pathfinding both for cheapness and for practical purposes // so you can't snake-arms round a row of windows or something crazy n = get_step(D, get_dir(D, th)) if(!D.Move(n)) // failed qdel(D) - return FALSE + return REACH_FAILED // keep going // at this point, we failed qdel(D) - return FALSE + return REACH_FAILED /** * quick and dirty reachability check @@ -160,18 +164,18 @@ if(isturf(curr)) source = get_turf(src) if(!source) - return FALSE + return REACH_FAILED return curr.TurfAdjacency(source) do if(curr == src) - return TRUE + return REACH_PHYSICAL if(!curr) - return FALSE + return REACH_FAILED curr = curr.loc while(!isturf(curr)) source = get_turf(src) if(!source) - return FALSE + return REACH_FAILED return curr.TurfAdjacency(source) /atom/movable/reachability_delegate diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3b82a6c0ecde..9ac54892885e 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -417,8 +417,14 @@ /obj/context_act(datum/event_args/actor/e_args, key) if(key == "obj_cell_slot") + var/reachability = e_args.performer.Reachability(src) + if(!reachability) + return TRUE + if(!CHECK_MOBILITY(e_args.performer, MOBILITY_CAN_USE)) + e_args.initiator.action_feedback(SPAN_WARNING("You can't do that right now!"), src) + return TRUE if(isnull(obj_cell_slot.cell)) - e_args.performer.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) + e_args.initiator.action_feedback(SPAN_WARNING("[src] doesn't have a cell installed.")) return TRUE if(!obj_cell_slot.interaction_active(e_args.performer)) return TRUE @@ -430,7 +436,11 @@ otherwise_self = SPAN_NOTICE("You remove the cell from [src]."), ) log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") - e_args.performer.put_in_hands_or_drop(obj_cell_slot.remove_cell(e_args.performer)) + var/obj/item/cell/removed = obj_cell_slot.remove_cell(src) + if(reachability == REACH_PHYSICAL) + e_args.performer.put_in_hands_or_drop() + else + removed.forceMove(drop_location()) return TRUE return ..() From bb5d9a3aeaf3d11cf66b180c6326ce151882dfff Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 17:08:27 -0700 Subject: [PATCH 25/33] context --- code/game/click/context.dm | 46 +++++++++++++++++++++++++++- code/game/rendering/legacy/radial.dm | 3 +- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 8bf897f4647a..5cbaf69c0450 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -26,6 +26,7 @@ return FALSE /atom/proc/context_menu(datum/event_args/actor/e_args) + set waitfor = FALSE // admin proccall support WRAP_MOB_TO_ACTOR_EVENT_ARGS(e_args) // todo: dynamically rebuild menu based on distance? @@ -33,4 +34,47 @@ if(isnull(receiving)) // well what the hell are we doing here? // automated functions should be using context_query and context_act directly - #warn impl + return FALSE + if(context_menus[receiving]) + // close + log_click_context(e_args, src, "menu close") + qdel(context_menus[receiving]) + return TRUE + var/list/menu_options = context_query(e_args) + if(!length(menu_options)) + return FALSE + // open + log_click_context(e_args, src, "menu open") + . = TRUE + blocking_context_menu(e_args) + +/atom/proc/blocking_context_menu(datum/event_args/actor/e_args) + // for now, we just filter without auto-updating/rebuilding when things change + var/list/transformed = list() + var/list/inverse_lookup = list() + for(var/key as anything in menu_options) + var/list/data = menu_options[key] + transformed[data[1]] = data[2] + inverse_lookup[data[1]] = key + + var/datum/radial_menu/context_menu/menu = new + var/id = "context_[REF(e_args.initiator)]" + GLOB.radial_menus[id] = menu + context_menus[receiving] = menu + + menu.radius = 16 + menu.check_screen_border(receiving.mob) + menu.set_choices(transformed, FALSE) + menu.show_to(receiving.mob) + menu.wait(receiving.mob, src, TRUE) + + var/chosen_name = menu.selected_choice + + qdel(menu) + GLOB.radial_menus -= id + + if(isnull(chosen_name)) + return + + var/key = inverse_lookup[chosen_name] + context_act(e_args, key) diff --git a/code/game/rendering/legacy/radial.dm b/code/game/rendering/legacy/radial.dm index 464001674da3..13811309cfdd 100644 --- a/code/game/rendering/legacy/radial.dm +++ b/code/game/rendering/legacy/radial.dm @@ -316,7 +316,8 @@ GLOBAL_LIST_EMPTY(radial_menus) return answer /datum/radial_menu/context_menu + // todo: this needs such a drastic fucking refactor along with the rest of this file i'm going to scream -/datum/radial_menu/Destroy() +/datum/radial_menu/context_menu/Destroy() LAZYREMOVE(anchor.context_menus, current_user) return ..() From ffc3f64a7ad89143732aaaf91fc172562c88337b Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 18:44:40 -0700 Subject: [PATCH 26/33] Fixes --- code/game/click/context.dm | 12 ++++++++---- code/game/objects/objs.dm | 18 ++++++++++++++++++ code/game/objects/systems/cell_slot.dm | 4 ++-- code/modules/tools/_tool_system.dm | 5 +++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 5cbaf69c0450..39b6316ddf7a 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -35,7 +35,7 @@ // well what the hell are we doing here? // automated functions should be using context_query and context_act directly return FALSE - if(context_menus[receiving]) + if(context_menus?[receiving]) // close log_click_context(e_args, src, "menu close") qdel(context_menus[receiving]) @@ -46,21 +46,25 @@ // open log_click_context(e_args, src, "menu open") . = TRUE - blocking_context_menu(e_args) + blocking_context_menu(e_args, receiving, menu_options, e_args.performer) -/atom/proc/blocking_context_menu(datum/event_args/actor/e_args) +/atom/proc/blocking_context_menu(datum/event_args/actor/e_args, client/receiving, list/menu_options, mob/actor) // for now, we just filter without auto-updating/rebuilding when things change var/list/transformed = list() var/list/inverse_lookup = list() for(var/key as anything in menu_options) var/list/data = menu_options[key] + if(!CHECK_ALL_MOBILITY(actor, data[4])) + continue + if(isnull(data[3])? !actor.Adjacent(src) : get_dist(actor, src) > data[3]) + continue transformed[data[1]] = data[2] inverse_lookup[data[1]] = key var/datum/radial_menu/context_menu/menu = new var/id = "context_[REF(e_args.initiator)]" GLOB.radial_menus[id] = menu - context_menus[receiving] = menu + LAZYSET(context_menus, receiving, menu) menu.radius = 16 menu.check_screen_border(receiving.mob) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9ac54892885e..7fb4e171f2eb 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -245,6 +245,24 @@ //? Attacks +/obj/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier) + if(user.a_intent == INTENT_HARM) + return ..() + if(istype(I, /obj/item/cell) && !isnull(obj_cell_slot) && isnull(obj_cell_slot.cell) && obj_cell_slot.interaction_active(user)) + if(!user.transfer_item_to_loc(I, src)) + user.action_feedback(SPAN_WARNING("[I] is stuck to your hand!"), src) + return CLICKCHAIN_DO_NOT_PROPAGATE + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[e_args.performer] inserts [I] into [src]."), + audible_hard = SPAN_NOTICE("You hear something being slotted in."), + visible_self = SPAN_NOTICE("You insert [I] into [src]."), + ) + obj_cell_slot.insert_cell(I) + return CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING + return ..() + /obj/on_attack_hand(datum/event_args/actor/clickchain/e_args) . = ..() if(.) diff --git a/code/game/objects/systems/cell_slot.dm b/code/game/objects/systems/cell_slot.dm index e772c9b37097..bf4e4e138807 100644 --- a/code/game/objects/systems/cell_slot.dm +++ b/code/game/objects/systems/cell_slot.dm @@ -27,7 +27,7 @@ var/remove_tool_behavior = null /// tool time for removal, if any var/remove_tool_time = 0 - /// removal is discrete or loud + /// removal / insertion is discrete or loud var/remove_is_discrete = TRUE /// legacy // todo: kill this @@ -40,9 +40,9 @@ if(isnull(cell)) return . = cell - cell = null if(cell.loc != new_loc) cell.forceMove(new_loc) + cell = null parent.object_cell_slot_removed(., src) /datum/object_system/cell_slot/proc/insert_cell(obj/item/cell/cell) diff --git a/code/modules/tools/_tool_system.dm b/code/modules/tools/_tool_system.dm index cde806324820..e2d49b770d6a 100644 --- a/code/modules/tools/_tool_system.dm +++ b/code/modules/tools/_tool_system.dm @@ -114,11 +114,12 @@ for(var/potential_function in possibilities) var/list/potential_hints = possibilities[potential_function] var/image/radial_render - var/radial_text = potential_function + var/radial_text if(length(potential_hints) == 1) radial_text = potential_hints[1] - radial_render = potential_hints[hint] || dyntool_image_neutral(potential_function) + radial_render = potential_hints[radial_text] || dyntool_image_neutral(potential_function) else + radial_text = potential_function radial_render = dyntool_image_neutral(potential_function) radial_render.maptext = MAPTEXT_CENTER(radial_text) radial_render.maptext_x = -16 From bc8cc29f84cfa52e415dd410c95d4b32953fc8d3 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 18:51:32 -0700 Subject: [PATCH 27/33] Fix --- code/game/click/context.dm | 1 + code/game/objects/items/inducer.dm | 2 +- code/game/objects/objs.dm | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 39b6316ddf7a..93bcde9809d5 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -67,6 +67,7 @@ LAZYSET(context_menus, receiving, menu) menu.radius = 16 + menu.anchor = src menu.check_screen_border(receiving.mob) menu.set_choices(transformed, FALSE) menu.show_to(receiving.mob) diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index ad6f44ad510d..60d92ca5d80e 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -167,7 +167,7 @@ ..() cut_overlays() if(opened) - if(!isnull(obj_cell_slot.cell)) + if(isnull(obj_cell_slot.cell)) add_overlay("inducer-nobat") else add_overlay("inducer-bat") diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 7fb4e171f2eb..f6961e406e87 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -255,7 +255,7 @@ user.visible_action_feedback( target = src, hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, - visible_hard = SPAN_NOTICE("[e_args.performer] inserts [I] into [src]."), + visible_hard = SPAN_NOTICE("[user] inserts [I] into [src]."), audible_hard = SPAN_NOTICE("You hear something being slotted in."), visible_self = SPAN_NOTICE("You insert [I] into [src]."), ) From 3f7949a37ffd9e09320cd4e8321a04bd3aa2112d Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 18:56:13 -0700 Subject: [PATCH 28/33] Fix --- code/game/click/context.dm | 8 +++++++- code/game/objects/items/inducer.dm | 5 ----- code/game/objects/objs.dm | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 93bcde9809d5..31ab74449c84 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -58,7 +58,13 @@ continue if(isnull(data[3])? !actor.Adjacent(src) : get_dist(actor, src) > data[3]) continue - transformed[data[1]] = data[2] + var/image/I = data[2] + // todo: why isn't radial menu doing this procesisng? + I.maptext_x = -16 + I.maptext_y = 32 + I.maptext_width = 64 + I.maptext = MAPTEXT_CENTER(data[1]) + transformed[data[1]] = I inverse_lookup[data[1]] = key var/datum/radial_menu/context_menu/menu = new diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index 60d92ca5d80e..67b653310715 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -86,11 +86,6 @@ opened = FALSE update_icon() return - if(cantbeused(user)) - return - - if(recharge(W, user)) - return return ..() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f6961e406e87..100ee1e676b5 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -456,7 +456,7 @@ log_construction(e_args, src, "removed cell [obj_cell_slot.cell] ([obj_cell_slot.cell.type])") var/obj/item/cell/removed = obj_cell_slot.remove_cell(src) if(reachability == REACH_PHYSICAL) - e_args.performer.put_in_hands_or_drop() + e_args.performer.put_in_hands_or_drop(removed) else removed.forceMove(drop_location()) return TRUE From 758d2634c463b746d7edfaf0cfd34f9024eb1407 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 19:07:47 -0700 Subject: [PATCH 29/33] fix --- code/game/atoms/action_feedback.dm | 2 ++ code/game/click/context.dm | 11 ++++++----- code/game/click/item_attack.dm | 4 ++-- code/game/objects/items.dm | 20 ++++++++++++++++---- code/game/objects/objs.dm | 2 +- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/code/game/atoms/action_feedback.dm b/code/game/atoms/action_feedback.dm index 52a8466ca558..096a003c3c15 100644 --- a/code/game/atoms/action_feedback.dm +++ b/code/game/atoms/action_feedback.dm @@ -31,6 +31,8 @@ //! end var/hard_visible = visible_hard || visible_soft var/hard_audible = audible_hard || audible_soft + visible_self = visible_self || otherwise_self + visible_them = visible_them || otherwise_them // todo: all of this needs rewritten oh my god for(var/atom/movable/AM as anything in viewing) if(get_dist(AM, src) <= hard_range) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 31ab74449c84..7c747aa70ff1 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -60,10 +60,11 @@ continue var/image/I = data[2] // todo: why isn't radial menu doing this procesisng? - I.maptext_x = -16 - I.maptext_y = 32 - I.maptext_width = 64 - I.maptext = MAPTEXT_CENTER(data[1]) + if(I) + I.maptext_x = -16 + I.maptext_y = 32 + I.maptext_width = 64 + I.maptext = MAPTEXT_CENTER(data[1]) transformed[data[1]] = I inverse_lookup[data[1]] = key @@ -72,7 +73,7 @@ GLOB.radial_menus[id] = menu LAZYSET(context_menus, receiving, menu) - menu.radius = 16 + menu.radius = 32 menu.anchor = src menu.check_screen_border(receiving.mob) menu.set_choices(transformed, FALSE) diff --git a/code/game/click/item_attack.dm b/code/game/click/item_attack.dm index f249a92261b9..f64c8bb68fa4 100644 --- a/code/game/click/item_attack.dm +++ b/code/game/click/item_attack.dm @@ -29,10 +29,10 @@ avoid code duplication. This includes items that may sometimes act as a standard return A.attackby(src, user, params, clickchain_flags, attack_modifier) // No comment -/atom/proc/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier) +/atom/proc/attackby(obj/item/I, mob/user, list/params, clickchain_flags, damage_multiplier) return I.standard_melee_attack(src, user, clickchain_flags, params, damage_multiplier, user.zone_sel?.selecting, user.a_intent) -/mob/living/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier) +/mob/living/attackby(obj/item/I, mob/user, list/params, clickchain_flags, damage_multiplier) if(can_operate(src) && user.a_intent != INTENT_HARM && I.do_surgery(src,user)) return NONE if(attempt_vr(src,"vore_attackby",args)) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 020bb28213b8..ecf0da767c20 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -378,9 +378,9 @@ R.activate_module(src) R.hud_used.update_robot_modules_display() -/obj/item/attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/storage)) - var/obj/item/storage/S = W +/obj/item/attackby(obj/item/I, mob/user, list/params, clickchain_flags, damage_multiplier) + if(istype(I, /obj/item/storage)) + var/obj/item/storage/S = I if(S.use_to_pickup) if(S.collection_mode) //Mode is set to collect all items if(isturf(src.loc)) @@ -388,7 +388,19 @@ else if(S.can_be_inserted(src)) S.handle_item_insertion(src, user) - return + if(istype(I, /obj/item/cell) && !isnull(obj_cell_slot) && isnull(obj_cell_slot.cell) && obj_cell_slot.interaction_active(user)) + if(!user.transfer_item_to_loc(I, src)) + user.action_feedback(SPAN_WARNING("[I] is stuck to your hand!"), src) + return CLICKCHAIN_DO_NOT_PROPAGATE + user.visible_action_feedback( + target = src, + hard_range = obj_cell_slot.remove_is_discrete? 0 : MESSAGE_RANGE_CONSTRUCTION, + visible_hard = SPAN_NOTICE("[user] inserts [I] into [src]."), + audible_hard = SPAN_NOTICE("You hear something being slotted in."), + visible_self = SPAN_NOTICE("You insert [I] into [src]."), + ) + obj_cell_slot.insert_cell(I) + return CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING /obj/item/proc/talk_into(mob/M as mob, text) return diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 100ee1e676b5..34aa79d6c46f 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -245,7 +245,7 @@ //? Attacks -/obj/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier) +/obj/attackby(obj/item/I, mob/user, list/params, clickchain_flags, damage_multiplier) if(user.a_intent == INTENT_HARM) return ..() if(istype(I, /obj/item/cell) && !isnull(obj_cell_slot) && isnull(obj_cell_slot.cell) && obj_cell_slot.interaction_active(user)) From 9f2d04219916cb687784931039b97b337cfaae53 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 19:12:18 -0700 Subject: [PATCH 30/33] ack --- code/game/click/context.dm | 11 +++++------ code/game/objects/objs.dm | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 7c747aa70ff1..f83832b88767 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -58,13 +58,12 @@ continue if(isnull(data[3])? !actor.Adjacent(src) : get_dist(actor, src) > data[3]) continue - var/image/I = data[2] + var/image/I = data[2] || image() // todo: why isn't radial menu doing this procesisng? - if(I) - I.maptext_x = -16 - I.maptext_y = 32 - I.maptext_width = 64 - I.maptext = MAPTEXT_CENTER(data[1]) + I.maptext_x = -16 + I.maptext_y = 32 + I.maptext_width = 64 + I.maptext = MAPTEXT_CENTER(data[1]) transformed[data[1]] = I inverse_lookup[data[1]] = key diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 34aa79d6c46f..5019578d42aa 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -431,7 +431,8 @@ /obj/context_query(datum/event_args/actor/e_args) . = ..() if(!isnull(obj_cell_slot?.cell) && obj_cell_slot.remove_yank_context && obj_cell_slot.interaction_active(e_args.performer)) - .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", null, null, MOBILITY_CAN_USE) + var/image/rendered = image(obj_cell_slot.cell) + .["obj_cell_slot"] = ATOM_CONTEXT_TUPLE("remove cell", rendered, null, MOBILITY_CAN_USE) /obj/context_act(datum/event_args/actor/e_args, key) if(key == "obj_cell_slot") From 6050a8b23da84a465cda92ac4b931d586d8de169 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 19:20:25 -0700 Subject: [PATCH 31/33] fix --- code/game/click/context.dm | 11 ++++++----- code/game/rendering/legacy/radial.dm | 6 +++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index f83832b88767..7c747aa70ff1 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -58,12 +58,13 @@ continue if(isnull(data[3])? !actor.Adjacent(src) : get_dist(actor, src) > data[3]) continue - var/image/I = data[2] || image() + var/image/I = data[2] // todo: why isn't radial menu doing this procesisng? - I.maptext_x = -16 - I.maptext_y = 32 - I.maptext_width = 64 - I.maptext = MAPTEXT_CENTER(data[1]) + if(I) + I.maptext_x = -16 + I.maptext_y = 32 + I.maptext_width = 64 + I.maptext = MAPTEXT_CENTER(data[1]) transformed[data[1]] = I inverse_lookup[data[1]] = key diff --git a/code/game/rendering/legacy/radial.dm b/code/game/rendering/legacy/radial.dm index 13811309cfdd..0f850f96cd42 100644 --- a/code/game/rendering/legacy/radial.dm +++ b/code/game/rendering/legacy/radial.dm @@ -234,8 +234,12 @@ GLOBAL_LIST_EMPTY(radial_menus) choices += id choices_values[id] = E if(new_choices[E]) - var/I = extract_image(new_choices[E]) + var/image/I = extract_image(new_choices[E]) if(I) + //! perform fixup + I.plane = FLOAT_PLANE + I.layer = FLOAT_LAYER + //! end choices_icons[id] = I setup_menu(use_tooltips) From bf07887e8e301f7d6d20d8d7da8469b39ea80c08 Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 19:32:45 -0700 Subject: [PATCH 32/33] fix --- code/game/click/context.dm | 5 +++++ code/game/rendering/legacy/radial.dm | 5 ++++- code/modules/mob/inventory/items.dm | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/code/game/click/context.dm b/code/game/click/context.dm index 7c747aa70ff1..81c18774cdc2 100644 --- a/code/game/click/context.dm +++ b/code/game/click/context.dm @@ -74,6 +74,7 @@ LAZYSET(context_menus, receiving, menu) menu.radius = 32 + menu.host = src menu.anchor = src menu.check_screen_border(receiving.mob) menu.set_choices(transformed, FALSE) @@ -90,3 +91,7 @@ var/key = inverse_lookup[chosen_name] context_act(e_args, key) + +/atom/proc/context_close() + for(var/client/C as anything in context_menus) + qdel(context_menus[C]) diff --git a/code/game/rendering/legacy/radial.dm b/code/game/rendering/legacy/radial.dm index 0f850f96cd42..e470eeaba274 100644 --- a/code/game/rendering/legacy/radial.dm +++ b/code/game/rendering/legacy/radial.dm @@ -320,8 +320,11 @@ GLOBAL_LIST_EMPTY(radial_menus) return answer /datum/radial_menu/context_menu + /// host atom + var/atom/host // todo: this needs such a drastic fucking refactor along with the rest of this file i'm going to scream /datum/radial_menu/context_menu/Destroy() - LAZYREMOVE(anchor.context_menus, current_user) + LAZYREMOVE(host.context_menus, current_user) + host = null return ..() diff --git a/code/modules/mob/inventory/items.dm b/code/modules/mob/inventory/items.dm index aa38b32e5929..2abb30e06e34 100644 --- a/code/modules/mob/inventory/items.dm +++ b/code/modules/mob/inventory/items.dm @@ -101,6 +101,9 @@ if(zoom) zoom() //binoculars, scope, etc + // close context menus + context_close() + return ((. & COMPONENT_ITEM_DROPPED_RELOCATE)? ITEM_RELOCATED_BY_DROPPED : NONE) /** From d88e4a6d7f1d431b2cc5e82dfd6fe553bb90b1fd Mon Sep 17 00:00:00 2001 From: silicons Date: Thu, 28 Sep 2023 19:52:41 -0700 Subject: [PATCH 33/33] fix --- code/game/machinery/pipe/construction.dm | 5 ----- code/game/objects/items/weapons/RPD.dm | 4 +--- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index e26127bf7fb6..d56a9340f005 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -175,11 +175,6 @@ Buildable meters else return ..() -/obj/item/pipe/attackby(var/obj/item/W as obj, var/mob/user as mob) - if(W.is_wrench()) - return wrench_act(W, user) - return ..() - /obj/item/pipe/wrench_act(obj/item/I, datum/event_args/actor/clickchain/e_args, flags, hint) if(!isturf(loc)) return TRUE diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index 0aa4275b216f..c8fc53f016af 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -352,9 +352,7 @@ playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) /obj/item/pipe_dispenser/proc/do_wrench(var/atom/target, mob/user) - var/resolved = target.attackby(tool,user) - if(!resolved && tool && target) - tool.afterattack(target,user,1) + tool.melee_attack_chain(target, user, CLICKCHAIN_HAS_PROXIMITY) /obj/item/pipe_dispenser/proc/mouse_wheeled(mob/user, atom/A, delta_x, delta_y, params) SIGNAL_HANDLER