From 11318bfc3ccead4f6b98f8c158c06f8a2f6f5eb1 Mon Sep 17 00:00:00 2001 From: nemvar <47324920+nemvar@users.noreply.github.com> Date: Fri, 16 Aug 2019 20:56:25 +0200 Subject: [PATCH] Arm implants now support more than two hands. (#45843) * Adds multiple hand support to arm implants * Kills those nasty static lists. * Update inventory.dm --- code/__DEFINES/inventory.dm | 4 ++ code/modules/flufftext/Hallucination.dm | 4 +- code/modules/mob/inventory.dm | 42 +++++--------------- code/modules/mob/living/say.dm | 4 +- code/modules/surgery/organs/augments_arms.dm | 35 ++++++++-------- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 0e902ff1706..cd6ec711ce2 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -128,6 +128,10 @@ #define NECK (1<<11) #define FULL_BODY (~0) +//defines for the index of hands +#define LEFT_HANDS 1 +#define RIGHT_HANDS 2 + //flags for female outfits: How much the game can safely "take off" the uniform without it looking weird #define NO_FEMALE_UNIFORM 0 #define FEMALE_UNIFORM_FULL 1 diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c0196504e58..86eae47f8bf 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -429,11 +429,11 @@ GLOBAL_LIST_INIT(hallucination_list, list( var/mob/living/carbon/human/H = pick(mob_pool) feedback_details += " Mob: [H.real_name]" - var/free_hand = H.get_empty_held_index_for_side(side = "left") + var/free_hand = H.get_empty_held_index_for_side(LEFT_HANDS) if(free_hand) side = "left" else - free_hand = H.get_empty_held_index_for_side(side = "right") + free_hand = H.get_empty_held_index_for_side(RIGHT_HANDS) if(free_hand) side = "right" diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 71f883131f1..5923179daec 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -51,46 +51,24 @@ //Finds the first available (null) index OR all available (null) indexes in held_items based on a side. //Lefts: 1, 3, 5, 7... //Rights:2, 4, 6, 8... -/mob/proc/get_empty_held_index_for_side(side = "left", all = FALSE) - var/start = 0 - var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE) - var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent" - if(lefts[side]) - start = 1 - else if(rights[side]) - start = 2 - if(!start) - return FALSE - var/list/empty_indexes - for(var/i in start to held_items.len step 2) +/mob/proc/get_empty_held_index_for_side(side = LEFT_HANDS, all = FALSE) + var/list/empty_indexes = all ? list() : null + for(var/i in (side == LEFT_HANDS) ? 1 : 2 to held_items.len step 2) if(!held_items[i]) if(!all) return i - if(!empty_indexes) - empty_indexes = list() empty_indexes += i return empty_indexes //Same as the above, but returns the first or ALL held *ITEMS* for the side -/mob/proc/get_held_items_for_side(side = "left", all = FALSE) - var/start = 0 - var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE) - var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent" - if(lefts[side]) - start = 1 - else if(rights[side]) - start = 2 - if(!start) - return FALSE - var/list/holding_items - for(var/i in start to held_items.len step 2) +/mob/proc/get_held_items_for_side(side = LEFT_HANDS, all = FALSE) + var/list/holding_items = all ? list() : null + for(var/i in (side == LEFT_HANDS) ? 1 : 2 to held_items.len step 2) var/obj/item/I = held_items[i] if(I) if(!all) return I - if(!holding_items) - holding_items = list() holding_items += I return holding_items @@ -193,11 +171,11 @@ //Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success. /mob/proc/put_in_l_hand(obj/item/I) - return put_in_hand(I, get_empty_held_index_for_side("l")) + return put_in_hand(I, get_empty_held_index_for_side(LEFT_HANDS)) //Puts the item into the first available right hand if possible and calls all necessary triggers/updates. returns 1 on success. /mob/proc/put_in_r_hand(obj/item/I) - return put_in_hand(I, get_empty_held_index_for_side("r")) + return put_in_hand(I, get_empty_held_index_for_side(RIGHT_HANDS)) /mob/proc/put_in_hand_check(obj/item/I) return FALSE //nonliving mobs don't have hands @@ -247,9 +225,9 @@ if(put_in_active_hand(I, forced)) return TRUE - var/hand = get_empty_held_index_for_side("l") + var/hand = get_empty_held_index_for_side(LEFT_HANDS) if(!hand) - hand = get_empty_held_index_for_side("r") + hand = get_empty_held_index_for_side(RIGHT_HANDS) if(hand) if(put_in_hand(I, hand, forced)) return TRUE diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index cac59d006f3..536b11fbee6 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -370,12 +370,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list( if(MODE_WHISPER) return ITALICS if(MODE_R_HAND) - for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE)) + for(var/obj/item/r_hand in get_held_items_for_side(RIGHT_HANDS, all = TRUE)) if (r_hand) return r_hand.talk_into(src, message, , spans, language) return ITALICS | REDUCE_RANGE if(MODE_L_HAND) - for(var/obj/item/l_hand in get_held_items_for_side("l", all = TRUE)) + for(var/obj/item/l_hand in get_held_items_for_side(LEFT_HANDS, all = TRUE)) if (l_hand) return l_hand.talk_into(src, message, , spans, language) return ITALICS | REDUCE_RANGE diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index fb9b11174c9..359fa06b8e7 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -98,23 +98,26 @@ var/obj/item/assembly/flash/F = holder F.set_light(7) - var/obj/item/arm_item = owner.get_active_held_item() - - if(arm_item) - if(!owner.dropItemToGround(arm_item)) - to_chat(owner, "Your [arm_item] interferes with [src]!") + var/side = zone == BODY_ZONE_R_ARM? "r" : "l" + var/hand = owner.get_empty_held_index_for_side(side) + if(hand) + owner.put_in_hand(holder, hand) + else + var/list/hand_items = owner.get_held_items_for_side(side, all = TRUE) + var/success = FALSE + var/list/failure_message = list() + for(var/i in 1 to hand_items.len) //Can't just use *in* here. + var/I = hand_items[i] + if(!owner.dropItemToGround(I)) + failure_message += "Your [I] interferes with [src]!" + continue + to_chat(owner, "You drop [I] to activate [src]!") + success = owner.put_in_hand(holder, owner.get_empty_held_index_for_side(side)) + break + if(!success) + for(var/i in failure_message) + to_chat(owner, i) return - else - to_chat(owner, "You drop [arm_item] to activate [src]!") - - var/result = (zone == BODY_ZONE_R_ARM ? owner.put_in_r_hand(holder) : owner.put_in_l_hand(holder)) - if(!result) - to_chat(owner, "Your [name] fails to activate!") - return - - // Activate the hand that now holds our item. - owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow - owner.visible_message("[owner] extends [holder] from [owner.p_their()] [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.", "You extend [holder] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.", "You hear a short mechanical noise.")