diff --git a/citadel.dme b/citadel.dme index d1f0fff9911..19499b43a5a 100644 --- a/citadel.dme +++ b/citadel.dme @@ -580,6 +580,7 @@ #include "code\datums\components\crafting\recipes\recipes_primal.dm" #include "code\datums\components\crafting\recipes\recipes_robot.dm" #include "code\datums\components\crafting\recipes\recipes_weapon_and_ammo.dm" +#include "code\datums\components\items\wielding.dm" #include "code\datums\components\riding\riding_filter.dm" #include "code\datums\components\riding\riding_handler.dm" #include "code\datums\components\riding\mob\_mob.dm" diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm index 3b2dd9b4a32..41981374f47 100644 --- a/code/__DEFINES/_flags/item_flags.dm +++ b/code/__DEFINES/_flags/item_flags.dm @@ -30,6 +30,8 @@ #define ITEM_THROW_UNCATCHABLE (1<<15) /// we cannot be used a tool on click, no matter what #define ITEM_NO_TOOL_ATTACK (1<<16) +/// we're dual wielded - multi-wielding coming later tm +#define ITEM_MULTIHAND_WIELDED (1<<17) DEFINE_BITFIELD(item_flags, list( BITFIELD(IN_INVENTORY), @@ -41,6 +43,7 @@ DEFINE_BITFIELD(item_flags, list( BITFIELD(IN_STORAGE), BITFIELD(ITEM_THROW_UNCATCHABLE), BITFIELD(ITEM_NO_TOOL_ATTACK), + BITFIELD(ITEM_MULTIHAND_WIELDED), )) //! Flags for the clothing_flags var on /obj/item diff --git a/code/__DEFINES/dcs/signals/signals_twohand.dm b/code/__DEFINES/dcs/signals/signals_twohand.dm deleted file mode 100644 index bc6a148a3c2..00000000000 --- a/code/__DEFINES/dcs/signals/signals_twohand.dm +++ /dev/null @@ -1,11 +0,0 @@ -/** - *! ## two_handed Signals. Format: - * * When the signal is called: (signal arguments) - * * All signals send the source datum of the signal as the first argument - */ - -///from base of datum/component/two_handed/proc/wield(mob/living/carbon/user): (/mob/user) -////#define COMSIG_TWOHANDED_WIELD "twohanded_wield" - ////#define COMPONENT_TWOHANDED_BLOCK_WIELD (1<<0) -///from base of datum/component/two_handed/proc/unwield(mob/living/carbon/user): (/mob/user) -////#define COMSIG_TWOHANDED_UNWIELD "twohanded_unwield" diff --git a/code/_globals/lists/keybindings.dm b/code/_globals/lists/keybindings.dm index 414c396026b..ec1b114b83e 100644 --- a/code/_globals/lists/keybindings.dm +++ b/code/_globals/lists/keybindings.dm @@ -1,3 +1,4 @@ +// todo: why not just all keybindings by tyyypeohrightpreferences GLOBAL_LIST_EMPTY(classic_keybinding_list_by_key) GLOBAL_LIST_EMPTY(hotkey_keybinding_list_by_key) GLOBAL_LIST_EMPTY(keybindings_by_name) diff --git a/code/datums/components/items/wielding.dm b/code/datums/components/items/wielding.dm new file mode 100644 index 00000000000..991b1c2c35f --- /dev/null +++ b/code/datums/components/items/wielding.dm @@ -0,0 +1,109 @@ +// todo: can element this by usign 3 signals instead of 2, one to receive a keybind signal. +/datum/component/wielding + /// hands needed + var/hands + /// lazylist + var/list/obj/item/offhand/wielding/offhands + /// wielded user + var/mob/wielder + /// callback on wield + var/datum/callback/on_wield + /// callback on unwield + var/datum/callback/on_unwield + +/datum/component/wielding/Initialize(hands = 2, datum/callback/on_wield, datum/callback/on_unwield) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + if((. = ..()) & COMPONENT_INCOMPATIBLE) + return + src.hands = hands + src.on_wield = on_wield + src.on_unwield = on_unwield + +/datum/component/wielding/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/signal_examine) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/signal_dropped) + +/datum/component/wielding/UnregisterFromParent() + unwield() + . = ..() + UnregisterSignal(parent, list( + COMSIG_PARENT_EXAMINE, + COMSIG_ITEM_DROPPED + )) + +/datum/component/wielding/proc/signal_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += SPAN_NOTICE("[parent] seems to be able to be used with [hands] hands. Press your \"Wield Item\" keybind to toggle wielding.") + +/datum/component/wielding/proc/signal_dropped(datum/source, mob/user, flags, atom/newloc) + unwield() + +/datum/component/wielding/proc/wield(mob/wielder) + if(src.wielder) + return + var/possible = wielder.get_number_of_hands() + var/wanted = hands - 1 + if(possible < wanted) + return + var/list/obj/item/offhand/wielding/made = list() + for(var/i in 1 to wanted) + var/obj/item/offhand/wielding/creating = wielder.allocate_offhand(/obj/item/offhand/wielding) + if(!creating) + QDEL_LIST(made) + return + creating.host = src + made += creating + offhands = made + src.wielder = wielder + to_chat(src.wielder, SPAN_WARNING("You start wielding [parent] with [hands == 2? "both" : "[hands]"] hands.")) + post_wield(src.wielder, hands) + +/datum/component/wielding/proc/post_wield(mob/user, hands) + if(on_wield) + on_wield.Invoke(user, hands) + var/obj/item/I = parent + I.on_wield(user, hands) + +/datum/component/wielding/proc/unwield(gcing) + if(!wielder) + return + if(offhands) + var/list/old = offhands + offhands = null + QDEL_LIST(old) + var/obj/item/I = parent + var/mob/unwielding = wielder + I.item_flags &= ~ITEM_MULTIHAND_WIELDED + if(wielder && !gcing) + to_chat(wielder, SPAN_WARNING("You stop wielding [parent] with [hands == 2? "both" : "[hands]"] hands.")) + wielder = null + post_unwield(unwielding, hands) + +/datum/component/wielding/proc/post_unwield(mob/user, hands) + if(on_unwield) + on_unwield.Invoke(user, hands) + var/obj/item/I = parent + I.on_unwield(user, hands) + +/datum/component/wielding/proc/offhand_destroyed(obj/item/offhand/wielding/I) + unwield() +/obj/item/offhand/wielding + name = "wielding offhand" + desc = "You shouldn't be able to see this." + /// host + var/datum/component/wielding/host + +/obj/item/offhand/wielding/Destroy() + if(host) + host.offhand_destroyed(src) + host = null + return ..() + +// item procs +/obj/item/proc/on_wield(mob/user, hands) + return + +/obj/item/proc/on_unwield(mob/user, hands) + return diff --git a/code/datums/components/riding/riding_filter.dm b/code/datums/components/riding/riding_filter.dm index ec5c0614d2b..ff1af33ee6c 100644 --- a/code/datums/components/riding/riding_filter.dm +++ b/code/datums/components/riding/riding_filter.dm @@ -239,7 +239,7 @@ /** * grab all necessary offhands - * qdel the entire list on failure. + * qdel the entire list on failure.T */ /obj/item/offhand/riding diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 50a4098d3c7..e1ffc1cfa60 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -59,11 +59,9 @@ return var/list/names = list() var/list/componentsubtypes = subtypesof(/datum/component) - names += "---Components---" names += componentsubtypes - names += "---Elements---" names += subtypesof(/datum/element) - var/result = input(usr, "Choose a component/element to add","better know what ur fuckin doin pal") as null|anything in names + var/result = tgui_input_list(usr, "Choose a component/element to add", "better know what ur fuckin doin pal", names) if(!usr || !result || result == "---Components---" || result == "---Elements---") return if(QDELETED(src)) @@ -81,6 +79,6 @@ datumname = "element" target._AddElement(lst) log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(src)].") - message_admins("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(src)].") + message_admins("[key_name_admin(usr)] has added [result] [datumname] to [target] ([ADMIN_VV(target)]).") if(href_list[VV_HK_CALLPROC]) usr.client.callproc_datum(target) diff --git a/code/modules/keybindings/keybind/mob.dm b/code/modules/keybindings/keybind/mob.dm index a9503400247..7738229ed3e 100644 --- a/code/modules/keybindings/keybind/mob.dm +++ b/code/modules/keybindings/keybind/mob.dm @@ -104,6 +104,30 @@ M.mode() return TRUE +/datum/keybinding/mob/multihand_wield + hotkey_keys = list("ShiftX") + classic_keys = list("X") + name = "multihand_wield" + full_name = "Wield Item" + description = "Wield an item with two, or more hands (if it's supported)." + +/datum/keybinding/mob/multihand_wield/down(client/user) + // yes, get component is asinine sometimes + // i don't care though, this is such a small feature + var/obj/item/I = user.mob.get_active_held_item() + if(!I) + to_chat(user, SPAN_WARNING("You are not holding anything to wield.")) + return FALSE + var/datum/component/wielding/comp = I.GetComponent(/datum/component/wielding) + if(!comp) + to_chat(user, SPAN_WARNING("That can't be wielded.")) + return FALSE + if(comp.wielder) + comp.unwield() + else + comp.wield(user.mob) + return TRUE + /datum/keybinding/mob/say hotkey_keys = list("T", "F3") name = "say" diff --git a/code/modules/mining/kinetic_crusher.dm b/code/modules/mining/kinetic_crusher.dm index e68145870c8..2bc2b04bc7d 100644 --- a/code/modules/mining/kinetic_crusher.dm +++ b/code/modules/mining/kinetic_crusher.dm @@ -85,14 +85,6 @@ return TRUE return !ishuman(victim) && !issilicon(victim) -/// triggered on wield of two handed item -/obj/item/kinetic_crusher/proc/on_wield(obj/item/source, mob/user) - wielded = TRUE - -/// triggered on unwield of two handed item -/obj/item/kinetic_crusher/proc/on_unwield(obj/item/source, mob/user) - wielded = FALSE - /obj/item/kinetic_crusher/examine(mob/living/user) . = ..() . += "Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage." diff --git a/code/modules/preferences/preference_setup/keybindings/keybindings.dm b/code/modules/preferences/preference_setup/keybindings/keybindings.dm index ab2962da0fe..57e92944ee4 100644 --- a/code/modules/preferences/preference_setup/keybindings/keybindings.dm +++ b/code/modules/preferences/preference_setup/keybindings/keybindings.dm @@ -1,3 +1,4 @@ +// todo: convert and make looking up keys BY BIND possible /datum/preferences /// Custom Keybindings var/list/key_bindings = list()